Список форумов AmiSite.ru AmiSite.ru
Форум по Ами
 FAQ  •  Поиск  •  Пользователи  •  Группы   •  Регистрация  •  Профиль  •  Войти и проверить личные сообщения  •  Вход
 Снова про размер позиции Следующая тема
Предыдущая тема
Начать новую тему  Ответить на тему
Автор Сообщение
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Чт Апр 13, 2017 9:49 pm Ответить с цитатой Вернуться к началу

Не могу сообразить, как сделать такую штуку:
Первоначальный размер позиции 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

СообщениеДобавлено: Пт Апр 14, 2017 6:54 am Ответить с цитатой Вернуться к началу

По моему это лучше и проще сделать через цикл. И PositionSize тоже в цикле задавать.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Пт Апр 14, 2017 9:19 am Ответить с цитатой Вернуться к началу

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

СообщениеДобавлено: Пт Апр 14, 2017 10:27 am Ответить с цитатой Вернуться к началу

1. PositionSize если отрицательная величина, то это процент от общего капитала

PositionSize[i] = -25; // 25% капитала в сделке.
2. backtestRegularRawMulti тебе не нужен. Этот режим позволяет открывать одновременно несколько позиций по бумаге а тебе это вроде не надо.
3. Не может быть чтобы открывалась только одна позиция. Где есть сигнал там должно открыться при условии, что не превышено число разрешенных одновременно открытых позиций.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Пт Апр 14, 2017 3:12 pm Ответить с цитатой Вернуться к началу

Это я знаю. Но у меня задумка чуть сложнее же. Открыли 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

СообщениеДобавлено: Пт Апр 14, 2017 3:52 pm Ответить с цитатой Вернуться к началу

ScaleIn работает тоже весьма странно Shocked
Код:
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

СообщениеДобавлено: Пт Апр 14, 2017 4:44 pm Ответить с цитатой Вернуться к началу

Это,а PositionSize = -2004; Это что?
PositionSize может быть отрицательным не меньше -100. -100 это 100% капитала инвестируется в сделку. А -2004 это не известно как Ами интерпретирует...

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Пт Апр 14, 2017 4:58 pm Ответить с цитатой Вернуться к началу

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 бумагам.

Совершенно точно могу сказать, что в коде размер позиции считается верно, о чем свидетельствует график. Но в целом какая-то ерунда получается Sad

Вот такая покупка на 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

СообщениеДобавлено: Пт Апр 14, 2017 10:13 pm Ответить с цитатой Вернуться к началу

Все получилось! Заморочно конечно вышло, но главное, что работает именно так, как надо. Тщательно проверил весь Detailed Log - нигде ни одного случая неправильно посчитанного размера позиции. Суть вкратце в том, что пришлось вернуться к backtestRegularRawMulti, отказаться от sigScaleIn и sigScaleOut, оставив только прямые Buy/Sell с переоткрытием позиции по средней цене (она считается отдельно) при выключенном PriceBoundChecking. Конечно комиссия учитывается дважды, но это и хорошо, типа эмуляции увеличенного проскальзывания. Если интересно подробнее, то могу привести куски кода.
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Пт Апр 14, 2017 10:33 pm Ответить с цитатой Вернуться к началу

Нифига ты заморочался... Супер. Самое что главное получилось.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Сб Апр 15, 2017 9:21 am Ответить с цитатой Вернуться к началу

000 писал(а):
Самое что главное получилось.
Это да.

Олег, а есть ли способ узнать размер позиции, заданной в процентах, в "бумажном" эквиваленте? Хочу попробовать сделать то же самое, но для процентов. Т.е., к примеру, на первой сделке
Код:
PositionSize[i] = -10;
, после чего на первом "уполовинивании" продать все (тут сложностей нет) и купить обратно половину только что проданного объема (как?). Тут уже просто проценты не сработают, как мне кажется.
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Сб Апр 15, 2017 10:20 am Ответить с цитатой Вернуться к началу

Размер позиции можно узнать только используя "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

СообщениеДобавлено: Сб Апр 15, 2017 2:34 pm Ответить с цитатой Вернуться к началу

Все оказалось намного проще. Достаточно после цикла вставить такие строки:
Код:
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

СообщениеДобавлено: Чт Июл 09, 2020 5:41 pm Ответить с цитатой Вернуться к началу

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 ) );
Посмотреть профиль Отправить личное сообщение
Показать сообщения:      
Начать новую тему  Ответить на тему


 Перейти:   



Следующая тема
Предыдущая тема
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы не можете скачивать файлы


Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme :: Часовой пояс: GMT + 3

File Attachment © by Meik Sievertsen