Как начать работу с MQL5 - страница 30

 
CodeFx # :

***

Однако мой первоначальный код ежегодно открывал несколько позиций, как и ожидалось, но его проблема заключалась в том, что когда последняя открытая позиция на покупку находится в убытке, он не может открыть позицию на продажу, как предполагалось. Пожалуйста, взгляните на код:

***

Я не понимаю. Опишите другими словами.

И далее:

 
Vladimir Karputov #:

Я не понимаю. Опишите другими словами.

И далее:


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

Спасибо за помощь.

 
CodeFx #:
Я имел в виду, что если последняя открытая позиция - это покупка (с максимальным размером лота, и ни одна из открытых позиций не имеет равного размера лота), а текущий рыночный тренд идет вниз, заставляя эту позицию на покупку терять минимум 250 пунктов, то есть не приносить прибыль, то советник должен открыть позицию на продажу с тем же размером лота, что и на покупку .

Ок. Добавьте код:

 
CodeFx # :

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

Спасибо за помощь.

Ваша ошибка: Вы помните параметры определенной позиции, но по какой-то причине сравниваете их в объекте m_positions:

      if(last_position_type==POSITION_TYPE_BUY && last_position_price_open> m_position.PriceCurrent() + (m_take_profit))
         if(count_max_volume==1 && last_position_volume==max_volume)
            m_trade.Sell(last_position_volume*1.0,m_symbol.Name(),Bid,0,(Bid-m_take_profit),NULL);
 
Vladimir Karputov #:

Ок. Добавьте код:


Когда последняя открытая позиция является покупкой (ее размер лота в настоящее время является самым высоким и ни одна из открытых позиций не имеет равного размера лота) и текущий рыночный тренд идет вниз, тем самым заставляя эту позицию покупки терять минимум 250 пунктов, то есть не приносить прибыль, тогда советник должен открыть позицию продажи с тем же размером лота, что и покупка, и наоборот .

Пожалуйста, посмотрите мой оригинальный код до предложенного вами решения ниже:

//+------------------------------------------------------------------+
//|                                                 New edition).mq5 |
//|                                              Copyright © 2021,   |
//|                                          |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2021"
#property link      "CodeFx"
#property version   "1.000"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Trade\OrderInfo.mqh>

CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
COrderInfo     m_order;                      // pending orders object
//--- input parameters
input ushort   InpStep           = 10;
input double   InpLot            = 0.01;
ulong          m_magic           = 12345;    // magic number
ulong          m_slippage        = 30;       // slippage
//---
double         ExtStep           = 0.0;
double         m_adjusted_point;             // point value adjusted for 3 or 5 points
input int      PF                = 10;       // Incremental Profit To Close All Trades
input int      DEP               = 1000;     // Deposit or Start Balance 
input int      TP                = 250;      // TakeProfit
double         Previous_balance  = AccountInfoDouble (ACCOUNT_BALANCE); // Balance at start of each algorithm  

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
 
   Comment("????? ????????? ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS));
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);
   RefreshRates();

   string err_text="";
   if(!CheckVolumeValue(InpLot,err_text))
     {
      Print(err_text);
      return(INIT_PARAMETERS_INCORRECT);
     }
//---
   m_trade.SetExpertMagicNumber(m_magic);
//---
   if(IsFillingTypeAllowed(m_symbol.Name(),SYMBOL_FILLING_FOK))
      m_trade.SetTypeFilling(ORDER_FILLING_FOK);
   else if(IsFillingTypeAllowed(m_symbol.Name(),SYMBOL_FILLING_IOC))
      m_trade.SetTypeFilling(ORDER_FILLING_IOC);
   else
      m_trade.SetTypeFilling(ORDER_FILLING_RETURN);
//---
   m_trade.SetDeviationInPoints(m_slippage);
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;

   ExtStep=InpStep*m_adjusted_point;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   datetime             last_position_time         = 0;
   double               last_position_price_open   = 0.0;
   double               last_position_volume       = 0.0;
   ENUM_POSITION_TYPE   last_position_type         = -1;
   int                  count_positions            = 0;    
   int                  count_max_volume           = 0;
   double               total_profit               = 0;

   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
           {
            if(m_position.Time()>last_position_time)
              {
               last_position_time         = m_position.Time();
               last_position_price_open   = m_position.PriceOpen();
               last_position_volume       = m_position.Volume();
               last_position_type         = m_position.PositionType();               
              }
            count_positions++;
            count_max_volume++;           
            total_profit=total_profit+m_position.Commission()+m_position.Swap()+m_position.Profit();
           }
   int count_pending_orders=0;
   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders
      if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties
         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)
            count_pending_orders++;

if (PositionsTotal()==0)
{Previous_balance = AccountInfoDouble (ACCOUNT_BALANCE);} 

double equity    = AccountInfoDouble (ACCOUNT_EQUITY);
if(equity > Previous_balance + PF) 
     {
      Print("Closing on profit");
      CloseAllPositions();
      return;
     } 

   if(!RefreshRates())
      return;

   if(count_positions>0)
     {
       double Ask=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_ASK),_Digits);
       double Bid=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_BID),_Digits); 
       double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
       
       if(last_position_type==POSITION_TYPE_BUY && m_symbol.Ask()-(TP * _Point) >last_position_price_open )                  
         m_trade.Buy(last_position_volume*2,m_symbol.Name(),Ask,0,(Ask+TP*_Point),NULL);
                                     
       if(last_position_type==POSITION_TYPE_BUY && last_position_price_open > m_position.PriceCurrent() + (TP * _Point) )                                 
       if(count_max_volume==1 && last_position_volume==max_volume) 
           m_trade.Sell(last_position_volume*1,m_symbol.Name(),Bid,0,(Bid-TP*_Point),NULL); 
                              
       if(last_position_type==POSITION_TYPE_SELL && m_symbol.Bid()+(TP * _Point) <last_position_price_open )       
         m_trade.Sell(last_position_volume*2,m_symbol.Name(),Bid,0,(Bid-TP*_Point),NULL);  
        
       if(last_position_type==POSITION_TYPE_SELL && last_position_price_open < m_position.PriceCurrent() - (TP * _Point) )                                                  
       if(count_max_volume==1 && last_position_volume==max_volume) 
           m_trade.Buy(last_position_volume*1,m_symbol.Name(),Ask,0,(Ask+TP*_Point),NULL);                                                                                                                   
               }

   if(count_positions==0 && count_pending_orders==0)
     {
      double Ask=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_ASK),_Digits);
      double Bid=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_BID),_Digits);     
      m_trade.Sell(InpLot,m_symbol.Name(),Bid,0,(Bid-TP*_Point),NULL);                 
      m_trade.Buy(InpLot,m_symbol.Name(),Ask,0,(Ask+TP*_Point),NULL);      
      return;
     }

   if(count_positions>0 && count_pending_orders>0)
      DeleteAllOrders();
//---
   return;
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
  
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &error_description)
  {
//--- minimal allowed volume for trade operations
// double min_volume=m_symbol.LotsMin();
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
// double max_volume=m_symbol.LotsMax();
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- get minimal step of volume changing
// double volume_step=m_symbol.LotsStep();
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                                     volume_step,ratio*volume_step);
      return(false);
     }
   error_description="Correct volume value";
   return(true);
  }
//+------------------------------------------------------------------+ 
//| Checks if the specified filling mode is allowed        .          | 
//+------------------------------------------------------------------+ 
bool IsFillingTypeAllowed(string symbol,int fill_type)
  {
//--- Obtain the value of the property that describes allowed filling modes 
   int filling=(int)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);
//--- Return true, if mode fill_type is allowed 
   return((filling & fill_type)==fill_type);
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions()
  { 
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
  }
//+------------------------------------------------------------------+
//| Delete all pendingA rders                                         |
//+------------------------------------------------------------------+
void DeleteAllOrders()
  {
   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders
      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties
         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)
            m_trade.OrderDelete(m_order.Ticket());
  }
//+------------------------------------------------------------------+
Файлы:
 
Vladimir Karputov #:

Ваша ошибка: Вы помните параметры определенной позиции, но по какой-то причине сравниваете их в объекте m_positions:

Спасибо за ответ. Пожалуйста, подтвердите предложенное вами исправление:

         if(last_position_type==POSITION_TYPE_BUY && last_position_price_open> m_symbol.Ask() + (m_take_profit))
         if(count_max_volume==1 && last_position_volume==max_volume)
            m_trade.Sell(last_position_volume*1.0,m_symbol.Name(),Bid,0,(Bid-m_take_profit),NULL);

Исходя из вышесказанного, полный код выглядит следующим образом:

//+------------------------------------------------------------------+
//|                                                 New edition).mq5 |
//|                                              Copyright © 2021,   |
//|                                          |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2021"
#property link      "CodeFx"
#property version   "1.000"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
#include <Trade\OrderInfo.mqh>

CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
COrderInfo     m_order;                      // pending orders object
//--- input parameters
input ushort   InpStep           = 10;
input double   InpLot            = 0.01;
ulong          m_magic           = 12345;    // magic number
ulong          m_slippage        = 30;       // slippage
//---
double         ExtStep           = 0.0;
double         m_adjusted_point;             // point value adjusted for 3 or 5 points
input int      PF                = 10;       // Incremental Profit To Close All Trades
input int      DEP               = 1000;     // Deposit or Start Balance 

double         Previous_balance  = AccountInfoDouble (ACCOUNT_BALANCE); // Balance at start of each algorithm  
double         m_take_profit     = 250;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
 
   Comment("????? ????????? ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS));
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);
   RefreshRates();

   string err_text="";
   if(!CheckVolumeValue(InpLot,err_text))
     {
      Print(err_text);
      return(INIT_PARAMETERS_INCORRECT);
     }
//---
   m_trade.SetExpertMagicNumber(m_magic);
//---
   if(IsFillingTypeAllowed(m_symbol.Name(),SYMBOL_FILLING_FOK))
      m_trade.SetTypeFilling(ORDER_FILLING_FOK);
   else if(IsFillingTypeAllowed(m_symbol.Name(),SYMBOL_FILLING_IOC))
      m_trade.SetTypeFilling(ORDER_FILLING_IOC);
   else
      m_trade.SetTypeFilling(ORDER_FILLING_RETURN);
//---
   m_trade.SetDeviationInPoints(m_slippage);
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;

   ExtStep=InpStep*m_adjusted_point;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   datetime             last_position_time         = 0;
   double               last_position_price_open   = 0.0;
   double               last_position_volume       = 0.0;
   ENUM_POSITION_TYPE   last_position_type         = -1;
   int                  count_positions            = 0;    
   int                  count_max_volume           = 0;
   double               total_profit               = 0;

   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
           {
            if(m_position.Time()>last_position_time)
              {
               last_position_time         = m_position.Time();
               last_position_price_open   = m_position.PriceOpen();
               last_position_volume       = m_position.Volume();
               last_position_type         = m_position.PositionType();               
              }
            count_positions++;
            count_max_volume++;           
            total_profit=total_profit+m_position.Commission()+m_position.Swap()+m_position.Profit();
           }
   int count_pending_orders=0;
   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders
      if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties
         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)
            count_pending_orders++;

if (PositionsTotal()==0)
{Previous_balance = AccountInfoDouble (ACCOUNT_BALANCE);} 

double equity    = AccountInfoDouble (ACCOUNT_EQUITY);
if(equity > Previous_balance + PF) 
     {
      Print("Closing on profit");
      CloseAllPositions();
      return;
     } 

   if(!RefreshRates())
      return;

   if(count_positions>0)
     {
       double Ask=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_ASK),_Digits);
       double Bid=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_BID),_Digits); 
       double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
       
       if(last_position_type==POSITION_TYPE_BUY && m_symbol.Ask()-(m_take_profit) >last_position_price_open )                  
         m_trade.Buy(last_position_volume*2,m_symbol.Name(),Ask,0,(Ask+m_take_profit),NULL);
                                     
       if(last_position_type==POSITION_TYPE_BUY && last_position_price_open> m_symbol.Ask() + (m_take_profit))
         if(count_max_volume==1 && last_position_volume==max_volume)
            m_trade.Sell(last_position_volume*1.0,m_symbol.Name(),Bid,0,(Bid-m_take_profit),NULL);
                                          
       if(last_position_type==POSITION_TYPE_SELL && m_symbol.Bid()+(m_take_profit) <last_position_price_open )       
         m_trade.Sell(last_position_volume*2,m_symbol.Name(),Bid,0,(Bid-m_take_profit),NULL);  
        
       if(last_position_type==POSITION_TYPE_SELL && last_position_price_open < m_symbol.Bid() - (m_take_profit) )                                                  
       if(count_max_volume==1 && last_position_volume==max_volume) 
           m_trade.Buy(last_position_volume*1,m_symbol.Name(),Ask,0,(Ask+m_take_profit),NULL);                                                                                                                   
               }

   if(count_positions==0 && count_pending_orders==0)
     {
      double Ask=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_ASK),_Digits);
      double Bid=NormalizeDouble (SymbolInfoDouble (_Symbol,SYMBOL_BID),_Digits);     
      m_trade.Sell(InpLot,m_symbol.Name(),Bid,0,(Bid-m_take_profit),NULL);                 
      m_trade.Buy(InpLot,m_symbol.Name(),Ask,0,(Ask+m_take_profit),NULL);      
      return;
     }

   if(count_positions>0 && count_pending_orders>0)
      DeleteAllOrders();
//---
   return;
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
  
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &error_description)
  {
//--- minimal allowed volume for trade operations
// double min_volume=m_symbol.LotsMin();
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
// double max_volume=m_symbol.LotsMax();
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- get minimal step of volume changing
// double volume_step=m_symbol.LotsStep();
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                                     volume_step,ratio*volume_step);
      return(false);
     }
   error_description="Correct volume value";
   return(true);
  }
//+------------------------------------------------------------------+ 
//| Checks if the specified filling mode is allowed        .          | 
//+------------------------------------------------------------------+ 
bool IsFillingTypeAllowed(string symbol,int fill_type)
  {
//--- Obtain the value of the property that describes allowed filling modes 
   int filling=(int)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);
//--- Return true, if mode fill_type is allowed 
   return((filling & fill_type)==fill_type);
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions()
  { 
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
  }
//+------------------------------------------------------------------+
//| Delete all pendingA rders                                         |
//+------------------------------------------------------------------+
void DeleteAllOrders()
  {
   for(int i=OrdersTotal()-1;i>=0;i--) // returns the number of current orders
      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties
         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==m_magic)
            m_trade.OrderDelete(m_order.Ticket());
  }
//+------------------------------------------------------------------+


Однако при бэктесте с января по сентябрь 2021 года было открыто только 2 позиции.

Файлы:
 
CodeFx # :

Спасибо за ваш ответ. Пожалуйста, подтвердите предложенное вами исправление:

Исходя из вышесказанного, полный код выглядит следующим образом:


Однако при бэктесте с января по сентябрь 2021 года было открыто только 2 позиции.

Да, теперь ход мыслей правильный

 
Vladimir Karputov #:

Да, теперь ход мыслей правильный.

Спасибо за ваш ответ. Из бэктестинга 2021 года советник открыл последнюю позицию на покупку 6 января 2021 года и не открывал ни одной позиции на продажу после потери 250 пунктов и выше до 23 сентября 2021 года, когда тестирование закончилось.

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

В общем, я хочу, чтобы советник функционировал следующим образом :

1. При старте советник открывает 1 позицию на покупку и 1 позицию на продажу с размером лота 0,01 каждая .

2. Если последняя открытая позиция - Buy и рынок движется вверх, разрешить текущей Buy закрыться с тейк-профитом 250 пунктов и открыть новую Buy с двойным, в 2 раза, размером лота предыдущей Buy.

3. Если последняя открытая позиция - Buy и рынок движется вниз, немедленно текущая покупка теряет 250 пунктов (не получает прибыли) и открывается Sell с тем же, 1-кратным, размером лота предыдущей покупки.

4. Если последняя открытая позиция - Sell и рынок движется вниз, позвольте текущей Sell закрыться с тейк-профитом 250 пунктов и откройте новую Sell с удвоенным, в 2 раза, размером лота предыдущей Sell.

5. Если последняя открытая позиция - Sell и рынок движется вверх, сразу же текущая Sell теряет 250 пунктов (не получает прибыли) и открывается Buy с тем же, 1-кратным, размером лота предыдущей Sell.

6. И наконец, только 1 позиция Buy и 1 Sell могут иметь одинаковые (одинаковые) размеры лота ,

Большое спасибо за помощь.

 
CodeFx # :

Спасибо за ваш ответ. Из бэктестинга 2021 года советник открыл последнюю позицию на покупку 6 января 2021 года и не открывал ни одной позиции на продажу после потери 250 пунктов и выше до 23 сентября 2021 года, когда тестирование закончилось.

Может быть, я неправильно сформулировал свою мысль по отношению к тому, чего я хочу добиться.

В общем, я хочу, чтобы советник работал следующим образом :

1. При старте советник открывает 1 позицию на покупку и 1 позицию на продажу с размером лота 0,01 каждая .

2. Если последняя открытая позиция - покупка и рынок движется вверх, позвольте текущей покупке закрыться с тейк-профитом 250 пунктов и откройте новую покупку с двойным, в 2 раза, размером лота предыдущей покупки.

3. Если последняя открытая позиция - покупка и рынок движется вниз, сразу же текущая покупка теряет 250 пунктов (не получает прибыли) и открывается продажа с тем же, 1-кратным, размером лота предыдущей покупки.

4. Если последняя открытая позиция - Sell и рынок движется вниз, позвольте текущей Sell закрыться с тейк-профитом 250 пунктов и откройте новую Sell с удвоенным, в 2 раза, размером лота предыдущей Sell.

5. Если последняя открытая позиция - Sell и рынок движется вверх, сразу же после того, как текущая Sell потеряет 250 пунктов (не получит прибыли), откройте Buy с таким же, 1-кратным, размером лота предыдущей Sell.

6. И наконец, только 1 позиция Buy и 1 Sell могут иметь одинаковые (одинаковые) размеры лота,

Большое спасибо за помощь.

Я бы работал через OnTradeTransaction - ловил бы сделку "EXIT".

 
CodeFx # :

Спасибо за ваш ответ. Из бэктестинга 2021 года советник открыл последнюю позицию на покупку 6 января 2021 года и не открывал ни одной позиции на продажу после потери 250 пунктов и выше до 23 сентября 2021 года, когда тестирование закончилось.

Может быть, я неправильно сформулировал свою мысль по отношению к тому, чего я хочу добиться.

В общем, я хочу, чтобы советник работал следующим образом :

1. При старте советник открывает 1 позицию на покупку и 1 позицию на продажу с размером лота 0,01 каждая .

2. Если последняя открытая позиция - покупка и рынок движется вверх, позвольте текущей покупке закрыться с тейк-профитом 250 пунктов и откройте новую покупку с двойным, в 2 раза, размером лота предыдущей покупки.

3. Если последняя открытая позиция - покупка и рынок движется вниз, сразу же текущая покупка теряет 250 пунктов (не получает прибыли) и открывается продажа с тем же, 1-кратным, размером лота предыдущей покупки.

4. Если последняя открытая позиция - Sell и рынок движется вниз, позвольте текущей Sell закрыться с тейк-профитом 250 пунктов и откройте новую Sell с удвоенным, в 2 раза, размером лота предыдущей Sell.

5. Если последняя открытая позиция - Sell и рынок движется вверх, сразу же после того, как текущая Sell потеряет 250 пунктов (не получит прибыли), откройте Buy с таким же, 1-кратным, размером лота предыдущей Sell.

6. И наконец, только 1 позиция Buy и 1 Sell могут иметь одинаковые (одинаковые) размеры лота,

Большое спасибо за помощь.

Новый проект "Туманность Андромеды

Как присоединиться к проекту

В MetaEditor в окне "Tools" перейдите на вкладку "Public Projects", в колонке "Name" на проекте "AlligatorAndStochastic" нажмите правой кнопкой мыши и выберите пункт "Join".

Аллигатор и стохастик