Discussing the article: "Developing a multi-currency Expert Advisor (Part 5): Variable position sizes"

 

Check out the new article: Developing a multi-currency Expert Advisor (Part 5): Variable position sizes.

In the previous parts, the Expert Advisor (EA) under development was able to use only a fixed position size for trading. This is acceptable for testing, but is not advisable when trading on a real account. Let's make it possible to trade using variable position sizes.

In the previous part, we dded the ability to restore the EA's state after a restart. It does not matter what the reason was - rebooting the terminal, changing the timeframe on the chart with the EA, launching a more recent version of the EA - in all cases, restoring the state allowed the EA not to start working from scratch and not to lose already open positions, but to continue handling them.

However, the size of the opened positions remained the same for each instance of the strategy throughout the entire testing period. Their size was set at the EA launch. If, as a result of the EA's operation, the trading account balance increased, then this would allow the use of an increased position size without increasing risk. It would be reasonable to take advantage of this, so let’s start implementing the use of variable position sizes.

Author: Yuriy Bykov

 

When I run the EA SimpleVolumesExpert with (3+3+3) and scaling 2.18, The log shows virtual trades opened but no real trades in strategy tester. Have I missed something?

 
Nigel Philip J Stephens #:

When I run SimpleVolumesExpert with (3+3+3) and scaling 2.18, the log shows open virtual trades, but no real trades in the strategy tester. Maybe I missed something?

Check that the initial balance in the tester is $10000 or more. I have this behaviour when the balance is not big enough. In this case, not every virtual position generates a real position. But the reason is probably something else, as your balance is probably correct.

Are there any real trades if the EA is run with other variants of strategy grouping?

 
I've been reading through your article extensively and found this to be exactly what I need to expand my knowledge. I appreciate your elaborate explanations on the topic and thoughtful coding decisions. Thank you.
 

Good afternoon. Thank you for your labour. I am very interested in your architecture and I am trying to understand it step by step. I have changed only the strategy class - I use my own. But at this stage I had difficulties with scaling the strategy. For the purity of the experiment, I used one instance of the strategy and two variants of the scale multiplier_ 1 and 2 (fixedBalance_ = 0;). In both cases, the result is the same - the lot size does not change. The place in the code where the lot size is determined

//+------------------------------------------------------------------+
//| Определение реального размера виртуальной позиции                |
//+------------------------------------------------------------------+
double CMoney::Volume(CVirtualOrder *p_order) {
   // Запрашиваем нормированный баланс стретегии для этой виртуальной позиции 
   double fittedBalance = p_order.FittedBalance();
   
   // Если он равен 0, то реальный объем равен виртуальному
   if(fittedBalance == 0.0) {
      return p_order.Volume();
   }
   
   // Иначе находим величину общего баланса для торговли
   double totalBalance = s_fixedBalance > 0 ? s_fixedBalance : AccountInfoDouble(ACCOUNT_BALANCE);
   
   // Возвращаем вычисленный реальный объем по виртуальному
   return p_order.Volume() * totalBalance * s_depoPart / fittedBalance ;
}
//+------------------------------------------------------------------+

However, the parameters m_fittedBalance and m_fixedLot are set by default in the virtual strategy constructor.

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CVirtualStrategy::CVirtualStrategy(double p_fittedBalance = 0,
                                   double p_fixedLot = 0.01) :
   m_fittedBalance(p_fittedBalance),
   m_fixedLot(p_fixedLot) {}

so the lot size does not change.

// Если он равен 0, то реальный объем равен виртуальному
   if(fittedBalance == 0.0) {
      return p_order.Volume();
   }

Although logically it should scale. Can you please tell me what is the reason? I don't want to meddle with my own edits - so as not to break it, and I have already added a few methods to the CVirtualOrder class because my strategy provides for partial closing, stop loss and closing on the counter signal.

 

Hello.

All is correct, for variable lot trading it is necessary for a strategy instance to be given the value of m_fittedBalance > 0. This is done by the inheritors of the base class of the trading strategy. This parameter is passed to them, and they substitute it into the call of the CVirtualStrategy constructor:

class CSimpleVolumesStrategy : public CVirtualStrategy {
...

public:
   //--- Публичные методы
   CSimpleVolumesStrategy(
      string           p_symbol,
      ENUM_TIMEFRAMES  p_timeframe,
      int              p_signalPeriod,
      double           p_signalDeviation,
      double           p_signaAddlDeviation,
      int              p_openDistance,
      double           p_stopLevel,
      double           p_takeLevel,
      int              p_ordersExpiration,
      int              p_maxCountOfOrders,
      double           p_fittedBalance = 0
   );                                     // Конструктор

   ...
};

...

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CSimpleVolumesStrategy::CSimpleVolumesStrategy(
   string           p_symbol,
   ENUM_TIMEFRAMES  p_timeframe,
   ...
   int              p_maxCountOfOrders,
   double           p_fittedBalance = 0) :
// Список инициализации
   CVirtualStrategy(p_fittedBalance, 0.01),
   m_symbol(p_symbol),
   m_timeframe(p_timeframe),
   ...
}

When creating instances, we specify a specific value for the last parameter so that the default value of 0 is not substituted into it:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   // Устанавливаем параметры в классе управления капиталом
   CMoney::DepoPart(expectedDrawdown_ / 10.0);
   CMoney::FixedBalance(fixedBalance_);

   // Создаем эксперта, работающего с виртуальными позициями
   expert = new CVirtualAdvisor(magic_, "SimpleVolumes_" + EnumToString(group_));

   // Создаем и наполняем массив из всех экземпляров стратегий
   CVirtualStrategy *strategies[] = {
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  13, 0.3, 1.0, 0, 10500,  465,  1000, 3, 1600),
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  17, 1.7, 0.5, 0, 16500,  220,  1000, 3,  900),
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  51, 0.5, 1.1, 0, 19500,  370, 22000, 3, 1600),

     ...
   };

   ...

   return(INIT_SUCCEEDED);
}

In the SimpleVolumesExpertSingle.mq5 Expert Advisor we do not do this, as the optimisation is only performed on a fixed initial position size. Note that the m_fixedLot parameter does not have to be used in the strategy exclusively as the size of all open virtual positions. It is just some base value from which we can calculate any others. In the model strategy in the article, simply the sizes of all positions are the same and this parameter is used without transformation. But nothing prevents you from opening a virtual position of size 10*m_fixedLot in another strategy and then applying its gradual closing.

 
Yuriy Bykov #:

Hello.

All is correct, for variable lot trading it is necessary for a strategy instance to be given the value of m_fittedBalance > 0. This is done by the inheritors of the base class of the trading strategy. This parameter is passed to them, and they substitute it into the call of the CVirtualStrategy constructor:

When creating instances, we specify a specific value for the last parameter so that the default value of 0 is not substituted into it:

In the SimpleVolumesExpertSingle.mq5 Expert Advisor we do not do this, as the optimisation is only performed on a fixed initial position size. Note that the m_fixedLot parameter does not have to be used in the strategy exclusively as the size of all open virtual positions. It is just some base value from which we can calculate any others. In the model strategy in the article, simply the sizes of all positions are the same and this parameter is used without transformation. But nothing prevents you from opening a virtual position of size 10*m_fixedLot in another strategy and then applying its gradual closing.

Hello. Thank you for your quick reply. I figured it out. I didn't immediately realise that the last parameter was added, because I was using my own strategy class and it has a slightly different set of parameters.