Author: runik
Price Data Components
Series array that contains tick volumes of each bar Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Orders Execution
Checks for the total of open orders
Indicators Used
Moving average indicator
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
NTK 07
ÿþ//+------------------------------------------------------------------+

//|                              NTK 07(barabashkakvn's edition).mq5 |

//|                                                            runik |

//|                                                  ngb2008@mail.ru |

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

#property copyright "runik"

#property link      "ngb2008@mail.ru"

#property version   "1.000"

//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Trade\DealInfo.mqh>

#include <Trade\OrderInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

#include <Expert\Money\MoneyFixedRisk.mqh>

CPositionInfo  m_position;                      // trade position object

CTrade         m_trade;                         // trading object

CSymbolInfo    m_symbol;                        // symbol info object

CAccountInfo   m_account;                       // account info wrapper

CDealInfo      m_deal;                          // deals object

COrderInfo     m_order;                         // pending orders object

CMoneyFixedMargin *m_money_fixed_margin;

CMoneyFixedRisk *m_money_fixed_risk;

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

//| Enum money management                                            |

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

enum ENUM_MM

  {

   FixedLot    = 0,  // Fixed Lot

   FixedMargin = 1,  // Fixed Margin

   FixedRisk   = 2,  // Fixed Risk

  };

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

//| Enum hours                                                       |

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

enum ENUM_HOURS

  {

   hour_00  =0,   // 00

   hour_01  =1,   // 01

   hour_02  =2,   // 02

   hour_03  =3,   // 03

   hour_04  =4,   // 04

   hour_05  =5,   // 05

   hour_06  =6,   // 06

   hour_07  =7,   // 07

   hour_08  =8,   // 08

   hour_09  =9,   // 09

   hour_10  =10,  // 10

   hour_11  =11,  // 11

   hour_12  =12,  // 12

   hour_13  =13,  // 13

   hour_14  =14,  // 14

   hour_15  =15,  // 15

   hour_16  =16,  // 16

   hour_17  =17,  // 17

   hour_18  =18,  // 18

   hour_19  =19,  // 19

   hour_20  =20,  // 20

   hour_21  =21,  // 21

   hour_22  =22,  // 22

   hour_23  =23,  // 23

  };

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

//| Enum type of trade                                               |

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

enum ENUM_TYPE_TRADE

  {

   EdgesOfRange   = 0,  // trade from edges of range

   CenterOfRange  = 1,  // trade from the centre of range

  };

//---- input parameters

input string      g1="Main settings"; // - Main settings -

input double      InpLots              = 1.0;      // Fixed Lot

input double      InpTotalLots         = 7.0;      // Max total lots

input uchar       InpMaxPositions      = 4;        // Max total Positions 

input ushort      InpNetStep           = 5;        // Net step (in pips)

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

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

input double      InpLotIncreaseRate   = 1.7;      // Lot increase rate

input bool        InpTrailingAtHighLow = true;     // Trailing at High and Low prices

input bool        InpUseTrailingMA     = false;    // Trailing at Moving Average

input ushort      InpTrailingStop      = 8;        // Trailing Stop (in pips), trailing step = trsailing step / 2

sinput string     g2="Money management"; // - Money management -

input ENUM_MM     InpMoneyManagement   = FixedRisk;// Money management 

input double      Risk                 = 5;        // Risk in % for a deal (only for "Fixed Margin" and "Fixed Risk")

input double      InpMinFreeMargin     = 5000.0;   // Min FreeMargin

sinput string     g3="Moving Average"; // - Moving Average -

input int         Inp_ma_period        = 100;      // MA: averaging period 

input int         Inp_ma_shift         = 0;        // MA: horizontal shift 

input ENUM_MA_METHOD Inp_ma_method=MODE_SMMA;// MA: smoothing type 

input ENUM_APPLIED_PRICE Inp_applied_price=PRICE_CLOSE;// MA: type of price 

sinput string     bb="Low-valued variables"; // - Low-valued variables -

input ENUM_HOURS  InpHourStart         = hour_00;  // Hour start   

input ENUM_HOURS  InpHourEnd           = hour_23;  // Hour end 

input uchar       InpBars              = 0;        // Period in bars. Period "1" and "2" - are equivalent!

input ENUM_TYPE_TRADE InpTypeTrade=EdgesOfRange;   // Type of trade

