Expert Ichimoku

Author: Copyright © 2018, Vladimir Karputov
Price Data Components
Series array that contains open prices of each barSeries array that contains close prices for each barSeries array that contains tick volumes of each bar
Indicators Used
Ichimoku Kinko Hyo
0 Views
0 Downloads
0 Favorites
Expert Ichimoku
ÿþ//+------------------------------------------------------------------+

//|                                              Expert Ichimoku.mq5 |

//|                              Copyright © 2018, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2018, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.000"

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

CMoneyFixedMargin *m_money;

//--- input parameters

input int      Inp_tenkan_sen    = 9;        // Ichimoku: period of Tenkan-sen 

input int      Inp_kijun_sen     = 26;       // Ichimoku: period of Kijun-sen 

input int      Inp_senkou_span_b = 52;       // Ichimoku: period of Senkou Span B 

input ushort   InpStopLoss       = 50;       // Stop Loss (in pips)

input ushort   InpTakeProfit     = 100;      // Take Profit (in pips)

input ushort   InpTrailingStop   = 15;       // Trailing Stop (in pips)

input ushort   InpTrailingStep   = 5;        // Trailing Step (in pips)

input int      InpMaxPositions   = 5;        // Maximum positions

input double   InpLots           = 0;        // Lots (or "Lots">0 and "Risk"==0 or "Lots"==0 and "Risk">0)

input double   Risk              = 5;        // Risk (or "Lots">0 and "Risk"==0 or "Lots"==0 and "Risk">0)

input ulong    m_magic           = 527085350;// magic number

//---

ulong          m_slippage=10;                // slippage



double         ExtStopLoss=0.0;

double         ExtTakeProfit=0.0;

double         ExtTrailingStop=0.0;

double         ExtTrailingStep=0.0;

double         ExtSpreadLimit=0.0;



int            handle_iIchimoku;             // variable for storing the handle of the iIchimoku indicator 



double         m_adjusted_point;             // point value adjusted for 3 or 5 points



bool           m_last_deal_LOSS=false;

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//---

   if(!m_symbol.Name(Symbol())) // sets symbol name

      return(INIT_FAILED);

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(m_magic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   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;



   ExtStopLoss    = InpStopLoss     * m_adjusted_point;

   ExtTakeProfit  = InpTakeProfit   * m_adjusted_point;

   ExtTrailingStop= InpTrailingStop * m_adjusted_point;

   ExtTrailingStep= InpTrailingStep * m_adjusted_point;

//--- create handle of the indicator iIchimoku

   handle_iIchimoku=iIchimoku(m_symbol.Name(),Period(),Inp_tenkan_sen,Inp_kijun_sen,Inp_senkou_span_b);

//--- if the handle is not created 

   if(handle_iIchimoku==INVALID_HANDLE)

     {

      //--- tell about the failure and output the error code 

      PrintFormat("Failed to create handle of the iIchimoku indicator for the symbol %s/%s, error code %d",

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early 

      return(INIT_FAILED);

     }

//---

   if(!LotsOrRisk(InpLots,Risk,digits_adjust))

      return(INIT_PARAMETERS_INCORRECT);

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---



  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   Trailing();

//--- we work only at the time of the birth of new bar

   static datetime PrevBars=0;

   datetime time_0=iTime(m_symbol.Name(),Period(),0);

   if(time_0==PrevBars)

      return;

   PrevBars=time_0;

   if(!RefreshRates())

     {

      PrevBars=0;

      return;

     }



   if(CalculateAllPositions()>=InpMaxPositions)

      return;

/*

   Yes, I know this way of referring to the indicator is very inefficient.

   It is much more efficient to get several values into an array at once.

   But today I decided to choose an inefficient way :)

*/

//+------------------------------------------------------------------+

//| Get value of buffers for the iIchimoku                           |

//|  the buffer numbers are the following:                           |

//|   0 - TENKANSEN_LINE, 1 - KIJUNSEN_LINE, 2 - SENKOUSPANA_LINE,   |

//|   3 - SENKOUSPANB_LINE, 4 - CHIKOUSPAN_LINE                      |

//+------------------------------------------------------------------+

   double Ten=iIchimokuGet(TENKANSEN_LINE,1);

   double Kij=iIchimokuGet(KIJUNSEN_LINE,1);

   double SpanA=iIchimokuGet(SENKOUSPANA_LINE,1);

   double SpanB=iIchimokuGet(SENKOUSPANB_LINE,1);

   double Chinkou=iIchimokuGet(CHIKOUSPAN_LINE,1);

   double Ten1=iIchimokuGet(TENKANSEN_LINE,2);

   double Kij1=iIchimokuGet(KIJUNSEN_LINE,2);

   double SpanA1=iIchimokuGet(SENKOUSPANA_LINE,2);

   double SpanB1=iIchimokuGet(SENKOUSPANB_LINE,2);

   double Chinkou1=iIchimokuGet(CHIKOUSPAN_LINE,2);

   double Ten2=iIchimokuGet(TENKANSEN_LINE,3);

   double Kij2=iIchimokuGet(KIJUNSEN_LINE,3);

   double SpanA2=iIchimokuGet(SENKOUSPANA_LINE,3);

   double SpanB2=iIchimokuGet(SENKOUSPANB_LINE,3);

   double Chinkou2=iIchimokuGet(CHIKOUSPAN_LINE,3);

//--- check BUY

   if((Ten1<=Kij1 && Ten>Kij && m_symbol.Ask()>SpanA1 && m_symbol.Ask()>SpanB1 && 

      iOpen(m_symbol.Name(),Period(),1)<iClose(m_symbol.Name(),Period(),1)) || 

      (Chinkou1<=iClose(m_symbol.Name(),Period(),11) && Chinkou>iClose(m_symbol.Name(),Period(),10) && 

      m_symbol.Ask()>SpanA1 && m_symbol.Ask()>SpanB1 && 

      iOpen(m_symbol.Name(),Period(),1)<iClose(m_symbol.Name(),Period(),1)))

     {

      double sl=(InpStopLoss==0)?0.0:m_symbol.Ask()-ExtStopLoss;

      if(sl>=m_symbol.Bid()) // incident: the position isn't opened yet, and has to be already closed

        {

         PrevBars=0;

         return;

        }

      double tp=(InpTakeProfit==0)?0.0:m_symbol.Ask()+ExtTakeProfit;

      OpenBuy(sl,tp);

     }

//--- check SELL

   if((Ten1>=Kij1 && Ten<Kij && m_symbol.Bid()<SpanA1 && m_symbol.Bid()<SpanB1 && 

      iOpen(m_symbol.Name(),Period(),1)>iClose(m_symbol.Name(),Period(),1)) || 

      (Chinkou1>=iOpen(m_symbol.Name(),Period(),11) && Chinkou<iOpen(m_symbol.Name(),Period(),10) && 

      m_symbol.Bid()<SpanA1 && m_symbol.Bid()<SpanB1 && 

      iOpen(m_symbol.Name(),Period(),1)>iClose(m_symbol.Name(),Period(),1)))

     {

      double sl=(InpStopLoss==0)?0.0:m_symbol.Bid()+ExtStopLoss;

      if(sl<=m_symbol.Ask()) // incident: the position isn't opened yet, and has to be already closed

        {

         PrevBars=0;

         return;

        }

      double tp=(InpTakeProfit==0)?0.0:m_symbol.Bid()-ExtTakeProfit;

      OpenSell(sl,tp);

     }

  }

//+------------------------------------------------------------------+

//| TradeTransaction function                                        |

//+------------------------------------------------------------------+

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//---

//--- get transaction type as enumeration value 

   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;

//--- if transaction is result of addition of the transaction in history

   if(type==TRADE_TRANSACTION_DEAL_ADD)

     {

      long     deal_ticket       =0;

      long     deal_order        =0;

      long     deal_time         =0;

      long     deal_time_msc     =0;

      long     deal_type         =-1;

      long     deal_entry        =-1;

      long     deal_magic        =0;

      long     deal_reason       =-1;

      long     deal_position_id  =0;

      double   deal_volume       =0.0;

      double   deal_price        =0.0;

      double   deal_commission   =0.0;

      double   deal_swap         =0.0;

      double   deal_profit       =0.0;

      string   deal_symbol       ="";

      string   deal_comment      ="";

      string   deal_external_id  ="";

      if(HistoryDealSelect(trans.deal))

        {

         deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);

         deal_order        =HistoryDealGetInteger(trans.deal,DEAL_ORDER);

         deal_time         =HistoryDealGetInteger(trans.deal,DEAL_TIME);

         deal_time_msc     =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);

         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);

         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);

         deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);

         deal_reason       =HistoryDealGetInteger(trans.deal,DEAL_REASON);

         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);



         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);

         deal_price        =HistoryDealGetDouble(trans.deal,DEAL_PRICE);

         deal_commission   =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);

         deal_swap         =HistoryDealGetDouble(trans.deal,DEAL_SWAP);

         deal_profit       =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);



         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);

         deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);

         deal_external_id  =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);

        }

      else

         return;

      if(deal_symbol==m_symbol.Name() && deal_magic==m_magic)

         if(deal_entry==DEAL_ENTRY_OUT)

            if(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)

              {

               if(deal_commission+deal_swap+deal_profit<0.0)

                  m_last_deal_LOSS=true;

               else

                  m_last_deal_LOSS=false;

              }

     }

  }

//+------------------------------------------------------------------+

//| Refreshes the symbol quotes data                                 |

//+------------------------------------------------------------------+

bool RefreshRates(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print("RefreshRates error");

      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 position volume                     |

//+------------------------------------------------------------------+

bool CheckVolumeValue(double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< <5=LH5 <8=8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MIN=%.2f",min_volume);

      else

         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();

   if(volume>max_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< 1>;LH5 <0:A8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MAX=%.2f",max_volume);

      else

         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();

   int ratio=(int)MathRound(volume/volume_step);

   if(MathAbs(ratio*volume_step-volume)>0.0000001)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< =5 :@0B5= <8=8<0;L=><C H03C SYMBOL_VOLUME_STEP=%.2f, 1;8609H89 ?@028;L=K9 >1J5< %.2f",

                                        volume_step,ratio*volume_step);

      else

         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);

  }

//+------------------------------------------------------------------+

//| Lots or risk in percent for a deal from a free margin            |

//+------------------------------------------------------------------+

bool LotsOrRisk(const double lots,const double risk,const int digits_adjust)

  {

   if(lots<0.0 && risk<0.0)

     {

      Print(__FUNCTION__,", ERROR: Parameter (\"lots\" or \"risk\") can't be less than zero");

      return(false);

     }

   if(lots==0.0 && risk==0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" == 0.0 and \"risk\" == 0.0");

      return(false);

     }

   if(lots>0.0 && risk>0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" > 0.0 and \"risk\" > 0.0");

      return(false);

     }

   if(lots>0.0)

     {

      string err_text="";

      if(!CheckVolumeValue(lots,err_text))

        {

         Print(__FUNCTION__,", ERROR: ",err_text);

         return(false);

        }

     }

   else if(risk>0.0)

     {

      if(m_money!=NULL)

         delete m_money;

      m_money=new CMoneyFixedMargin;

      if(m_money!=NULL)

        {

         if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))

            return(INIT_FAILED);

         m_money.Percent(risk);

        }

      else

        {

         Print(__FUNCTION__,", ERROR: Object CMoneyFixedMargin is NULL");

         return(INIT_FAILED);

        }

     }

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Open Buy position                                                |

//+------------------------------------------------------------------+

void OpenBuy(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_long_lot=0.0;

   if(Risk>0.0)

     {

      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_long_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_long_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenLong returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_long_lot=InpLots;

   if(m_last_deal_LOSS)

      check_open_long_lot*=2.0;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_long_lot)

        {

         if(m_trade.Buy(check_open_long_lot,NULL,m_symbol.Ask(),sl,tp))

           {

            if(m_trade.ResultDeal()==0)

              {

               Print("#1 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenLong ("+DoubleToString(check_open_long_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(check_volume_lot,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

//+------------------------------------------------------------------+

//| Open Sell position                                               |

//+------------------------------------------------------------------+

void OpenSell(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_short_lot=0.0;

   if(Risk>0.0)

     {

      check_open_short_lot=m_money.CheckOpenShort(m_symbol.Bid(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_short_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_short_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenShort returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_short_lot=InpLots;

   if(m_last_deal_LOSS)

      check_open_short_lot*=2.0;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_short_lot,m_symbol.Bid(),ORDER_TYPE_SELL);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_short_lot)

        {

         if(m_trade.Sell(check_open_short_lot,NULL,m_symbol.Bid(),sl,tp))

           {

            if(m_trade.ResultDeal()==0)

              {

               Print("#1 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Sell -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResultTrade(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenShort ("+DoubleToString(check_open_short_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(InpLots,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

//+------------------------------------------------------------------+

//| Print CTrade result                                              |

//+------------------------------------------------------------------+

void PrintResultTrade(CTrade &trade,CSymbolInfo &symbol)

  {

   Print("File: ",__FILE__,", symbol: ",m_symbol.Name());

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

  }

//+------------------------------------------------------------------+

//| Get value of buffers for the iIchimoku                           |

//|  the buffer numbers are the following:                           |

//|   0 - TENKANSEN_LINE, 1 - KIJUNSEN_LINE, 2 - SENKOUSPANA_LINE,   |

//|   3 - SENKOUSPANB_LINE, 4 - CHIKOUSPAN_LINE                      |

//+------------------------------------------------------------------+

double iIchimokuGet(const int buffer,const int index)

  {

   double Ichimoku[1];

//--- reset error code 

   ResetLastError();

//--- fill a part of the iIchimoku array with values from the indicator buffer that has 0 index 

   if(CopyBuffer(handle_iIchimoku,buffer,index,1,Ichimoku)<0)

     {

      //--- if the copying fails, tell the error code 

      PrintFormat("Failed to copy data from the iIchimoku indicator, error code %d",GetLastError());

      //--- quit with zero result - it means that the indicator is considered as not calculated 

      return(0.0);

     }

   return(Ichimoku[0]);

  }

//+------------------------------------------------------------------+

//| Calculate all positions                                          |

//+------------------------------------------------------------------+

int CalculateAllPositions()

  {

   int total=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)

            total++;

//---

   return(total);

  }

//+------------------------------------------------------------------+

//| Trailing                                                         |

//+------------------------------------------------------------------+

void Trailing()

  {

   if(InpTrailingStop==0)

      return;

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions

      if(m_position.SelectByIndex(i))

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtTrailingStop+ExtTrailingStep)

                  if(m_position.StopLoss()<m_position.PriceCurrent()-(ExtTrailingStop+ExtTrailingStep))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()-ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                     RefreshRates();

                     m_position.SelectByIndex(i);

                     PrintResultModify(m_trade,m_symbol,m_position);

                     continue;

                    }

              }

            else

              {

               if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtTrailingStop+ExtTrailingStep)

                  if((m_position.StopLoss()>(m_position.PriceCurrent()+(ExtTrailingStop+ExtTrailingStep))) || 

                     (m_position.StopLoss()==0))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()+ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                     RefreshRates();

                     m_position.SelectByIndex(i);

                     PrintResultModify(m_trade,m_symbol,m_position);

                    }

              }



           }

  }

//+------------------------------------------------------------------+

//| Print CTrade result                                              |

//+------------------------------------------------------------------+

void PrintResultModify(CTrade &trade,CSymbolInfo &symbol,CPositionInfo &position)

  {

   Print("File: ",__FILE__,", symbol: ",m_symbol.Name());

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

   Print("Price of position opening: "+DoubleToString(position.PriceOpen(),symbol.Digits()));

   Print("Price of position's Stop Loss: "+DoubleToString(position.StopLoss(),symbol.Digits()));

   Print("Price of position's Take Profit: "+DoubleToString(position.TakeProfit(),symbol.Digits()));

   Print("Current price by position: "+DoubleToString(position.PriceCurrent(),symbol.Digits()));

  }

//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---