Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
Есть набор данных - числовой ряд значений equity во времени, нужно определить максимальный (по модулю) относительный минимум и его время. Кто знает, можно ли это каким-нибудь хитрым SQL-запросом или ч-з CTE получить? Насколько я понял, аналитической ф-ии типа GetDrawDown() нету в MS SQL.
Для ряда, к примеру янв 100; фев 90; мар 110; апр 95 решением будет
апр 0,137
Если я не очень понятно объяснил задачу, более-менее подходящий вар-т определения максимального дродауна с картинкой на урле
http://actionforex.ru/page/drodaun-prosadka
Максимальный относительный дродаун на на нижнем графике в районе 10%.
База на MS SQL 2005 XE. Пока я сделал вар-т нахождения искомых значений, елозя циклом, но, наверное, ч-з SQL такая задача тоже может решаться?
ЗЫ Просьба ногами не пинать - я не программист, увы. 8-0
ЗЗЫ Код с циклом, он все, что надо возвращает:
ALTER PROCEDURE [dbo].[p_GetMaxDrawDown]
	-- NO PARAMETERS
	
AS
SET NOCOUNT ON;
BEGIN
	DECLARE
	@maxEq float,  @maxDD float,  @Equity float, @DD float,
	@MyDate datetime, @DD_date datetime;
Set @maxEq=1; Set @maxDD=0;
DECLARE c_Equity CURSOR FAST_FORWARD
FOR SELECT Date, EqOptGroup  FROM dbo.v_OneTradeUNTradesTotal;
OPEN c_Equity;
FETCH c_Equity INTO @MyDate, @Equity;
WHILE @@Fetch_Status = 0 
BEGIN
	If @maxEq < @Equity 
        SET @maxEq = @Equity
    Else
       	SET @DD = (@Equity - @maxEq) / @maxEq    
	If @maxDD > @DD 
	BEGIN
		SET @maxDD = @DD
		SET @DD_date=@MyDate
	END
FETCH c_Equity INTO @MyDate, @Equity;
END
CLOSE c_Equity;
DEALLOCATE c_Equity;

SELECT @DD_date as DD_Date, -1*@maxDD as Drawdown  
END
15 сен 12, 17:40    [13169224]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
комплектовщик,

вообще-то, можно считать, что рекурсивное CTE - это тот же цикл,
правда до самого конца сохраняющий все результаты всех проходов этого цикла.
Ресурсозатратный, другими словами, но - цикл!
15 сен 12, 18:59    [13169419]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
qwerty112
Guest
комплектовщик
...
DECLARE c_Equity CURSOR FAST_FORWARD
FOR SELECT Date, EqOptGroup  FROM dbo.v_OneTradeUNTradesTotal;
OPEN c_Equity;

...гмм,
как-то "смущает" отсутствие сортировки по Date ....


автор,

пример данных давай !
15 сен 12, 20:57    [13169695]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
Оно?
set nocount on;
use tempdb;
if object_id(N'tempdb..#dd') is not null drop table #dd;
create table #dd(d datetime primary key,v numeric(6,3));
insert into #dd(d,v) values('2012-01-01',100);
insert into #dd(d,v) values('2012-02-01',90);
insert into #dd(d,v) values('2012-03-01',110);
insert into #dd(d,v) values('2012-04-01',95);
SELECT TOP 1 d1.d,-1*(d1.v-COALESCE(MAX(d2.v),d1.v))/COALESCE(MAX(d2.v),d1.v) AS dd
FROM #dd AS d1 LEFT JOIN #dd AS d2 ON d1.d>d2.d
GROUP BY d1.d,d1.v
ORDER BY dd DESC;
15 сен 12, 22:52    [13170054]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
OffTop

Тут для построения того графика должна отлично пойти оконная функция:
SELECT Value/Max(Value)OVER(ORDER BY [Date])
...
У кого 2012 (Denali), проверьте пожалуйста.
16 сен 12, 00:48    [13170440]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
qwerty112
...гмм,
как-то "смущает" отсутствие сортировки по Date ....


автор,

пример данных давай !

В источнике данных уже по дате отсортировано. Я прикладываю эксельный файл с данными. Для этого набора решением является 19.03.2012 0,217750206.
andrey odegov
Оно?
...

Нет, это не то.
16 сен 12, 08:27    [13170925]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
Не приложился почему-то файл, выкладываю в теле топика примерный набор данных (2 знака после запятой).

Date;EqOptGroup
01.03.2012;1,06
02.03.2012;1,12
05.03.2012;1,14
06.03.2012;1,16
07.03.2012;1,23
08.03.2012;1,22
09.03.2012;1,33
12.03.2012;1,36
13.03.2012;1,47
14.03.2012;1,28
15.03.2012;1,26
16.03.2012;1,21
19.03.2012;1,15
20.03.2012;1,26
21.03.2012;1,34
22.03.2012;1,41
23.03.2012;1,27
26.03.2012;1,26
27.03.2012;1,37
28.03.2012;1,49
29.03.2012;1,57
30.03.2012;1,55
16 сен 12, 08:32    [13170928]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
комплектовщик, сравните результаты выполнения вариантов:
Вашего
+
set nocount on;
use tempdb;
if object_id(N'tempdb..#v_OneTradeUNTradesTotal') is not null drop table #v_OneTradeUNTradesTotal;
create table #v_OneTradeUNTradesTotal(Date datetime primary key,EqOptGroup float);
insert into #v_OneTradeUNTradesTotal(Date,EqOptGroup)
values ('20120301',1.06)
      ,('20120302',1.12)
      ,('20120305',1.14)
      ,('20120306',1.16)
      ,('20120307',1.23)
      ,('20120308',1.22)
      ,('20120309',1.33)
      ,('20120312',1.36)
      ,('20120313',1.47)
      ,('20120314',1.28)
      ,('20120315',1.26)
      ,('20120316',1.21)
      ,('20120319',1.15)
      ,('20120320',1.26)
      ,('20120321',1.34)
      ,('20120322',1.41)
      ,('20120323',1.27)
      ,('20120326',1.26)
      ,('20120327',1.37)
      ,('20120328',1.49)
      ,('20120329',1.57)
      ,('20120330',1.55);
DECLARE
	@maxEq float,  @maxDD float,  @Equity float, @DD float,
	@MyDate datetime, @DD_date datetime;
Set @maxEq=1; Set @maxDD=0;
DECLARE c_Equity CURSOR FAST_FORWARD
FOR SELECT Date, EqOptGroup  FROM #v_OneTradeUNTradesTotal;
OPEN c_Equity;
FETCH c_Equity INTO @MyDate, @Equity;
WHILE @@Fetch_Status = 0 
BEGIN
	If @maxEq < @Equity 
        SET @maxEq = @Equity
    Else
       	SET @DD = (@Equity - @maxEq) / @maxEq    
	If @maxDD > @DD 
	BEGIN
		SET @maxDD = @DD
		SET @DD_date=@MyDate
	END
FETCH c_Equity INTO @MyDate, @Equity;
END
CLOSE c_Equity;
DEALLOCATE c_Equity;

SELECT @DD_date as DD_Date, -1*@maxDD as Drawdown
и моего:
+
set nocount on;
use tempdb;
if object_id(N'tempdb..#v_OneTradeUNTradesTotal') is not null drop table #v_OneTradeUNTradesTotal;
create table #v_OneTradeUNTradesTotal(Date datetime primary key,EqOptGroup float);
insert into #v_OneTradeUNTradesTotal(Date,EqOptGroup)
values ('20120301',1.06)
      ,('20120302',1.12)
      ,('20120305',1.14)
      ,('20120306',1.16)
      ,('20120307',1.23)
      ,('20120308',1.22)
      ,('20120309',1.33)
      ,('20120312',1.36)
      ,('20120313',1.47)
      ,('20120314',1.28)
      ,('20120315',1.26)
      ,('20120316',1.21)
      ,('20120319',1.15)
      ,('20120320',1.26)
      ,('20120321',1.34)
      ,('20120322',1.41)
      ,('20120323',1.27)
      ,('20120326',1.26)
      ,('20120327',1.37)
      ,('20120328',1.49)
      ,('20120329',1.57)
      ,('20120330',1.55);
SELECT top 1 d1.Date as DD_Date
,-1*(d1.EqOptGroup-coalesce(MAX(d2.EqOptGroup),1))/coalesce(MAX(d2.EqOptGroup),1) as Drawdown
--,case when d1.EqOptGroup>coalesce(max(d2.EqOptGroup),1) then 0
--      else (d1.EqOptGroup-coalesce(MAX(d2.EqOptGroup),1))/coalesce(MAX(d2.EqOptGroup),1)
-- end as dd2
FROM #v_OneTradeUNTradesTotal AS d1 LEFT JOIN #v_OneTradeUNTradesTotal AS d2 ON d1.Date>d2.Date
GROUP BY d1.Date,d1.EqOptGroup
ORDER BY Drawdown desc;
16 сен 12, 13:30    [13171445]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
andrey odegov, результаты одинаковые, погонял на разных временных окнах.
Спасибо. Видимо, Вы нашли решение.
16 сен 12, 17:34    [13172229]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
Измеряю время работы скалярной хранимой процедуры(2 штуки).
USE TRADES;
DECLARE @d1 datetime, @d2 Datetime;
Set @d1=GETDATE();
--exec p_GetMaxDrawDawnSQLWay;
exec p_GetMaxDrawDown;
SET @d2=GETDATE();
SELECT @d2-@d1;

