Страницы

2013-01-06

Теоретическая система для фьючерса РТС

Попробуем создать простейшую теоретическую систему для фьючерса на индекс РТС с самого начала на самых популярных индикаторах, допуская что непрерывный график с Финама правильный и соответствует действительности. Все слышали что этот инструмент довольно трендовый, особенно на часовиках или, по крайней мере был таковым когда-то. А если был, то примем допущение что останется трендовым и в дальнейшем. А чтобы ловить тренды наверняка, что надо применять? -- правильно, каналы Дончиана, так как они не упустят тренд никогда.

Итак, берем график фьючерса на индекс РТС (часовики) и закачиваем в программу WealthLab6 или в любую другую. Мне удобно тестировать в Велслабе потому что там есть встроенный датафид от Финама. Открываем мастер стратегий и конструируем простейшую систему на Каналах Дончиана. Период каналов возьмем логический -- 14 часов в сессии. Тестировать будем за 2 последних года.

Правила:
Покупаем на пробое верхнего канала, продаем на пробое нижнего канала.
Открываем шорт на пробое нижнего канала, закрываем шорт на пробое верхнего канала.

Тестируем:



Кое что получилось, но совершенно непривлекательно. Попробуем применить простейший фильтр тренда. Возьмем самый популярный индикатор -- скользящую среднюю с периодом -- 280 -- количество торговых часов в месяце. Если цена будет выше средней -- можно только покупать. Если цена ниже средней, то только продавать.

Тестируем:



Чуть лучше, но незначительно. Чего-то явно не хватает. Что в трендследящей системе самое важное? Конечно же стопы, причем покороче чем потенциальная прибыль. Поэтому возьмем стоп 0,5% -- просто с потолка, без причин. Просто чтобы был короткий.

Итак теперь имеем -- позиции открываются по каналам Дончиана, фильтр позиций скользящая средняя и добавился короткий стоп.
Тестируем:


Ну уже намного лучше -- и кривая ровнее и прибыль намного больше.
Но всем известно, что падает рынок совсем не так как растет. Поэтому может быть установить разные параметры индикаторов для длинных и коротких позиций? А также применить разные параметры каналов Дончиана на вход и выход. Это ведь система только для одного инструмента, а не для портфеля, поэтому можно и нужно учесть характер поведения именно этого инструмента. Как это лучше сделать? Можно просто прооптимизировать и посмотреть какие параметры окажутся лучше. И посмотреть что мы из этого сможем получить и устойчив ли широкий спектр полученных оптимальных параметров.
Но для этого придется написать код в Велслабе вручную, так как скрипты, сгенерированные мастером стратегий не дают нужный шаг для оптимизации. Просто преобразовываем полученный код из мастера стратегий в простой код и дописываем все что нам нужно вручную. А нужны нам только параметры оптимизации.


Запускаем оптимизатор и через две минуты получаем результат. Выбираем самый лучший по Recovery Factor, также видим что вообще все результаты со всеми параметрами в приличном плюсе и нет ни одного отрицательного результата -- это говорит о том что инструмент действительно трендовый и прибыль получается не случайно. Можно просто выбирать любые параметры наугад, но мы, все же выберем самый лучший, надеясь на то что он на самом деле лучший и таковым останется в дальнейщем:)

Итак смотрим что получилось:



Итак, уже кое что -- и прибыль значительно увеличилась, и просадки небольшие.

Кстати, параметры получились такие:


Расшифруем:
Когда цена выше МА(200), покупаем по верхнему каналу Дончиана с периодом 90 и продаем по нижнему каналу с периодом 10.
Когда цена ниже МА(600), шортим по нижнему каналу Дончиана с периодом 10 и откупаем по верхнему каналу с периодом 10.
Стоп лосс устанавливаем 0,25% на следующем баре после бара открытия позиции.

Мы тестировали и оптимизировали за 2 последних года. А теперь посмотрим что бы было если с этими же параметрами торговали за 6 последних лет.

Тестируем и смотрим:


Итак, вполне привлекательный результат. Взглянем для интереса на то, как распределились сделки:



Видно, что много-много маленьких убытков и поменьше больших прибыльных сделок, особенно несколько лет назад -- наверняка, из-за большой волатильности. А в последнее время уже таких больших плюсов и минусов нет и сделки лежат кучнее.

Большие минусы были получены из-за того что стопы устанавливались только на следующем баре после открытия позиции и цена могла уйти далеко в минус. Смоделировать выставление стопа сразу после открытия позиции немного сложнее -- для этого необходимо перейти на более низкие таймфреймы, например, минутки или даже тики. Это лучше делать в Трейдстейшн -- там можно установить опцию и тестируя на часовиках, автоматически будут учитываться минутные графики и стоп сработает в нужном месте. В Велслабе такой опции нет. Но, все же, самое главное, найти преимущество, а такой же результат как в прошлом все равно никогда не повторится.

Конечно же, система теоретическая, так как не учитывались проскальзывания, комиссии, ложная первая минута сессии, неточный финамовский график и многое другое. Просто, так называемая, "рыба", как поэты называют заготовки для своих стихов -- сначала напишут белиберду в рифму, а потом уже эту форму наполняют смыслом.....

Ну и код для WL6.

Если будут идеи как улучшить систему или код, можете продолжить дискуссию в комментариях. Если, это не будет секретом, конечно....


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies
{
public class MyStrategy : WealthScript
{
private StrategyParameter slider1;
private StrategyParameter slider2;
private StrategyParameter slider3;
private StrategyParameter slider4;
private StrategyParameter slider5;
private StrategyParameter slider6;
public MyStrategy()
{
slider1 = CreateParameter("Channel Period",20,10,200,10);
slider2 = CreateParameter("MA Period",200,100,1000,50);
slider3 = CreateParameter("Channel Period",20,10,200,10);
slider4 = CreateParameter("Channel Period",20,10,200,10);
slider5 = CreateParameter("MA Period",200,100,1000,50);
slider6 = CreateParameter("Channel Period",20,10,200,10);
}


protected override void Execute()
{
DataSeries ma = SMA.Series(Close, slider2.ValueInt);
DataSeries ma_1 = SMA.Series(Close, slider5.ValueInt);



PlotSeries(PricePane, Highest.Series(High, slider1.ValueInt) >> 1, Color.Red, LineStyle.Solid, 1);
PlotSeries(PricePane,SMA.Series(Close,slider2.ValueInt),Color.Blue,LineStyle.Solid,2);
PlotSeries(PricePane, Lowest.Series(Low, slider3.ValueInt) >> 1, Color.Green, LineStyle.Solid, 1);
PlotSeries(PricePane, Lowest.Series(Low, slider4.ValueInt) >> 1, Color.Green, LineStyle.Solid, 1);
PlotSeries(PricePane,SMA.Series(Close,slider5.ValueInt),Color.Blue,LineStyle.Solid,2);
PlotSeries(PricePane, Highest.Series(High, slider6.ValueInt) >> 1, Color.Red, LineStyle.Solid, 1);

for(int bar = GetTradingLoopStartBar(1); bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
Position p = LastPosition;
if (p.EntrySignal.Contains("Group2|"))
{
double Stop1 = p.EntryPrice * (1 + 0.25 / 100.0d);
CoverAtStop(bar + 1, p, Stop1, "Initial Stop");
CoverAtStop(bar + 1, p, Highest.Value(bar, High, slider6.ValueInt), "Group2");
}
if (p.EntrySignal.Contains("Group1|"))
{
double Stop = p.EntryPrice * (1 - 0.25 / 100.0d);
SellAtStop(bar + 1, p, Stop, "Group1");
SellAtStop(bar + 1, p, Lowest.Value(bar, Low, slider3.ValueInt), "Group1");
}

}
else
{
if (Close[bar] < ma_1[bar])
{
ShortAtStop(bar + 1, Lowest.Value(bar, Low, slider4.ValueInt), "Group2|");
}
if (Close[bar] > ma[bar])
{
BuyAtStop(bar + 1, Highest.Value(bar, High, slider1.ValueInt), "Group1|");
}

}
}
}
}
}

1 комментарий:

  1. Этот комментарий был удален администратором блога.

    ОтветитьУдалить