Хочется обсудить реализацию системы манименеджмента

 

Здравствуйте. Появилась у меня, вчера мысль. Но вчера я хотел спать и забил. Сегодня думал, и, хотя, понимаю как это сделать, но.. мне не нравится реализация, которую я придумал. Поэтому, решил написать сюда, что бы обсудить эту вещь, если кому будет интересно.

Суть следующая: я, обычно, не использовал манименеджмент(ММ), но, появилось желание проверить, как будут влиять, некоторые вариации на профитность систем. Так вот смысл в том, что есть желание, что бы когда я добавлю класс, в котором будут появляться различные системы ММ, я прямо из бота мог выбирать, например, enum'ом желаемую систему ММ. Т.е. запускаю я бота, и выбрал, например, систему №1, и, бот - торгует с этой системой ММ. Выбрал систему №2, и, бот торгует с этой системой ММ. Такое кто-нить вообще реализовывал?

Я это веду к тому, что любую систему можно будет удобно прогонять одним махом сразу по всем системам ММ (оптимизация по полю ММ). Понятно, что можно прописывать в коде какую систему использовать, но.. как говорится, лень - двигатель прогресса)) Только вот дело не в лени, а в том, что бы уделять внимание больше написанию кода, а не обезьянней работе, меняя тоже самое в каждой сове.

Если кому интересно, я могу накидать то, что думаю, сегодня. А дальше обсудить..

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

 
Viktar Dzemikhau:

Здравствуйте. Появилась у меня, вчера мысль. Но вчера я хотел спать и забил. Сегодня думал, и, хотя, понимаю как это сделать, но.. мне не нравится реализация, которую я придумал. Поэтому, решил написать сюда, что бы обсудить эту вещь, если кому будет интересно.

Суть следующая: я, обычно, не использовал манименеджмент(ММ), но, появилось желание проверить, как будут влиять, некоторые вариации на профитность систем. Так вот смысл в том, что есть желание, что бы когда я добавлю класс, в котором будут появляться различные системы ММ, я прямо из бота мог выбирать, например, enum'ом желаемую систему ММ. Т.е. запускаю я бота, и выбрал, например, систему №1, и, бот - торгует с этой системой ММ. Выбрал систему №2, и, бот торгует с этой системой ММ. Такое кто-нить вообще реализовывал?

Я это веду к тому, что любую систему можно будет удобно прогонять одним махом сразу по всем системам ММ (оптимизация по полю ММ). Понятно, что можно прописывать в коде какую систему использовать, но.. как говорится, лень - двигатель прогресса)) Только вот дело не в лени, а в том, что бы уделять внимание больше написанию кода, а не обезьянней работе, меняя тоже самое в каждой сове.

Если кому интересно, я могу накидать то, что думаю, сегодня. А дальше обсудить..

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

Все можно было описать двумя фразами.

Хочу через enum задавать параметр.Кто-нибудь так делал?

Ответ: да

 
Viktar Dzemikhau:

Здравствуйте. Появилась у меня, вчера мысль....

...

Ведь это пишется раз, и пользоваться придётся постоянно.

Оч большое предисловие...

Примерно так:

//--- enums
enum ENUM_MONEY_MANAGEMENT
  {
   MONEY_MANAGEMENT_FIX,               // Fixed volume
   MONEY_MANAGEMENT_MARTINGALE,        // Martingale
   MONEY_MANAGEMENT_DRUNK_TRADER,      // Drunk trader
   MONEY_MANAGEMENT_ENTIRE_CUTLET,     // Entire cutlet
   MONEY_MANAGEMENT_UNNECESSARY_MONEY, // Unnecessary money
   MONEY_MANAGEMENT_ETC                // etc ... 
  };
//--- input parameters
input ENUM_MONEY_MANAGEMENT InpMoneyManagement   =  MONEY_MANAGEMENT_FIX;

Т.е.: создаёте своё перечисление с описаниями, а потом создаёте входной параметр.

В примере, мною приведённом, по умолчанию будет выбран ММ с фиксированным лотом.

В перечислении можете свои нужные вам значения перечисления добавлять - я пример показал.

 
Artyom Trishkin:

Оч большое предисловие...

Примерно так:

