Автор |
Сообщение |
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Стандартный ApplyStop такой функции не поддерживает.
Суть стопа такова. Вхожу в позицию по условиям входа. Далее, при определенных условиях (например, движение цены на n пунктов от цены открытия), стоп на выход из позиции должен быть установлен на уровне цены открытия позиции.
Допустим, я использую следующую стратегию:
Код: |
Buy = Cross( MA( Close, 10 ), MA( Close, 40 ) );
Sell = 0; // sell is via stops
ApplyStop( stopTypeLoss, stopModePoint, BuyPrice - Ref( Low, -1 ), 0 ); // простой стоп-лосс |
Как мне зафиксировать цену входа? ValueWhen(Buy) не подойдет, потому что условия для Buy могут срабатывать и после открытия позиции. Освободиться от прочих баев с помощью ExRem не получиться, так как Sell у нас равен нулю.
Я так понимаю, нужно использовать кастомный бэктестинг, причем low level?
Праймер (тот, что Хьюстон) я прочитал - информации там немного. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
А почему именно стоп, Не вижу сложностей реализовать эту стратегию при помощи обычного выхода реализовав его при помощи цикла. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Хорошо, но как? Я же говорю, как мне зафиксировать цену входа?
Кстати, я тут начал что-то ваять:
Код: |
// Breakeven stop
BreakevenValue = 100;
SetCustomBacktestProc( "" );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess();
for( bar = 0; bar < BarCount; bar++ )
{
bo.ProcessTradeSignals( bar );
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
gain = pos.GetPrice("H") - pos.GetEntryValue()
if (gain >= BreakevenValue)
{
// что тут написать? Как установить стоп по цене pos.GetEntryValue()
}
}
}
bo.PostProcess();
} |
|
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
вечером. ща недосуг. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Типа так. Я не внимательно побыстрому накидал. Принцип думаю понятен. Тут, на форуме подобных кодов как говна
Код: |
Buy = Cross( MA( Close, 10 ), MA( Close, 40 ) );
Sell = 0; // sell is via stops
pos = 0;
for(i = 0; i < BarCount; i++)
{
if(pos == 0) // нет открытой пзиции
{
if(Buy[i]) // есть сигнал на покупку
{
pos = 1;
BuyLevel = C[i]; // цена покупки для примера Close
SellLevel = BuyLevel - 100; // уровень выхода. Для примера
key = 0; // маркер переноса стопа
}
}
else // есть открытая позиция
{
Buy[i] = 0; // убираем сигналы Buy. Просто для красоты
if(L[i] < SellLevel) // проверка стопа
{
Sell[i] = 1;
Pos = 0;
}
else if(H[i] > (SellLevel + 200)) // проверка условия переноса стопа
{
if(key == 0)
{
SellLevel = BuyLevel; // перенесли стоп на уровень входа
key = 1;
}
}
}
}
|
|
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Олег, спасибо! Логику понял, буду шлифовать под себя...
А вообще, кастомный бэктестинг меня реально заинтересовал. Просто шикарные потенциальные возможности! К сожалению, отсутствие нормальной справочной литературы очень замедляет исследовательский процесс. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Немного подкорректировал код:
Код: |
SetTradeDelays(0,0,0,0);
Buy = Cross( MA( Close, 10 ), MA( Close, 40 ) );
BuyPrice = Close;
Sell = 0; // sell is via stops
SellPrice = Close;
pos = 0;
key = 0;
for( i = 0; i < BarCount; i++ )
{
if( pos == 0 ) // нет открытой позиции
{
if( Buy[i] ) // есть сигнал на покупку
{
pos = 1;
BuyLevel = C[i]; // цена покупки для примера Close
key = 0; // маркер установки стопа
}
}
else // есть открытая позиция
{
Buy[i] = 0; // убираем сигналы Buy. Просто для красоты
if( H[i] > BuyLevel + 5 )
{
if( key == 0 ) // если стоп еще не был установлен
{
key = 1; // признак, что стоп установлен
}
}
if( L[i] < BuyLevel AND key == 1 ) // проверка прохождения уровня стопа
{
Sell[i] = 1;
SellPrice = BuyLevel;
Pos = 0;
key = 0;
}
}
}
|
Но столкнулся с какой-то чертовщиной! Выход не происходит по цене входа! BuyLevel показывает на баре выхода правильное значение, выход происходит по цене BuyLevel, но в тестере цена выхода отличается! Никаких комиссионных и проскальзываний не установлено.
Ничего не могу понять |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Вот тут
Код: |
SellPrice = BuyLevel; |
исправь
Код: |
SellPrice[i] = BuyLevel; |
|
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Спасибо, вроде заработало... |
|
|
Посмотреть профиль Отправить личное сообщение |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
В общем, доковырял я этот кастомный бэктестер. Вот такая получилась реализация Breakeven stop с его использованием:
Код: |
SetPositionSize( RoundLotSize, spsShares );
ShortMA = MA( Close, 20 );
LongMA = MA( Close, 40 );
Buy = Cross( ShortMA, LongMA );
Sell = Cross( LongMA, ShortMA );
Threshold = Param( "MFE", 5, 1, 30, 1 );
Plot( Close, "Price", colorBlack, styleBar );
Plot( ShortMA, "ShortMA", colorGreen );
Plot( LongMA, "LongMA", colorBlue );
//======== Начало кастомного бэктестинга
SetCustomBacktestProc( "" );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject(); // Get backtester object
bo.PreProcess(); // Do pre-processing
for( i = 0; i < BarCount; i++ ) // Loop through all bars
{
for( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )
{
// Loop through all signals at this bar
if( sig.IsEntry() )
bo.EnterTrade( i, sig.Symbol, sig.IsLong(), sig.Price, sig.PosSize );
if( sig.IsExit() )
bo.ExitTrade( i, sig.Symbol, sig.Price );
}
bo.HandleStops( i ); // Handle programmed stops at this bar
for( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
{
if( trade.GetPrice( i, "L" ) <= trade.EntryPrice AND
trade.GetPrice( i - 1, "L" ) > trade.EntryPrice AND
trade.GetMFE() > Threshold )
{
bo.ExitTrade( i, trade.Symbol, Min(trade.EntryPrice, trade.GetPrice(i, "O" )));
}
}
bo.UpdateStats( i, 1 ); // Update MAE/MFE stats for bar
bo.UpdateStats( i, 2 ); // Update stats at bar's end
} // End of for loop over bars
bo.PostProcess(); // Do post-processing
}
|
Большую часть кода составляют процедуры Low level кастомного бэктестинга - к сожалению, управление позициями (насколько я понял), возможно только на этом уровне.
Часть кода, собственно ответственная за breakeven stop:
Код: |
for( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
{
if( trade.GetPrice( i, "L" ) <= trade.EntryPrice AND
trade.GetPrice( i - 1, "L" ) > trade.EntryPrice AND
trade.GetMFE() > Threshold )
{
bo.ExitTrade( i, trade.Symbol, Min(trade.EntryPrice, trade.GetPrice(i, "O" )));
}
} |
А в основной части кода где-нибудь прописать переменную:
Код: |
Threshold = Param( "MFE", 5, 1, 30, 1 ); |
|
Последний раз редактировалось: rupiter (Чт Июл 07, 2016 7:27 am), всего редактировалось 1 раз |
|
Посмотреть профиль Отправить личное сообщение |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
Провел тестирование представленной системки с оптимизацией параметра MFE (тот, что регулируется в коде переменной Threshold) на примере акции Сбербанка за период 2006 - 2016 гг. Вот что получилось: |
|
|
Посмотреть профиль Отправить личное сообщение |
|
rupiter
Зарегистрирован: 16.09.2013
Сообщения: 75
|
То есть, в данном случае, после 10% хода в благоприятную сторону закрытие происходит каким-то иным способом, нежели breakeven стопом, и наш стоп на результаты работы системы влияние уже не оказывает (если провести тестирование без этого стопа, то видно, что это именно так)...
Правда, все это к делу уже не относится. Просто, приятно, что наконец хоть что-то заработало, как надо. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Красиво. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
|