2 процедуры реализуют 1 и тот же механизм, p_GetMaxDrawDawnSQLWay - через 1 запрос(P & C andrey odegov), p_GetMaxDrawDown - циклом.
Набор данных один и тот же.
Я думал, что ч-з запросы должно быть быстрее цикла, а сейчас получаю
1900-01-01 00:00:00.077 - циклом и
1900-01-01 00:00:08.597 запросом.
Т.е. SQL не всегда шустрей циклов может работать?
-----
Не люблю Progress OpenEdge.
30 мар 13, 19:13    [14116698]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
че гевара и фидель
Guest
комплектовщик, план у этого запроса не очень.

просто запрос не оптимально написан. посмотрите в сторону аггрегирующих функций.
30 мар 13, 19:29    [14116724]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
aleks2
Guest
че гевара и фидель
комплектовщик, план у этого запроса не очень.

просто запрос не оптимально написан. посмотрите в сторону аггрегирующих функций.


Нафега козе баян?
set nocount on;
declare  @v table(Date datetime primary key clustered, Eq float);
insert into @v(Date,Eq)
values ('20120301',1.06)
      ,('20120302',1.12)
      ,('20120305',1.14)
      ,('20120306',1.16)
      ,('20120307',1.23)
      ,('20120308',1.22)
      ,('20120309',1.33)
      ,('20120312',1.36)
      ,('20120313',1.47)
      ,('20120314',1.28)
      ,('20120315',1.26)
      ,('20120316',1.21)
      ,('20120319',1.15)
      ,('20120320',1.26)
      ,('20120321',1.34)
      ,('20120322',1.41)
      ,('20120323',1.27)
      ,('20120326',1.26)
      ,('20120327',1.37)
      ,('20120328',1.49)
      ,('20120329',1.57)
      ,('20120330',1.55);

-- монотонно возрастающие значения
declare  @vn table(Date datetime, Eq float, n int identity primary key clustered);

insert into @vn(Date, Eq)
 select Date, Eq 
   from @v t 
   where not exists(select * from @v tt where tt.Eq>t.Eq and tt.Date<t.Date)
 order by Date
 
select * from @vn

-- интервалы дродаунов
declare  @ddv table(Date1 datetime, Date2 datetime, Eq1 float, Eq2 float, n int identity primary key clustered);
 
insert into @ddv(Date1, Date2, Eq1, Eq2)
 select t.Date as Date1, tt.Date as Date2, t.Eq as Eq1, tt.Eq as Eq2 
   from @vn t inner join @vn tt on t.n+1=tt.n
   where exists(select * from @v v where t.Date<v.Date and v.Date<tt.Date)
   
select * from @ddv
   
-- значения минимальных просадок для интервалов
select dd.*, i.minEq
  from
    (select d.n, MIN(v.Eq) minEq
       from @ddv d inner join @v v on d.Date1<v.Date and v.Date < d.Date2
       group by d.n
     ) i
     left outer join
     @ddv dd
     on i.n = dd.n
-- проценты ужо сами исчислите...


Советую ВНИМАТЕЛЬНО ПОСМОТРЕТЬ НА ИНДЕКСЫ ВРЕМЕННЫХ ТАБЛИЦ.
31 мар 13, 10:45    [14118088]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
комплектовщик
Guest
aleks2, сейчас перечитал еще раз на хабре "Семь смертных грехов программиста на T-SQL" и посты в топике, похоже, все объекты кроме таблиц и триггеров переделывать надо.
Чего можно прочитать по разработке БД MS SQL 2205/2008 доступного для человека без высшего программистского образования?
А то до сих пор не понимаю отличия кластеризованного индекса от некластеризованного и уровни изоляции транзакций.
ЗЫ Я умею программировать в Экселе, начал курс по VB.NET читать.
Как я понимаю, можно на VB.NET специальные агрегированные функции делать, отчеты тоже. Так?
-----
Не люблю Progress OpenEdge.
6 апр 13, 18:26    [14145143]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли получить значение макс. относительного дродауна ч-з SQL?  [new]
aleks2
Guest
Главное - не делать из T-SQL культа.
6 апр 13, 19:46    [14145406]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить