SQL и биржевой график (Анализ эффективности торговой стратегии)
Публикация шестая
Анализ эффективности торговой стратегии
В предыдущей статье , я рассказал о создании торговой системы.
Собственно была создана инфраструктура (пакет , набор функций и таблиц) , с помощью которой появилась возможность разрабатывать множество новых торговых стратегий, прописывать разные правила для открытия , закрытия сделок, программировать сложные модели управления капиталом.
Итак, перечислим элементы созданной инфраструктуры
Таблицы
Positions – текущие позиции
Balance – баланс накопительный, по инструменту, а так же прибыль убыток по сделке
Trades – сведения о сделках
Пакет
tradesystem_pkg - реализует основную инфраструктуру для работы торговой системы, в пакете реализован механизм открытия , закрытия сделок, ведения баланса торговых операций, ведения таблицы позиций. Так же в пакете реализована возможность тестирования торговой стратегии на исторических данных
Функции
Closerules – описывает правила для закрытия сделки
Openrule – описывает правила для окрытия сделки
Getpriceind – значения цены и индикаторов цены из представления priceind на заданное количество торговых сессий назад
Ind – текущее значение цены и индикаторов цены из представления priceind
Spriorind - значение цены и индикаторов цены из представления priceind предыдцщей торговой сессии
moneyposition – реализует механизм управления капиталом ,
Обратите внимание, что все функции связаны с пакетом и после изменения кода любой из функций потребуется повторная перекомпиляция пакета tradesystem_pkg!!!
В пакете реализована tradesystem_pkg возможность тестирования нашей торговой стратегии на исторических данных
Теперь нам необходимо понять, насколько эффективна наша торговая стратегия
Для анализа эффективности торговой стратегии инвестор использует следующие показатели
• Общая прибыль - общая прибыльность торговой стратегии за период тетстирования
• Средняя прибыль на сделку – сколько нам принесла средняя прибыльна сделка
• Средний убыток – величина средней убыточной сделки
• Максимальная просадка - максимальная суммы потенциального убытка торговой стратегии
• Общее количество сделок – количество сделок на заданном историческом промежутке
• Общее прибыльных сделок – общее количество сделок с положительным результатом
• Общее количество убыточных сделок – общее количество сделок с убытком
• Количество убыточных сделок подряд – максимальная цепочка из убыточных сделок
• Отношение прибыль и убыточных сделок – количество прибыльных сделок к количеству сделок убыточных
Запрограммируем вышеуказанные показатели , для этого создадим сервисный пакет report_pkg
create or replace package report_pkg is -- Author : Чaлышев Максим Михайлович -- Created : 02.10.2014 16:24:41 -- Purpose : отчет -- Общая прибыль function getsumwin(priceticker varchar2 default null) return number; -- Средняя прибыльная сделка function getavgwintrade(priceticker varchar2 default null) return number; -- Средний убыточная сделка function getavglosstrade(priceticker varchar2 default null) return number; -- Максимальная просадка function getmaxloss(priceticker varchar2 default null) return number; -- Общее количество сделок function gettradescount(priceticker varchar2 default null) return number; -- Общее прибыльных сделок function gettradeswincount(priceticker varchar2 default null) return number; -- Общее количество убыточных сделок function gettradeslosscount(priceticker varchar2 default null) return number; -- Количество убыточных сделок подряд function getlosscount(priceticker varchar2 default null) return number; -- Максимальный убыток в рублях function gettradeslosstrade(priceticker varchar2 default null) return number; end report_pkg; create or replace package body report_pkg is -- Function and procedure implementations -- Общая прибыль function getsumwin(priceticker varchar2 default null) return number is vr_return number; begin select sum(balance.balancedeltarur) into vr_return from balance where (balance.ticker = priceticker or priceticker is null); return vr_return; end getsumwin; -- Средняя прибыльная сделка function getavgwintrade(priceticker varchar2 default null) return number is vr_return number; begin select avg(balance.balancedeltarur) into vr_return from balance where (balance.balancedelta>0) and (balance.ticker = priceticker or priceticker is null); return vr_return; end getavgwintrade; -- Средняя убыточная сделка function getavglosstrade(priceticker varchar2 default null) return number is vr_return number; begin select avg(balance.balancedeltarur) into vr_return from balance where (balance.balancedelta<0) and (balance.ticker = priceticker or priceticker is null); return vr_return; end getavglosstrade; -- Максимальная просадка function getmaxloss(priceticker varchar2 default null) return number is vr_return number; begin if priceticker is null then select max(balance.balanceallrur)-min(balance.balanceallrur) into vr_return from balance; else select max(balance.balancealltickerrur)-min(balance.balancealltickerrur) into vr_return from balance where balance.ticker = priceticker; end if; return vr_return; end getmaxloss; -- Общее количество сделок function gettradescount(priceticker varchar2 default null) return number is vr_return number; begin select count(1) into vr_return from balance where (balance.ticker = priceticker or priceticker is null); return vr_return; end gettradescount; -- Общее прибыльных сделок function gettradeswincount(priceticker varchar2 default null) return number is vr_return number; begin select count(1) into vr_return from balance where balance.balancedelta>0 and (balance.ticker = priceticker or priceticker is null); return vr_return; end gettradeswincount; -- Общее количество убыточных сделок function getlosscount(priceticker varchar2 default null) return number is vr_return number; begin select count(1) into vr_return from balance where balance.balancedelta<0 and (balance.ticker = priceticker or priceticker is null); return vr_return; end getlosscount; -- макс Количество убыточных сделок подряд function gettradeslosscount(priceticker varchar2 default null) return number is vr_return number:=0; vr_count number:=0; begin for i in ( select balance.balancedeltarur r from balance where (balance.ticker = priceticker or priceticker is null) order by balance.tradedate ) loop if i.r > 0 then vr_count:=0; end if; if i.r < 0 then vr_count:=vr_count+1 ; if vr_count>vr_return then vr_return := vr_count; end if; end if; end loop; return vr_return; end gettradeslosscount; -- Максимальный убыток function gettradeslosstrade(priceticker varchar2 default null) return number is vr_return number; begin select min(balance.balancedelta rur) into vr_return from balance where balance.balancedelta<0 and (balance.ticker = priceticker or priceticker is null); return vr_return; end gettradeslosstrade; begin -- Initialization null; end report_pkg;
откомпилируем пакет.
проведем историческое тестирование нашей торговой стратегии , проанализируем результаты на заданном историческом периоде
-- Created on 09.10.2014 by 1 declare -- Local variables here i integer; start_date date := TO_DATE('07.07.2009','DD.MM.YYYY'); end_date date := TO_DATE('24.09.2014 ','DD.MM.YYYY'); ticker varchar2(5):= 'SBER'; begin -- Test statements here tradesystem_pkg.cleartable; tradesystem_pkg.checkhistory(ticker,start_date,end_date); dbms_output.put_line('------------------------------------------------------------'); dbms_output.put_line('Тестирование на исторических данных. Инструмент: '||ticker); dbms_output.put_line(' начало периода ' ||to_char(start_date,'DD.MM.YYYY')); dbms_output.put_line(' окончание периода ' ||to_char(end_date,'DD.MM.YYYY')); dbms_output.put_line('-------------------------------------------------------------'); dbms_output.put_line(' '); dbms_output.put_line(' Баланс(RUR) ' || tradesystem_pkg.moneybalance); dbms_output.put_line(' Общая прибыль (RUR) ' || report_pkg.getsumwin(ticker)); dbms_output.put_line(' Средняя прибыль на сделку (RUR) ' || report_pkg.getavgwintrade(ticker)); dbms_output.put_line(' Средний убыток (RUR) ' || report_pkg.getavglosstrade(ticker)); dbms_output.put_line(' Максимальная просадка (RUR) ' || report_pkg.getmaxloss(ticker)); dbms_output.put_line(' Общее количество сделок ' || report_pkg.gettradescount(ticker)); dbms_output.put_line(' Общее прибыльных сделок ' || report_pkg.gettradeswincount(ticker)); dbms_output.put_line(' Общее количество убыточных сделок ' || report_pkg.getlosscount(ticker)); dbms_output.put_line(' Количество убыточных сделок подряд ' || report_pkg.gettradeslosscount(ticker)); dbms_output.put_line(' '); dbms_output.put_line('-------------------------------------------------------------'); end;
------------------------------------------------------------
Тестирование на исторических данных. Инструмент: SBER
начало периода 07.07.2009
окончание периода 24.09.2014
-------------------------------------------------------------
Баланс(RUR) 1000000
Общая прибыль (RUR) 52799,25
Средняя прибыль на сделку (RUR) 12524,926
Средний убыток (RUR) -4261,765
Максимальная просадка (RUR) 23441,85
Общее количество сделок 27
Общее прибыльных сделок 10
Общее количество убыточных сделок 17
Количество убыточных сделок подряд 6
-------------------------------------------------------------
напоминаю так же , что необходимую нам информацию можно посмотреть в таблицах
Positions – текущие позиции
Balance – баланс накопительный, по инструменту, а так же прибыль убыток по сделке
Trades – сведения о сделках