Автор |
Сообщение |
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
Не могу сообразить, как сделать такую штуку:
Первоначальный размер позиции 5% от капитала, максимум 2 открытые позиции, т.е. по 5% на каждую. Добавляем через sigScaleIn. Закрытие тоже делается за 2 раза: сначала половина позиции (sigScaleOut), потом все остальное. Особенность в том, что после первого закрытия остается одна позиция и может появиться сигнал на добавление второй снова 5% от капитала.
Начало такое:
Код: |
SetPositionSize( 5, spsPercentOfEquity ); |
После цикла с расстановками sigScaleIn и sigScaleOut делаю так:
Код: |
SetPositionSize( IIf( Buy == sigScaleOut, 50, IIf( Buy == sigScaleIn, 200, 100 ) ),
IIf( Buy == sigScaleOut or Buy == sigScaleIn, spsPercentOfPosition, spsNoChange ) ); |
Но такое ощущение, что работает это не совсем как я ожидаю. Этот график PositionSize выводит какую-то фигню:
Код: |
Plot( PositionSize, "PositionSize", colorYellow, styleLeftAxisScale ); |
Что я делаю не так и как сделать так, как надо? |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
По моему это лучше и проще сделать через цикл. И PositionSize тоже в цикле задавать. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
000 писал(а): |
По моему это лучше и проще сделать через цикл. И PositionSize тоже в цикле задавать. |
Через цикл получилось, то только для фиксированного числа лотов. Не соображу, как сделать с процентом от капитала. С лотами выглядит так:
Код: |
Size = 10; // Lots
PositionSize = 0;
pos = 0;
for ( i = Per; i < BarCount; i++ ) {
PositionSize[i] = PositionSize[i-1];
// если открытых позиций менее 2
if ( pos < 2 )
// есть условие покупки
if ( BuyCond[i-1] == 1 ) {
// увеличить счетчик открытых позиций
pos = pos + 1;
// если вторая позиция, то sigScaleIn
if ( pos == 1 ) Buy[i] = 1; else Buy[i] = sigScaleIn;
// вход по цене открытия
BuyPrice[i] = O[i];
// values below -2000 encode share count
if ( pos == 1 ) PositionSize[i] = -2000 - Size * RoundLotSize;
else PositionSize[i] = PositionSize[i] - Size * RoundLotSize;
continue;
}
// если нет позиции, то далее
if ( pos == 0 ) continue;
// SellCond1 - продажа 1 половины
// SellCond2 - продажа 2 половины (остатка)
// если нет условий продажи, то далее
if ( SellCond1[i-1] == 0 and SellCond2[i-1] == 0 ) continue;
// условие продажи первой половины
if ( SellCond1[i-1] == 1 ) {
// получаем число shares
x = PositionSize[i] + 2000;
// приводим к лотам
x = abs( x / RoundLotSize );
// запоминаем исходные лоты
xx = x;
// делим пополам и берем бОльшую часть
x = ceil( x / 2 );
// если не "поделилось" (1 лот = 1 лот), то далее
if ( xx == x ) continue;
// приводим к shares
x = x * RoundLotSize;
x = -2000 - x;
// "открытие" позиции
Buy[i] = sigScaleOut;
// по цене открытия
BuyPrice[i] = O[i];
// уменьшаем счетчик открытых позиций
pos = 1;
// ставим PositionSize
PositionSize[i] = x;
continue;
}
// услови продажи 2 половины (остатка)
if ( SellCond2[i-1] == 1 ) {
Sell[i] = 1;
SellPrice[i] = O[i];
// обнуляем счетчик открытых позиций и PositionSize
pos = 0;
PositionSize[i] = 0;
}
}
P = IIf( PositionSize == 0, 0, -( PositionSize + 2000 ) );
Plot( P, "PositionSize", colorYellow, styleLeftAxisScale );
|
Тестирую на нескольких тикерах сразу в режиме
Код: |
SetBacktestMode( backtestRegularRawMulti ); |
Почему-то в тестере в detailed log вижу такие строки:
Код: |
14.02.2017 10:00:00
Entry signals(score):
Exit signals:GMKN=Sell,
Exit Long, GMKN, Price: 9686, (Avg. exit pr. 9815.44), Shares: 13, Commission: 138.51, (Total comm.: 541.058), Profit: -1640.06 (-0.67 %), Entry rank:1, Equity: 1.23161e+006, Fx rate: 1
Exit Long, GMKN, Price: 9686, (Avg. exit pr. 9830.55), Shares: 13, Commission: 138.51, (Total comm.: 430.783), Profit: 1170.22 (0.60 %), Entry rank:1, Equity: 1.23161e+006, Fx rate: 1
Exit Long, GMKN, Price: 9686, (Avg. exit pr. 9878.73), Shares: 8, Commission: 85.2368, (Total comm.: 323.858), Profit: 1622.14 (1.11 %), Entry rank:1, Equity: 1.23161e+006, Fx rate: 1
Exit Long, GMKN, Price: 9686, (Avg. exit pr. 9686), Shares: 7, Commission: 74.5822, (Total comm.: 152.344), Profit: -3043.34 (-4.31 %), Entry rank:1, Equity: 1.23161e+006, Fx rate: 1
|
Как будто открыто не 2 позиции, а намного больше. И вот такое тоже встречается:
Код: |
06.02.2017 10:00:00
Entry signals(score):GMKN=Buy(1),
Exit signals:GMKN=Scale-Out,
Scale-Out Long GMKN, Price 10099, Shares 7, Fx Rate 1, Number of shares - Current: 13, Exited: 12, Total Cost: 246485, Avg. Entry Price 9818, Avg. Exit Price 9955.67, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 402.548
Scale-Out Long GMKN, Price 10099, Shares 7, Fx Rate 1, Number of shares - Current: 13, Exited: 7, Total Cost: 195010, Avg. Entry Price 9750.5, Avg. Exit Price 10099, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 292.273
Scale-Out Long GMKN, Price 10099, Shares 7, Fx Rate 1, Number of shares - Current: 8, Exited: 7, Total Cost: 146235, Avg. Entry Price 9749, Avg. Exit Price 10099, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 238.621
Enter Long, GMKN, Price: 10099, Shares: 7, Commission: 77.7623, Rank: 1, Equity 1.23681e+006, Margin Loan: 0, Fx rate: 1
GMKN Scaling ignored because signal predates already processed event
GMKN Scaling ignored because signal predates already processed event
GMKN Scaling ignored because signal predates already processed event
GMKN Scaling ignored because signal predates already processed event
4 Open Positions: , GMKN (+13), , GMKN (+13), , GMKN (+8), , GMKN (+7), Equity: 1.2322e+006, Cash: 634232
|
Подозреваю, что это из-за backtestRegularRawMulti, но если эту опцию отключить, то при появлении сигналов на открытие по нескольким тикерам открывается только 1 позиция, а нужно по всем, где есть сигнал. Как быть? Или я многого хочу от тестера? |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
1. PositionSize если отрицательная величина, то это процент от общего капитала
PositionSize[i] = -25; // 25% капитала в сделке.
2. backtestRegularRawMulti тебе не нужен. Этот режим позволяет открывать одновременно несколько позиций по бумаге а тебе это вроде не надо.
3. Не может быть чтобы открывалась только одна позиция. Где есть сигнал там должно открыться при условии, что не превышено число разрешенных одновременно открытых позиций. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
Это я знаю. Но у меня задумка чуть сложнее же. Открыли 5%, закрыли половину, осталось 2.5%. Еще один вход, должно стать 7.5%. Опять половинный выход, стало ~3.7%. Снова вход, стало 8.7% и т.д. Поскольку не знаю, как это реализовать, решил попробовать через "фиксированный лот", задавая PositionSize ниже -2000. Понимаю, что в чужом коде копаться неинтересно, поэтому поясню словами:
0. фикс.размер 10 лот, в лоте 10 бумаг.
1. первый вход: positionSize = -2100 (10 лот)
2. первый выход: positionSize = -2050 (5 лот)
3. второй вход: positionSize = -2150 (15 лот)
4. опять выход: positionSize = -2080 (8 лот, т.к. 15 лот не делится на 2)
5. снова вход: positionSize = -2180 (18 лот)
.....
Про backtestRegularRawMulti ты прав. Без него получаются открытия по нескольким тикерам на одном баре, тут все ок. Но в некоторых случаях странно работает "уполовинивание" позиции. Вот пример:
Код: |
02.03.2010 10:30:00
Entry signals(score):
Exit signals:
3 Open Positions: , ROSN (+60), , LKOH (+4), , GMKN (+2), Equity: 500826, Cash: 454905
03.03.2010 10:30:00
Entry signals(score):
Exit signals:GMKN=Scale-Out, ROSN=Scale-Out,
Scale-Out Long ROSN, Price 237.03, Shares 20, Fx Rate 1, Number of shares - Current: 40, Exited: 20, Total Cost: 13868.8, Avg. Entry Price 231.147, Avg. Exit Price 237.03, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 20.4703
Scale-Out Long GMKN, Price 4702.01, Shares 1, Fx Rate 1, Number of shares - Current: 1, Exited: 1, Total Cost: 8999.1, Avg. Entry Price 4499.55, Avg. Exit Price 4702.01, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 15.0712
3 Open Positions: , ROSN (+40), , LKOH (+4), , GMKN (+1), Equity: 501216, Cash: 464337
04.03.2010 10:30:00
Entry signals(score):
Exit signals:LKOH=Scale-Out,
Scale-Out Long LKOH, Price 1626, Shares 2, Fx Rate 1, Number of shares - Current: 2, Exited: 2, Total Cost: 6232, Avg. Entry Price 1558, Avg. Exit Price 1626, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 10.4324
3 Open Positions: , ROSN (+40), , LKOH (+2), , GMKN (+1), Equity: 501418, Cash: 467586
|
Обрати внимание, по роснефти scaleout, но из 6 лот осталось 4, а не 3. лукойл и гмк - все норм. В чем причина не пойму... |
|
|
Посмотреть профиль Отправить личное сообщение |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
ScaleIn работает тоже весьма странно
Код: |
Lot = 2;
RoundLotSize = 1; // для простоты
// где-то в цикле...
if ( pos == 1 ) PositionSize[i] = -2000 - Lot * RoundLotSize;
else PositionSize[i] = PositionSize[i] - Lot * RoundLotSize;
.... |
Т.е. если позиция первая, то -2002. Если добавление, то вычтем еще 2 и должно стать -2004. Во вложении виден график PositionSize, который выводится так:
Код: |
P = IIf( PositionSize == 0, 0, -( PositionSize + 2000 ) );
Plot( P, "PositionSize", colorYellow, styleLeftAxisScale ); |
А вот что выводит Detailed Log в эти дни (лишние убрал)
Код: |
10.02.2010 10:30:00
Entry signals(score):GAZP=Buy(1),
Exit signals:
Enter Long, GAZP, Price: 176.11, Shares: 2, Commission: 0.387442, Rank: 1, Equity 499999, Margin Loan: 0, Fx rate: 1
1 Open Positions: , GAZP (+2), Equity: 499990, Cash: 499647
26.02.2010 10:30:00
Entry signals(score):
Exit signals:GAZP=Scale-In,
Scale-In Long GAZP, Price 166.9, Shares 4, Fx Rate 1, Number of shares - Current: 6, Exited: 0, Total Cost: 1019.82, Avg. Entry Price 169.97, Avg. Exit Price 0, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 1.1218
1 Open Positions: , GAZP (+6), Equity: 499978, Cash: 498979
10.03.2010 10:30:00
Entry signals(score):
Exit signals:GAZP=Scale-Out,
Scale-Out Long GAZP, Price 174.8, Shares 2, Fx Rate 1, Number of shares - Current: 4, Exited: 2, Total Cost: 1019.82, Avg. Entry Price 169.97, Avg. Exit Price 174.8, Avg Fx. Rate Entry 1, Exit 1, Entry+scaling commission 1.50636
1 Open Positions: , GAZP (+4), Equity: 500023, Cash: 499328
06.04.2010 10:30:00
Entry signals(score):
Exit signals:GAZP=Sell,
Exit Long, GAZP, Price: 175.51, (Avg. exit pr. 175.273), Shares: 4, Commission: 0.772244, (Total comm.: 2.27861), Profit: 29.5414 (2.90 %), Entry rank:1, Equity: 500030, Fx rate: 1
0 Open Positions: , Equity: 500030, Cash: 500030
|
Может я в опциях чего перемудрил?
Код: |
SetBarsRequired(sbrAll,sbrAll);
SetOption( "InitialEquity", 500000);
SetOption( "DisableRuinStop", True);
SetOption( "AllowSameBarExit", True);
SetOption( "ActivateStopsImmediately", True);
SetOption( "MinShares", 1);
SetOption( "AllowPositionShrinking", true);
SetOption( "MinPosValue", 0);
SetOption( "MaxOpenPositions", 1000);
SetOption( "InterestRate", 0);
SetOption( "PriceBoundChecking", True);
SetOption( "AccountMargin", 100);
SetOption( "ReverseSignalForcesExit", False);
SetTradeDelays(0,0,0,0); |
|
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Это,а PositionSize = -2004; Это что?
PositionSize может быть отрицательным не меньше -100. -100 это 100% капитала инвестируется в сделку. А -2004 это не известно как Ами интерпретирует... |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
000 писал(а): |
Это,а PositionSize = -2004; Это что?
PositionSize может быть отрицательным не меньше -100. -100 это 100% капитала инвестируется в сделку. А -2004 это не известно как Ами интерпретирует... |
В хэлпе написано так:
Цитата: |
New SetPositionSize function automatically encodes new methods of expressing position size into old "positionsize" variable as follows:
values below -2000 encode share count,
values between -2000 and -1000 encode % of current position
values between -1000 and 0 encode % of portfolio equity
values above 0 encode dollar value |
Я это понимаю так, что любое значение ниже -2000 интерпретируется как число бумаг, т.е. -2200 соответствует 200 бумагам.
Совершенно точно могу сказать, что в коде размер позиции считается верно, о чем свидетельствует график. Но в целом какая-то ерунда получается
Вот такая покупка на ScaleIn ведет к утроению позиции:
Код: |
if ( pos == 1 ) Buy[i] = 1; else Buy[i] = sigScaleIn;
if ( pos == 1 ) PositionSize[i] = -2000 - Lot * RoundLotSize;
else PositionSize[i] = PositionSize[i] - Lot * RoundLotSize;
|
Т.е. как будто доливка происходит дважды. И действительно, т.к. следующий код "доливает" правильно:
Код: |
if ( pos == 1 ) Buy[i] = 1; else Buy[i] = sigScaleIn;
if ( pos == 1 ) PositionSize[i] = -2000 - Lot * RoundLotSize;
//else PositionSize[i] = PositionSize[i] - Lot * RoundLotSize;
|
А вот с уменьшением позиции все ровно наоборот. Без уточнения позиции вычитает не пойми как, а с уточнением все идеально, но это уточнение (PositionSize[i] = ....) нужно делать ДО sigScaleOut. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
Все получилось! Заморочно конечно вышло, но главное, что работает именно так, как надо. Тщательно проверил весь Detailed Log - нигде ни одного случая неправильно посчитанного размера позиции. Суть вкратце в том, что пришлось вернуться к backtestRegularRawMulti, отказаться от sigScaleIn и sigScaleOut, оставив только прямые Buy/Sell с переоткрытием позиции по средней цене (она считается отдельно) при выключенном PriceBoundChecking. Конечно комиссия учитывается дважды, но это и хорошо, типа эмуляции увеличенного проскальзывания. Если интересно подробнее, то могу привести куски кода. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Нифига ты заморочался... Супер. Самое что главное получилось. |
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
000 писал(а): |
Самое что главное получилось. |
Это да.
Олег, а есть ли способ узнать размер позиции, заданной в процентах, в "бумажном" эквиваленте? Хочу попробовать сделать то же самое, но для процентов. Т.е., к примеру, на первой сделке
Код: |
PositionSize[i] = -10; |
, после чего на первом "уполовинивании" продать все (тут сложностей нет) и купить обратно половину только что проданного объема (как?). Тут уже просто проценты не сработают, как мне кажется. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
000
Site Admin
Зарегистрирован: 10.12.2007
Сообщения: 9106
|
Размер позиции можно узнать только используя "UseCustomBacktestProc".
Мне кажется должно получиться использовать
Цитата: |
New SetPositionSize function automatically encodes new methods of expressing position size into old "positionsize" variable as follows:
values below -2000 encode share count,
values between -2000 and -1000 encode % of current position
values between -1000 and 0 encode % of portfolio equity
values above 0 encode dollar value
Although it is possible to assign these values directly to old-style PositionSize variable, new code should use SetPositionSize function for clarity.
|
|
_________________ ceterum censeo carthaginem esse delendam
Удачи. Олег. |
|
Посмотреть профиль Отправить личное сообщение Посетить сайт автора |
|
Marcello
Зарегистрирован: 30.05.2015
Сообщения: 69
|
Все оказалось намного проще. Достаточно после цикла вставить такие строки:
Код: |
SetPositionSize( 10, spsPercentOfEquity );
SetPositionSize( 50, IIf( Buy == sigScaleOut, spsPercentOfPosition, spsNoChange ) );
SetPositionSize( 100, IIf( Buy == sigScaleIn, spsPercentOfPosition, spsNoChange ) ); |
Кстати, такой же способ подходит и при начальном размере в лотах, а не в % от депозита. Первую строку нужно поменять на
Код: |
SetPositionSize( 10 * RoundLotSize, spsShares ); |
Но такой способ хорош, если вход двумя частями и выход также. Если же пропорции иные, то все получается сложнее. |
|
|
Посмотреть профиль Отправить личное сообщение |
|
helgir
Зарегистрирован: 05.05.2020
Сообщения: 8
|
Marcello писал(а): |
Все оказалось намного проще. Достаточно после цикла вставить такие строки:
Код: |
SetPositionSize( 10, spsPercentOfEquity );
SetPositionSize( 50, IIf( Buy == sigScaleOut, spsPercentOfPosition, spsNoChange ) );
SetPositionSize( 100, IIf( Buy == sigScaleIn, spsPercentOfPosition, spsNoChange ) ); |
Кстати, такой же способ подходит и при начальном размере в лотах, а не в % от депозита. Первую строку нужно поменять на
Код: |
SetPositionSize( 10 * RoundLotSize, spsShares ); |
Но такой способ хорош, если вход двумя частями и выход также. Если же пропорции иные, то все получается сложнее. |
Добрый день, а у вас получилось в итоге?
я просто пыталась сделать цикл на выход из лонга частями, но у меня не работает, выходит сразу одной сделкой и все тут.
Мой код был такой:
Код: |
SetPositionSize( 100, spsShares ); // 100 shares by default
SetPositionSize( 50, IIf( Buy == sigScaleOut, spsPercentOfPosition, spsNoChange ) ); // for scale-out use 50% of current position size
priceatbuy=0;
highsincebuy = 0;
exit = 0;
for( i = 0; i < BarCount; i++ )
{
if( priceatbuy == 0 AND Buy[ i ] )
{
priceatbuy = BuyPrice[ i ];
}
if( priceatbuy > 0 )
{
if( exit == 0 AND
Overbought[ i ]> myStochK[ i ] AND Overbought[ i-1 ]< myStochK[ i-1 ])
{
// first profit target hit - scale-out
exit = 1;
Buy[ i ] = sigScaleOut;
}
if( exit == 1 AND
nw[ i ]>j[ i ] )
{
Buy[ i ] = 0;
Sell[ i ] = exit + 1; // mark appropriate exit code
exit = 0;
priceatbuy = 0; // reset price
highsincebuy = 0;
}
}
}
SetPositionSize( 50, IIf( Ref(Buy,-1) == sigScaleOut, spsPercentOfPosition, spsNoChange ) );
SetPositionSize( 100, IIf( Ref(Buy,-1)== sigScaleIn, spsPercentOfPosition, spsNoChange ) ); |
|
|
|
Посмотреть профиль Отправить личное сообщение |
|
|
|
Следующая тема
Предыдущая тема
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете вкладывать файлы Вы не можете скачивать файлы
|
|