Т.е.: создаёте своё перечисление с описаниями, а потом создаёте входной параметр.

В примере, мною приведённом, по умолчанию будет выбран ММ с фиксированным лотом.

В перечислении можете свои нужные вам значения перечисления добавлять - я пример показал.

Предисловие большое т.к. я хотел донести свою мысль. Вижу, что не донёс целиком. Всё что Вы написали я сделал. Но получилось так, что каждый раз, перед открытием позиции нужно будет создавать объект выбранной системы мани-менеджмента и тогда уже из неё получать полученное значение лота. А я хотел, как-то реализовать гибче, что бы вот так как Вы написал выбирать можно было из внешнего input-параметра систему ММ и в классе-родителе всех ММ создавался бы объект класса, который выбран и с ним работать на протяжении работы программы. Как это сделать не придумал. Остановился на этом варианте, как Вы написали. Я это после создания этой ветки сделал сам

.

Думал, подойти иначе. Нополиморфизм здесь не катит, т.к. у класса-родителя не всегда имеются все поля, как у наследника.

 
Viktar Dzemikhau:

Здравствуйте. Появилась у меня, вчера мысль. Но вчера я хотел спать и забил. Сегодня думал, и, хотя, понимаю как это сделать, но.. мне не нравится реализация, которую я придумал. Поэтому, решил написать сюда, что бы обсудить эту вещь, если кому будет интересно.

Суть следующая: я, обычно, не использовал манименеджмент(ММ), но, появилось желание проверить, как будут влиять, некоторые вариации на профитность систем. Так вот смысл в том, что есть желание, что бы когда я добавлю класс, в котором будут появляться различные системы ММ, я прямо из бота мог выбирать, например, enum'ом желаемую систему ММ. Т.е. запускаю я бота, и выбрал, например, систему №1, и, бот - торгует с этой системой ММ. Выбрал систему №2, и, бот торгует с этой системой ММ. Такое кто-нить вообще реализовывал?

Я это веду к тому, что любую систему можно будет удобно прогонять одним махом сразу по всем системам ММ (оптимизация по полю ММ). Понятно, что можно прописывать в коде какую систему использовать, но.. как говорится, лень - двигатель прогресса)) Только вот дело не в лени, а в том, что бы уделять внимание больше написанию кода, а не обезьянней работе, меняя тоже самое в каждой сове.

Если кому интересно, я могу накидать то, что думаю, сегодня. А дальше обсудить..

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

Хорошая идея.

Ждем реализацию.

 
Viktar Dzemikhau:

***

Всё можно. Пример кода: Expert Ichimoku

Реализована схема:

  • размер лота постоянный (входной параметр Lots ставим больше нуля, а входной параметр Risk ставим равным нулю)
  • размер лота динамический (входной параметр Lots ставим равным нулю, а входной параметр Risk ставим больше нуля)

Здесь Risk - это процент риска на сделку (используется класс CMoneyFixedMargin - торговля с фиксированным уровнем маржи).

Можно прикрутить класс CMoneyFixedRisk - торговля с фиксированным уровнем риска.


Сравнить работу этих двух классов можно здесь: Money Fixed Margin и Money Fixed Risk. Здесь наглядно показано, как влияет Стоп Лосс на расчёт объёма позиции: чтоб будет если указать Стоп Лосс равным нулю и что будет если указать Стоп Лосс не равным нулю.

 
Viktar Dzemikhau:
Предисловие большое т.к. я хотел донести свою мысль. Вижу, что не донёс целиком. Всё что Вы написали я сделал. Но получилось так, что каждый раз, перед открытием позиции нужно будет создавать объект выбранной системы мани-менеджмента и тогда уже из неё получать полученное значение лота. А я хотел, как-то реализовать гибче, что бы вот так как Вы написал выбирать можно было из внешнего input-параметра систему ММ и в классе-родителе всех ММ создавался бы объект класса, который выбран и с ним работать на протяжении работы программы. Как это сделать не придумал. Остановился на этом варианте, как Вы написали. Я это после создания этой ветки сделал сам

.

Думал, подойти иначе. Нополиморфизм здесь не катит, т.к. у класса-родителя не всегда имеются все поля, как у наследника.

Зачем создавать объект каждый раз перед открытием позиции? Объект создаёте один раз в OnInit() в зависимости от настроек внешних параметров. И будет вам постоянно выбран один из возможных методов расчёта лота. Сменили в настройках ММ - сменился тип ММ в классе ММ, и программа использует уже иной тип ММ.

Всё же просто.

 
Vladimir Karputov:

Всё можно. Пример кода: Expert Ichimoku

Реализована схема:

  • размер лота постоянный (входной параметр Lots ставим больше нуля, а входной параметр Risk ставим равным нулю)
  • размер лота динамический (входной параметр Lots ставим равным нулю, а входной параметр Risk ставим больше нуля)

Здесь Risk - это процент риска на сделку (используется класс CMoneyFixedMargin - торговля с фиксированным уровнем маржи).

Можно прикрутить класс CMoneyFixedRisk - торговля с фиксированным уровнем риска.


Сравнить работу этих двух классов можно здесь: Money Fixed Margin и Money Fixed Risk. Здесь наглядно показано, как влияет Стоп Лосс на расчёт объёма позиции: чтоб будет если указать Стоп Лосс равным нулю и что будет если указать Стоп Лосс не равным нулю.

Владимир, я так не пишу. У меня не процедурное программирование. Я если пишу какой-то метод, обычно, он у меня встречается 1 раз во всей иерархии. Больше его нигде не встретишь. Максимум бывает ни одна перегрузка. если разные типы (т.к. в мкл нет нормального приведения к объекту это приходится делать иногда). Поэтому первоначально продумывать архитектуру сложнее чутка, чем у других. Но это не преграда.

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

 
Renat Akhtyamov:

Хорошая идея.

Ждем реализацию.

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

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|                                                                                                                                                                            MoneyManagement.mqh |
//|                                                                                                                                                                                            hoz |
//|                                                                                                                                                                                                |
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
#property copyright "hoz"
#property link      ""
#property version   "1.00"

#import    "EnvironmentInfo\AccountInfo.ex5"
  double  balance(void);   // Возвращает баланс счета в валюте депозита
  double  equity(void);    // Возвращает значение собственных средств на счете в валюте депозита
#import

#include  <HOZ_Code\Enums\InitialLotSize.mqh>
#include  <HOZ_Code\Enums\MoneyManagmentSystem.mqh>
#include  <HOZ_Code\Classes\MoneyManagement\FixedPercent.mqh>
#include  <HOZ_Code\Classes\MoneyManagement\NextLotWillBeIncreaseByTwoBasedLot.mqh>

// =======================================================================================  Input переменные  =====================================================================================+
input string   __toRealizeMoneyManagement  =  "Input parameters of money-managment";
input ENUM_INITIAL_LOT_SIZE         i_initialLotSize = LOT_FIXED_SIZE;    // Переключатель первоначального размера лота для торговли
input ENUM_MONEY_MANAGMENT_SYSTEM   i_moneyManagementSystem = NONE;       // Переключатель систем мани-менеджмента
input double   i_lot = 0.1;    // Объём позиции

//==================================================================================================================================================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//|                                                                                   КЛАСС ДЛЯ МАНИ-МЕНЕДЖМЕНТА                                                                                   |
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+================================================================================================================================================================================================+
class MoneyManagement {
  private:
    double   m_minLot;    // минимальный объём торгового лота
  public:
    //--- Конструктор и деструктор
    MoneyManagement(void);
   ~MoneyManagement(void);
    //--- Свойства
    double   getMinLot(void);
    double   getLotToTrade(void);
};
//==================================================================================================================================================================================================
// Конструктор класса. =============================================================================================================================================================================
MoneyManagement :: MoneyManagement(void) {
  m_minLot = getMinLot();
}
//==================================================================================================================================================================================================
// Деструктор класса. ==============================================================================================================================================================================
MoneyManagement :: ~MoneyManagement(void) {
}
//==================================================================================================================================================================================================
// Возвращает минимальное значение торгового лота, на основании input-параметра i_initialLotSize. ==================================================================================================
double MoneyManagement :: getMinLot(void) {
  switch (i_initialLotSize) {
    case LOT_IN_PERCENT_OF_EQUITY:
      return equity() / 100 * i_lot;
    case LOT_IN_PERCENT_OF_BALANCE:
      return balance() / 100 * i_lot;
    default:
      return i_lot;    // case LOT_FIXED_SIZE
  }
}
//==================================================================================================================================================================================================
// Возвращает значение торгового лота, используя выбранную систему мани-менеджмента посредством внешнего параметра i_moneyManagementSystem. ========================================================
double MoneyManagement :: getLotToTrade(void) {
  switch (i_moneyManagementSystem) {
    case NEXT_LOT_WILL_BE_INCREASE_BY_TWO_BASED_LOT: {
      NextLotWillBeIncreaseByTwoBasedLot nextLotWillBeIncreaseByTwoBasedLot(m_minLot);
      return nextLotWillBeIncreaseByTwoBasedLot.getLot();
    }
    default:
      return m_minLot;    // case NONE
  }
}
Он, как видно, расширяем.

