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



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

СообщениеДобавлено: Пн Авг 03, 2015 12:00 am Ответить с цитатой Вернуться к началу

Приветствую!

Решил прикрутить Фиксировано-пропорциональный метод (ФПМ) управления капиталом. Суть метода в следующем:
Цитата:
Согласно т.н. фиксированно-пропорционного метода Джонса, для того, чтобы к уже имеющемуся количеству лотов прибавить ещё один, каждый из уже имеющихся должен "заработать" некое кол-во пунктов (последнее Джонс назвал "дельтой"). Например, если у нас есть депо в $300 и мы работаем 1 минилотом, определив дельту равной, допустим, тем же $300, то мы перейдем на 2 минилота, когда наберем (имеющимся 1 минилотом) $300, а увеличение количества лотов до 3 произойдет только когда теперь уже 2 минилота заработают – каждый – по дельте ($300) (т.е. переход с 2 минилотов на 3 будет, когда мы к имеющимся $600 добавим ещё 2 х $300 = $600, т.е. при $1200), с 3 на 4 минилота – при депо в $1200 + ($300 х 3) = $1200 + $900 = $2100 и т.д. Таким образом, "по мере роста числа контрактов сумма, необходимая для приобретения очередного кол-ва контрактов, увеличивается пропорционально", откуда и название метода.


Провел тестирование 1 лотом. Получил Net Profit 7495.52. Разделил профит условно на 15 частей, получив "дельту" равной 500. Далее написал функцию, которая определяет размер позиции:
Код:
/*
x - бар для определения
xDelta - дельта
xSize - текущий размер
*/
function getSize( x, xDelta, xSize ) {
   ySize = 1;
   xEq = Equity();
   vEq = xEq[x] - 1000000; // InitialEquity установлен в 1 млн.
   while ( vEq > 0 ) {
      ySize++;
      vEq = vEq - xDelta * xSize;
   }
   return ySize;
}

Вызываю в цикле вот так (вход на текущем баре, поэтому размер позиции определяю для "вчерашнего" бара):
Код:
S[i] = getSize( i-1, 500, S[i] );

В конце выставляю размер позиции:
Код:
SetPositionSize( S * RoundLotSize, spsShares );

Есть подозрения, что я что-то делаю не так, потому что никакого улучшения не наблюдается, как и получения "максимальной прибыли при оч. разумной просадке" (как пишут в некоторых источниках). Если использовать 100% капитала, то округленно получаю профит 1780000 при макс.просадке -977000 (в "пунктах"). Если использовать ФПМ, то просадка снижается до -235000 (т.е. почти в 4 раза), а профит падает до 471000 (тоже почти в 4 раза). Профит фактор правда возрастает с 2.2 до 3.3, но толку от этого немного, т.к. рекавери фактор также снижается с 1.82 до 1.71.


Последний раз редактировалось: Marcello (Вт Сен 15, 2015 6:48 pm), всего редактировалось 1 раз
Посмотреть профиль Отправить личное сообщение
000
Site Admin


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

СообщениеДобавлено: Пн Авг 03, 2015 12:37 am Ответить с цитатой Вернуться к началу

Не думаю что в таком ММ есть смысл.
Так как ты написал работать скорее всего не будет. Проверь в отчете сайз сделок соответствует ли он алгоритму.
Я думаю, что функция Equity() считает экити не учитывая сайз полученый после работы функции getSize.
Для того, чтобы реализовать точно пожалуй придется городить огород через Custom backtester interface
http://www.amibroker.com/docs/Houston2.pdf

Там есть подходящий пример на стренице 23

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



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

СообщениеДобавлено: Пн Авг 03, 2015 9:07 am Ответить с цитатой Вернуться к началу

Проверил. Не соответствует. Даже несмотря на то, что использую цикл. Видимо так и придется разбираться с Custom backtester interface.
Посмотреть профиль Отправить личное сообщение
Marcello



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

СообщениеДобавлено: Пн Авг 03, 2015 10:45 am Ответить с цитатой Вернуться к началу

000 писал(а):

Для того, чтобы реализовать точно пожалуй придется городить огород через Custom backtester interface
http://www.amibroker.com/docs/Houston2.pdf

Там есть подходящий пример на стренице 23


Что-то с наскока не получается прикрутить Custom backtester interface.

Оставил функцию определения размера позиции:
Код:
function getSize( xEquity, xDelta, xSize ) {
   ySize = 1;
   vEq = xEquity - 1000000; // InitialEquity установлен в 1 млн.
   while ( vEq > 0 ) {
      ySize++;
      vEq = vEq - xDelta * xSize;
   }
   return ySize;
}

Далее добавил такой код:
Код:
if( Status("action") == actionPortfolio )
{
    vPos = 1;
    bo = GetBacktesterObject();
   bo.PreProcess();
   for ( bar = 0; bar < BarCount; bar++ ) {
      EQ = bo.Equity;
      for ( sig = bo.GetFirstSignal(); sig; sig = bo.GetNextSignal() ) {
         if ( sig.IsExit() ) continue;
         vPos = getSize( EQ, 500, vPos );
         sig.PosSize = vPos * RoundLotSize;
      }
      bo.ProcessTradeSignals(bar);
   }
   bo.PostProcess();
}

И снова ничего не происходит. Менял xDelta, оставлял в getSize возврат 1 лота
Код:
function getSize( xEquity, xDelta, xSize ) {
   ySize = 1;
   return ySize;
}
- результат одинаковый, будто вход происходит всегда на 100% депозита. Не пойму в чем дело.

Не могут ли на это влиять опции ?
Код:
SetOption("FuturesMode", True );
SetOption( "InitialEquity", 1000000);
SetOption( "DisableRuinStop", True);
SetOption( "AllowSameBarExit", True);
SetOption( "ActivateStopsImmediately", True);
SetOption( "MinShares", 1);
SetOption( "AllowPositionShrinking", true);
SetOption( "MinPosValue", 0);
SetOption( "MaxOpenPositions", 100);
SetOption( "InterestRate", 0);
SetOption( "PriceBoundChecking", True);
SetOption( "AccountMargin", 100);
SetOption( "ReverseSignalForcesExit", False);
SetTradeDelays(0,0,0,0); 
Посмотреть профиль Отправить личное сообщение
Marcello



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

СообщениеДобавлено: Пн Авг 03, 2015 11:19 am Ответить с цитатой Вернуться к началу

Чтобы изменилась процедура бэктестинга, добавил строку:
Код:
SetCustomBacktestProc("");

Сразу вылезла ошибка в коде
Код:
for ( sig = bo.GetFirstSignal(); sig; sig = bo.GetNextSignal() ) {

Переписал фрагмент так:
Код:
if( Status("action") == actionPortfolio )
{
    vPos = 1;
    bo = GetBacktesterObject();
   bo.PreProcess();
   for ( bar = 0; bar < BarCount; bar++ ) {
      EQ = bo.Equity;
      for ( sig = bo.GetFirstSignal(bar); sig; sig = bo.GetNextSignal(bar) ) {
         if ( sig.IsExit() ) continue;
         //vPos = getSize( EQ, 100, vPos );
         sig.PosSize = vPos * RoundLotSize; // всегда 1 лот
      }
      bo.ProcessTradeSignals(bar);
   }
   bo.PostProcess();
}


Тестер показывает 0 сделок. Подробный отчет пишет:
Цитата:
GAZP not entered because of insufficient funds or wrong position size/value (reqEntryPrice: 285, reqEntryPosSize: 0 (value = 0), reqLotSize: 10)


Что может быть не так?
Посмотреть профиль Отправить личное сообщение
000
Site Admin


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

СообщениеДобавлено: Вт Авг 04, 2015 7:54 pm Ответить с цитатой Вернуться к началу

Завтра вечером поковыряюсь. Ща некогда.

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


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

СообщениеДобавлено: Ср Авг 05, 2015 11:35 pm Ответить с цитатой Вернуться к началу

Вроде работает.
Код:

SetOption("UseCustomBacktestProc", True );

SetOption("FuturesMode", True );
SetOption( "InitialEquity", 1000000);
SetOption( "DisableRuinStop", True);
SetOption( "AllowSameBarExit", True);
SetOption( "ActivateStopsImmediately", True);
SetOption( "MinShares", 1);
SetOption( "AllowPositionShrinking", true);
SetOption( "MinPosValue", 0);
SetOption( "MaxOpenPositions", 100);
SetOption( "InterestRate", 0);
SetOption( "PriceBoundChecking", True);
SetOption( "AccountMargin", 100);
SetOption( "ReverseSignalForcesExit", False);
SetTradeDelays(0,0,0,0);

delta = 300;

Buy = Cross(C, MA(C, 30));
Sell = Cross(MA(C, 20), C);

if( Status("action") == actionPortfolio )
{
   vPos = 1;
   bo = GetBacktesterObject();
   bo.PreProcess();
   for ( bar = 0; bar < BarCount; bar++ )
   {
      EQ = bo.Equity;
      for ( sig = bo.GetFirstSignal(bar); sig; sig = bo.GetNextSignal(bar) )
      {
         if( sig.IsEntry() )
         {
            PS = Max(1, int((EQ - 1000000)/delta));
            sig.PosSize = PS*sig.Price;
         }   
      }
      bo.ProcessTradeSignals(bar);
   }
   bo.PostProcess();
}

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



Зарегистрирован: 29.04.2010
Сообщения: 729
Откуда: Moscow

СообщениеДобавлено: Чт Авг 06, 2015 10:27 am Ответить с цитатой Вернуться к началу

Олег, подскажи, эти фокусы с актиавцией custom backtester'a работают в режиме Walk Forward'a? Или это подходит только для обычного бэктеста?
Посмотреть профиль Отправить личное сообщение ICQ Number
000
Site Admin


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

СообщениеДобавлено: Чт Авг 06, 2015 10:32 am Ответить с цитатой Вернуться к началу

Не знаю. Wink Думаю что работают.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:      
Начать новую тему  Ответить на тему


 Перейти:   



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


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

File Attachment © by Meik Sievertsen