input ulong       m_magic              =468451380; // magic number

//---

ulong             m_slippage=30;                   // slippage

//---

double            ExtNetStep=0.0;

double            ExtStopLoss=0.0;

double            ExtTakeProfit=0.0;

double            ExtTrailingStop=0.0;

uchar             ExtBars=0;



int               handle_iMA;                      // variable for storing the handle of the iMA indicator 



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

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

//| Expert initialization function                                   |

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

int OnInit()

  {

   if(InpNetStep==0)

     {

      string text="Attention! \"Net step\" can not be zero!";

      Alert(text);

      Print(text);

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpStopLoss==0 && (InpMoneyManagement==FixedMargin || InpMoneyManagement==FixedRisk))

     {

      string text="Attention! \"Stop Loss\" can not be equal to zero, if \"Money management\" is equal to \"Fixed Margin\" or \"Fixed Risk\"!";

      Alert(text);

      Print(text);

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpTrailingStop==0)

     {

      string text="Attention! \"Trailing Stop\" can not be zero!";

      Alert(text);

      Print(text);

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   int all_trailing=0;

   all_trailing=(InpTrailingAtHighLow)?all_trailing+1:all_trailing;

   all_trailing=(InpUseTrailingMA)?all_trailing+1:all_trailing;

   if(all_trailing>1)

     {

      string text="Attention! You use more than one type of trailing!";

      Alert(text);

      Print(text);

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpHourStart>=InpHourEnd)

     {

      string text="Attention! \"Hour start\" >= \"Hour end\"";

      Alert(text);

      Print(text);

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   if(InpMoneyManagement==FixedLot)

     {

      if(InpLots<=0.0)

        {

         Print("The \"Fixed Lot\" can't be smaller or equal to zero");

         return(INIT_PARAMETERS_INCORRECT);

        }

     }

//---

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

      return(INIT_FAILED);

   RefreshRates();

   if(InpMoneyManagement==FixedLot)

     {

      string err_text="";

      if(!CheckVolumeValue(InpLots,err_text))

        {

         Print(err_text);

         return(INIT_PARAMETERS_INCORRECT);

        }

     }

//---

   m_trade.SetExpertMagicNumber(m_magic);

//---

   if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))

      m_trade.SetTypeFilling(ORDER_FILLING_FOK);

   else if(IsFillingTypeAllowed(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;



   ExtNetStep        =InpNetStep       *m_adjusted_point;

   ExtStopLoss       =InpStopLoss      *m_adjusted_point;

   ExtTakeProfit     =InpTakeProfit    *m_adjusted_point;

   ExtTrailingStop   =InpTrailingStop  *m_adjusted_point;

   ExtBars=InpBars;

   if(ExtBars==1)

      ExtBars=2;

//---

   if(InpMoneyManagement==FixedMargin)

     {

      delete m_money_fixed_margin;

      m_money_fixed_margin=new CMoneyFixedMargin;

      if(m_money_fixed_margin==NULL)

        {

         Print("Object CMoneyFixedMargin id POINTER_INVALID");

         return(INIT_FAILED);

        }

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

         return(INIT_FAILED);

      m_money_fixed_margin.Percent(Risk);

     }

   if(InpMoneyManagement==FixedRisk)

     {

      delete m_money_fixed_risk;

      m_money_fixed_risk=new CMoneyFixedRisk;

      if(m_money_fixed_risk==NULL)

        {

         Print("Object CMoneyFixedRisk id POINTER_INVALID");

         return(INIT_FAILED);

        }

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

         return(INIT_FAILED);

      m_money_fixed_risk.Percent(Risk);

     }

//--- create handle of the indicator iMA

   handle_iMA=iMA(m_symbol.Name(),Period(),Inp_ma_period,Inp_ma_shift,Inp_ma_method,Inp_applied_price);

//--- if the handle is not created 

   if(handle_iMA==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early 

      return(INIT_FAILED);

     }

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   delete(m_money_fixed_margin);

   delete(m_money_fixed_risk);

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

   MqlDateTime str1;

   TimeToStruct(TimeCurrent(),str1);

//--- we do not work on weekends

   if(str1.day_of_week==0 || str1.day_of_week==6)

      return;

//---

   static datetime last_time=0;

   datetime time_current=TimeCurrent();

   if((long)(time_current-last_time)<10)

     {

      return;

     }

   last_time=time_current;

//---

   static int count_errors=0;

   if(m_account.FreeMargin()<InpMinFreeMargin)

     {

      if(count_errors==0)

        {

         PrintFormat("We have no money. FreeMargin %.2f < \"Min FreeMargin\" %.2f",m_account.FreeMargin(),InpMinFreeMargin);

         count_errors=1;

        }

      return;

     }

   count_errors=0;

//---

   double buylot        =0.0; double buyprice      =0.0; double buystoplot    =0.0; double buystopprice  =0.0;

   double selllot       =0.0; double sellprice     =0.0; double sellstoplot   =0.0; double sellstopprice =0.0;

   double buysl         =0.0; double buytp         =0.0; double sellsl        =0.0; double selltp=0.0;



   ulong buy_ticket  =ULONG_MAX; ulong buy_stop_ticket   =ULONG_MAX;

   ulong sell_ticket =ULONG_MAX; ulong sell_stop_ticket  =ULONG_MAX;

//---

   int count_buy=0;

   int count_sell=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.PositionType()==POSITION_TYPE_BUY)

              {

               count_buy++;

               //--- remember the parameters of the largest BUY position

               if(buylot<m_position.Volume())

                 {

                  buylot      =m_position.Volume();

                  buyprice    =m_position.PriceOpen();

                  buy_ticket  =m_position.Ticket();

                  buysl       =m_position.StopLoss();

                  buytp       =m_position.TakeProfit();

                 }

              }

            if(m_position.PositionType()==POSITION_TYPE_SELL)

              {

               count_sell++;

               //--- remember the parameters of the largest position SELL

               if(selllot<m_position.Volume())

                 {

                  selllot     =m_position.Volume();

                  sellprice   =m_position.PriceOpen();

                  sell_ticket =m_position.Ticket();

                  sellsl      =m_position.StopLoss();

                  selltp      =m_position.TakeProfit();

                 }

              }

           }

   int count_buy_stop=0;

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

           {

            if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

              {

               count_buy_stop++;

               buystoplot        =m_order.VolumeInitial();

               buystopprice      =m_order.PriceOpen();

               buy_stop_ticket   =m_order.Ticket();

              }

            if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

              {

               count_sell_stop++;

               sellstoplot       =m_order.VolumeInitial();

               sellstopprice     =m_order.PriceOpen();

               sell_stop_ticket  =m_order.Ticket();

              }

           }

//--- begin!

   if(!RefreshRates())

      return;

   if(count_buy+count_sell+count_buy_stop+count_sell_stop==0)

     {

      if(str1.hour<InpHourStart || str1.hour>InpHourEnd)

         return;

      double ssmax=iHigh(1);

      double ssmin=iLow(1);

      if(ssmax==0.0 || ssmin==0.0)

         return;

      for(int x=2;x<=ExtBars;x++)

        {

         double high=iHigh(x);

         double low=iLow(x);

         if(high==0.0 || low==0.0)

            return;

         if(ssmax<high)

            ssmax=high;

         if(ssmin>low)

            ssmin=low;

        }

      //---

      double price_buy  =m_symbol.Ask()+ExtNetStep;

      double sl_buy     =(InpStopLoss==0)?0.0:m_symbol.Ask()+ExtNetStep-ExtStopLoss;

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

      double lot_buy    =CalculatLot(price_buy,POSITION_TYPE_BUY,sl_buy,tp_buy);

      if(lot_buy==0.0)

        {

         Print("CalculatLot(POSITION_TYPE_BUY)==0.0");

         return;

        }

      lot_buy=LotCheck(lot_buy);

      if(lot_buy==0.0)

        {

         Print("LotCheck(calculate lot BUY)==0.0");

         return;

        }

      //---

      double price_sell =m_symbol.Bid()-ExtNetStep;

      double sl_sell    =(InpStopLoss==0)?0.0:m_symbol.Bid()-ExtNetStep+ExtStopLoss;

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

      double lot_sell   =CalculatLot(price_sell,POSITION_TYPE_SELL,sl_sell,tp_sell);

      if(lot_sell==0.0)

        {

         Print("CalculatLot(POSITION_TYPE_SELL)==0.0");

         return;

        }

      lot_sell=LotCheck(lot_sell);

      if(lot_sell==0.0)

        {

         Print("LotCheck(calculate lot SELL)==0.0");

         return;

        }

      if(lot_buy+lot_sell>InpTotalLots)

        {

         Print(" Calculate lot BUY ",DoubleToString(lot_buy,2),

               " + calculate lot SELL ",DoubleToString(lot_sell,2)," > \"Max total lots\"",InpTotalLots);

         return;

        }

      //---

      bool one=(InpTypeTrade==EdgesOfRange && (m_symbol.Ask()>ssmax || m_symbol.Bid()<ssmin));

      bool two=(InpTypeTrade==CenterOfRange &&

                ((m_symbol.Ask()+m_symbol.Bid())/2.0<=(ssmax+ssmin)/2.0+1.0*m_adjusted_point && 

                (m_symbol.Ask()+m_symbol.Bid())/2.0>=(ssmax+ssmin)/2.0-1.0*m_adjusted_point));

      if(one || two || ExtBars==0)

        {

         if(m_trade.BuyStop(lot_buy,price_buy,m_symbol.Name(),sl_buy,tp_buy))

            Print("BUY_STOP - > true. ticket of order = ",m_trade.ResultOrder());

         else

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

                  ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                  ", ticket of order: ",m_trade.ResultOrder());

         if(m_trade.SellStop(lot_sell,price_sell,m_symbol.Name(),sl_sell,tp_sell))

            Print("SELL_STOP - > true. ticket of order = ",m_trade.ResultOrder());

         else

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

                  ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                  ", ticket of order: ",m_trade.ResultOrder());

         return;

        }

     }

//--- if there is a SELL position, then the pending order SELL_STOP has triggered

//--- and you need to remove the opportunity to open the BUY position

   if(sell_ticket!=ULONG_MAX) // 5A;8 F5=0 ?>H;0 2=87 

     {

      if(buy_stop_ticket!=ULONG_MAX) // delete BUY_STOP

        {

         m_trade.OrderDelete(buy_stop_ticket);

         return;

        }

      if(buy_ticket!=ULONG_MAX) // close position BUY

        {

         m_trade.PositionClose(buy_ticket);

         return;

        }

      if(sell_stop_ticket==ULONG_MAX) // there are no pending orders and there is at least a SELL position

        {

         double price_sell    =sellprice-ExtNetStep;

         double stops_freeze  =(m_symbol.StopsLevel()>m_symbol.FreezeLevel())?(double)m_symbol.StopsLevel():(double)m_symbol.FreezeLevel();

         stops_freeze         =(stops_freeze==0.0)?m_symbol.Bid()-(m_symbol.Ask()-m_symbol.Bid())*3.0:m_symbol.Bid()-stops_freeze*m_symbol.Point();

         if(price_sell>stops_freeze)

            return;

         price_sell           =m_symbol.NormalizePrice(sellprice-ExtNetStep);

         double sl_sell       =(InpStopLoss==0)?0.0:m_symbol.NormalizePrice(sellprice-ExtNetStep+ExtStopLoss);

         double tp_sell       =(InpTakeProfit==0)?0.0:m_symbol.NormalizePrice(sellprice-ExtNetStep-ExtTakeProfit);

         double lot_sell      =selllot*InpLotIncreaseRate;

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

         double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),lot_sell,price_sell,ORDER_TYPE_SELL);

         Print("CheckVolume: ",

               ", Lot sell * \"Lot increase rate\"= ",DoubleToString(lot_sell,2),

               ", CheckVolume=",DoubleToString(check_volume_lot,2));

         if(check_volume_lot==0.0 || check_volume_lot<lot_sell)

            return;

         lot_sell=LotCheck(lot_sell);

         if(lot_sell==0.0)

            return;

         if(buylot+selllot+buystoplot+sellstoplot>InpTotalLots)

            return;

         if(m_trade.SellStop(lot_sell,price_sell,m_symbol.Name(),sl_sell,tp_sell))

            Print("SELL_STOP - > true. ticket of order = ",m_trade.ResultOrder());

         else

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

                  ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                  ", ticket of order: ",m_trade.ResultOrder());

         return;

        }

     }

//--- if there is a position BUY - it means that the suspended order BUY_STOP

//--- and you need to remove the opportunity to open the SELL position

   if(buy_ticket!=ULONG_MAX) // 5A;8 F5=0 ?>H;0 225@E

     {

      if(sell_stop_ticket!=ULONG_MAX) // remove SELL_STOP

        {

         m_trade.OrderDelete(sell_stop_ticket);

         return;

        }

      if(sell_ticket!=ULONG_MAX) // close the SELL position

        {

         m_trade.PositionClose(sell_ticket);

         return;

        }

      if(buy_stop_ticket==ULONG_MAX) // there are no pending orders and there is at least a BUY position

        {

         double price_buy     =buyprice+ExtNetStep;

         double stops_freeze  =(m_symbol.StopsLevel()>m_symbol.FreezeLevel())?(double)m_symbol.StopsLevel():(double)m_symbol.FreezeLevel();

         stops_freeze         =(stops_freeze==0.0)?m_symbol.Ask()+(m_symbol.Ask()-m_symbol.Bid())*3.0:m_symbol.Ask()+stops_freeze*m_symbol.Point();

         if(price_buy<stops_freeze)

            return;

         price_buy=m_symbol.NormalizePrice(buyprice+ExtNetStep);

         double sl_buy     =(InpStopLoss==0)?0.0:m_symbol.NormalizePrice(buyprice+ExtNetStep-ExtStopLoss);

         double tp_buy     =(InpTakeProfit==0)?0.0:m_symbol.NormalizePrice(buyprice+ExtNetStep+ExtTakeProfit);

         double lot_buy=buylot*InpLotIncreaseRate;

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

         double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),lot_buy,price_buy,ORDER_TYPE_BUY);

         Print("CheckVolume: ",

               ", Lot buy * \"Lot increase rate\"= ",DoubleToString(lot_buy,2),

               ", CheckVolume=",DoubleToString(check_volume_lot,2));

         if(check_volume_lot==0.0 || check_volume_lot<lot_buy)

            return;

         lot_buy=LotCheck(lot_buy);

         if(lot_buy==0.0)

            return;

         if(buylot+selllot+buystoplot+sellstoplot>InpTotalLots)

            return;

         if(m_trade.BuyStop(lot_buy,price_buy,m_symbol.Name(),sl_buy,tp_buy))

            Print("BUY_STOP - > true. ticket of order = ",m_trade.ResultOrder());

         else

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

                  ", description of Retcode: ",m_trade.ResultRetcodeDescription(),

                  ", ticket of order: ",m_trade.ResultOrder());

         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 && m_position.PriceCurrent()>m_position.PriceOpen()) // ?>78F8O 4>;6=0 1KBL :0: <8=8<C< ?@81K;L=0O

              {

               double sl=0.0;

               if(InpTrailingAtHighLow)

                 {

                  double low_1=iLow(1);

                  if(low_1==0.0)

                     continue;

                  double delta=m_position.PriceCurrent()-ExtTrailingStop-ExtTrailingStop/2.0;

                  if((m_position.StopLoss()!=0.0 && delta>low_1 && m_position.StopLoss()<low_1 && !CompareDoubles(m_position.StopLoss(),low_1,m_symbol.Digits())) || 

                     (m_position.StopLoss()==0.0 && delta>low_1))

                    {

                     sl=low_1;

                    }

                 }

               else if(InpUseTrailingMA)

                 {

                  double ma_1=iMAGet(0);

                  if(ma_1==0.0)

                     continue;

                  double delta=m_position.PriceCurrent()-ExtTrailingStop-ExtTrailingStop/2.0;

                  if((m_position.StopLoss()!=0.0 && delta>ma_1 && m_position.StopLoss()<ma_1 && !CompareDoubles(m_position.StopLoss(),ma_1,m_symbol.Digits())) || 

                     (m_position.StopLoss()==0.0 && delta>ma_1))

                    {

                     sl=ma_1;

                    }

                 }

               else if(InpTrailingStop!=0)

                 {

                  double delta=m_position.PriceCurrent()-ExtTrailingStop-ExtTrailingStop/2.0;

                  if((m_position.StopLoss()!=0.0 && delta>m_position.StopLoss()) || 

                     (m_position.StopLoss()==0.0 && delta>m_position.PriceOpen()))

                    {

                     double temp_sl=m_position.PriceCurrent()-ExtTrailingStop; // 30@0=B8O ?@81K;L=>AB8 =0 =>2>< C@>2=5 Stop Loss

                     if(temp_sl>m_position.PriceOpen() && !CompareDoubles(temp_sl,m_position.PriceOpen(),m_symbol.Digits()))

                        sl=temp_sl;

                    }

                 }

               if(sl!=0.0)

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

                     m_symbol.NormalizePrice(sl),

                     m_position.TakeProfit()))

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

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

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

               continue;

              }

            else if(m_position.PositionType()==POSITION_TYPE_SELL && m_position.PriceCurrent()<m_position.PriceOpen()) // ?>78F8O 4>;6=0 1KBL :0: <8=8<C< ?@81K;L=0O

              {

               double sl=0.0;

               if(InpTrailingAtHighLow)

                 {

                  double high_1=iHigh(1);

                  if(high_1==0.0)

                     continue;

                  double delta=m_position.PriceCurrent()+ExtTrailingStop+ExtTrailingStop/2.0;

                  if((m_position.StopLoss()!=0.0 && delta<high_1 && m_position.StopLoss()>high_1 && !CompareDoubles(m_position.StopLoss(),high_1,m_symbol.Digits())) || 

                     (m_position.StopLoss()==0.0 && delta<high_1))

                    {

                     sl=high_1;

                    }

                 }

               else if(InpUseTrailingMA)

                 {

                  double ma_1=iMAGet(0);

                  if(ma_1==0.0)

                     continue;

                  double delta=m_position.PriceCurrent()+ExtTrailingStop+ExtTrailingStop/2.0;

                  if((m_position.StopLoss()!=0.0 && delta<ma_1 && m_position.StopLoss()>ma_1 && !CompareDoubles(m_position.StopLoss(),ma_1,m_symbol.Digits())) || 

                     (m_position.StopLoss()==0.0 && delta<ma_1))

                    {

                     sl=ma_1;

                    }

                 }

               else if(InpTrailingStop!=0)

                  if((m_position.StopLoss()!=0.0 && m_position.PriceCurrent()+ExtTrailingStop+ExtTrailingStop/2.0<m_position.StopLoss()) || 

                     (m_position.StopLoss()==0.0 && m_position.PriceCurrent()+ExtTrailingStop+ExtTrailingStop/2.0<m_position.PriceOpen()))

                    {

                     double temp_sl=m_position.PriceCurrent()+ExtTrailingStop; // 30@0=B8O ?@81K;L=>AB8 =0 =>2>< C@>2=5 Stop Loss

                     if(temp_sl<m_position.PriceOpen() && !CompareDoubles(temp_sl,m_position.PriceOpen(),m_symbol.Digits()))

                        sl=temp_sl;

                    }

               if(sl!=0.0)

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

                     m_symbol.NormalizePrice(sl),

                     m_position.TakeProfit()))

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

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

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

               continue;

              }

           }

//---

  }

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

//| TradeTransaction function                                        |

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

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

   double res=0.0;

   int losses=0.0;

//--- 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_reason!=-1)

      //   DebugBreak();

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

         if(deal_entry==DEAL_ENTRY_OUT)

           {

            int count_buy=0;

            int count_sell=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.PositionType()==POSITION_TYPE_BUY)

                        count_buy++;

                     if(m_position.PositionType()==POSITION_TYPE_SELL)

                        count_sell++;

                    }

            if(count_buy+count_sell==0.0)

               DeleteAllOrders();

           }

     }

  }

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

//| Calculation Net Price                                            |

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

double CalculationNetPrice()

  {

   double total_price_multiply_volume_buy    = 0.0;

   double total_volume_buy                   = 0.0;

   double net_price_buy                      = 0.0;



   double total_price_multiply_volume_sell   = 0.0;

   double total_volume_sell                  = 0.0;

   double net_price_sell                     = 0.0;



   int total=PositionsTotal();

   for(int i=total-1;i>=0;i--)

     {

      if(!m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         break;

      if(m_position.Symbol()==Symbol())

        {

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

            total_price_multiply_volume_buy+=m_position.PriceOpen()*m_position.Volume();

            total_volume_buy+=m_position.Volume();

           }

         else

           {

            total_price_multiply_volume_sell+=m_position.PriceOpen()*m_position.Volume();

            total_volume_sell+=m_position.Volume();

           }

        }

     }

//---

   if(total_volume_buy-total_volume_sell!=0)

     {

      double breakeven_price=(total_price_multiply_volume_buy-total_price_multiply_volume_sell)/

                             (total_volume_buy+total_volume_sell*-1);

      return(breakeven_price);

     }

//---

   return(0.0);

  }

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

//| Get the High for specified bar index                             | 

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

double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   double High[1];

   double high=0;

   int copied=CopyHigh(symbol,timeframe,index,1,High);

   if(copied>0)

      high=High[0];

   return(high);

  }

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

//| Get Low for specified bar index                                  | 

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

double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)

  {

   if(symbol==NULL)

      symbol=m_symbol.Name();

   if(timeframe==0)

      timeframe=Period();

   double Low[1];

   double low=0;

   int copied=CopyLow(symbol,timeframe,index,1,Low);

   if(copied>0)

      low=Low[0];

   return(low);

  }

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

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

  }

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

//| Calculat lot                                                     |

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

double CalculatLot(double &price,ENUM_POSITION_TYPE pos_type,double &sl,double &tp)

  {

   price=m_symbol.NormalizePrice(price);

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);

   if(pos_type==POSITION_TYPE_BUY)

     {

      double check_open_long_lot=0.0;

      if(InpMoneyManagement==FixedLot)

        {

         check_open_long_lot=InpLots;

        }

      if(InpMoneyManagement==FixedMargin)

        {

         check_open_long_lot=m_money_fixed_margin.CheckOpenLong(price,sl);

         Print("CheckOpenLong: 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)

            return(0.0);

        }

      if(InpMoneyManagement==FixedRisk)

        {

         check_open_long_lot=m_money_fixed_risk.CheckOpenLong(price,sl);

         Print("CheckOpenLong: 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)

            return(0.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,price,ORDER_TYPE_BUY);

      Print("CheckVolume: ",

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

            ", CheckVolume=",DoubleToString(check_volume_lot,2));

      if(check_volume_lot!=0.0)

         if(check_volume_lot>=check_open_long_lot)

            return(check_open_long_lot);

      return(0.0);

     }

//---

   if(pos_type==POSITION_TYPE_SELL)

     {

      double check_open_short_lot=0.0;

      if(InpMoneyManagement==FixedLot)

        {

         check_open_short_lot=InpLots;

        }

      if(InpMoneyManagement==FixedMargin)

        {

         check_open_short_lot=m_money_fixed_margin.CheckOpenShort(price,sl);

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

               ", CheckOpenShort: ",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)

            return(0.0);

        }

      if(InpMoneyManagement==FixedRisk)

        {

         check_open_short_lot=m_money_fixed_risk.CheckOpenShort(price,sl);

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

               ", CheckOpenShort: ",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)

            return(0.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,price,ORDER_TYPE_SELL);

      Print("CheckVolume: ",

            ", CheckOpenShort= ",DoubleToString(check_open_short_lot,2),

            ", CheckVolume=",DoubleToString(check_volume_lot,2));

      if(check_volume_lot!=0.0)

         if(check_volume_lot>=check_open_short_lot)

            return(check_open_short_lot);

      return(0.0);

     }

//---

   return(0.0);

  }

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

//| Lot Check                                                        |

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

double LotCheck(double lots)

  {

//--- calculate maximum volume

   double volume=NormalizeDouble(lots,2);

   double stepvol=m_symbol.LotsStep();

   if(stepvol>0.0)

      volume=stepvol*MathFloor(volume/stepvol);

//---

   double minvol=m_symbol.LotsMin();

   if(volume<minvol)

      volume=0.0;

//---

   double maxvol=m_symbol.LotsMax();

   if(volume>maxvol)

      volume=maxvol;

   return(volume);

  }

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

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

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

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

   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(int fill_type)

  {

//--- Obtain the value of the property that describes allowed filling modes 

   int filling=m_symbol.TradeFillFlags();

//--- Return true, if mode fill_type is allowed 

   return((filling & fill_type)==fill_type);

  }

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

//| Compare doubles                                                  |

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

bool CompareDoubles(double number1,double number2,int digits)

  {

   if(NormalizeDouble(number1-number2,digits)==0)

      return(true);

   else

      return(false);

  }

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

//| Delete all pendinf orders                                        |

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

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

  }

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

//| Get value of buffers for the iMA                                 |

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

double iMAGet(const int index)

  {

   double MA[1];

//--- reset error code 

   ResetLastError();

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

   if(CopyBuffer(handle_iMA,0,index,1,MA)<0)

     {

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

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

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

      return(0.0);

     }

   return(MA[0]);

  }

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

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