Как видно, метод getMinLot() возвращает минимальный лот, который задал пользователь. Дальше.. если система ММ не выбрана, а точнее она NONE, тогда будет торговля производится либо фиксированным лотом, либо процентов от эквити или баланса. Ну а если выбрана система ММ, тогда будет браться это минимальное значение лота и передаваться в выбранную систему через параметр и там уже генерироваться торговый лот.

Осталось только проверки лота на корректность проверить и всё. Ну и протестировать всё. Я только нашёл время и накидал набросок. Раньше не было времени этим заняться. Приоритеты сменились.

В самом торговом боте будет вот так лот получать из класса:

  lot = prMoneyManagement.getLotToTrade();

где, prMoneyManagement соответственно, указатель на класс ММ.

 
Artyom Trishkin:

Зачем создавать объект каждый раз перед открытием позиции? Объект создаёте один раз в OnInit() в зависимости от настроек внешних параметров. И будет вам постоянно выбран один из возможных методов расчёта лота. Сменили в настройках ММ - сменился тип ММ в классе ММ, и программа использует уже иной тип ММ.

Всё же просто.

Я привёл код, который написал. Создать объект под конкретную систему ММ..тогда придётся в конструкторе switch сделать я так понимаю? Я как написал каркас, проще думать уже над канкретикой. А когда ничего не было, не просто))

Я пришёл к тому, что прежде чем написать что-то грамотно, нужно писать как пишется. Потому пару раз отредактировал, оптимизировал.. и постепенно получается пуля. А если думать ничего не написал, может мозг перегрузиться.

 
Viktar Dzemikhau:

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

Он, как видно, расширяем.

Как видно, метод getMinLot() возвращает минимальный лот, который задал пользователь. Дальше.. если система ММ не выбрана, а точнее она NONE, тогда будет торговля производится либо фиксированным лотом, либо процентов от эквити или баланса. Ну а если выбрана система ММ, тогда будет браться это минимальное значение лота и передаваться в выбранную систему через параметр и там уже генерироваться торговый лот.

Осталось только проверки лота на корректность проверить и всё. Ну и протестировать всё. Я только нашёл время и накидал набросок. Раньше не было времени этим заняться. Приоритеты сменились.

В самом торговом боте будет вот так лот получать из класса:

где, prMoneyManagement соответственно, указатель на класс ММ.

Зачем нужен этот класс, если он ничего не делает?

Его легко можно заменить одной функцией.

double MMgetLotToTrade()
{
   double m_minLot = i_lot;
   
   switch( i_initialLotSize ){
      case LOT_IN_PERCENT_OF_EQUITY:
         m_minLot = equity() / 100.0 * i_lot;
         break;
      case LOT_IN_PERCENT_OF_BALANCE:
         m_minLot = balance() / 100.0 * i_lot;
         break;
   }
   
   if( i_moneyManagementSystem == NEXT_LOT_WILL_BE_INCREASE_BY_TWO_BASED_LOT ){
      NextLotWillBeIncreaseByTwoBasedLot nextLotWillBeIncreaseByTwoBasedLot( m_minLot );
      return nextLotWillBeIncreaseByTwoBasedLot.getLot();
   }
   else {
      return m_minLot;
   }
}

Используем:

lot = MMgetLotToTrade();

Необходимость класса NextLotWillBeIncreaseByTwoBasedLot тоже под сомнением.

Причина обращения: