Author: Copyright © 2017, Vladimir Karputov
Price Data Components
Series array that contains tick volumes of each bar
Indicators Used
Moving average indicator
0 Views
0 Downloads
0 Favorites
New Martin
ÿþ//+------------------------------------------------------------------+

//|                                                   New Martin.mq5 |

//|                              Copyright © 2017, Vladimir Karputov |

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

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

#property copyright "Copyright © 2017, Vladimir Karputov"

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

#property version   "1.113"

#property description "45O 27OB0 745AL: https://www.mql5.com/ru/forum/167026"

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

//---

input ushort   InpTP                = 50;    // TakeProfit (in pips)

input double   InpLot               = 0.1;   // Lot

input int      Inp_ma_period_slow   = 20;    // ma_period (slow)

input int      Inp_ma_period_fast   = 5;     // ma_period (fast)

input double   InpPersent           = 12;    // Loss persent

//---

ulong          m_magic=524150170;            // magic number

ulong          m_slippage=10;                // slippage

ENUM_ACCOUNT_MARGIN_MODE m_margin_mode;

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

bool           m_first=true;

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

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

//--- 3;>10;L=K5 ?5@5<5==K5

bool           bln_buy=false;                // false -> =C6=> >B:@K20BL Buy

bool           bln_sell=false;               // false -> =C6=> >B:@K20BL Sell

bool           bln_loss_close_pos=false;     // true -> =C6=> 70:@KBL ?>78F8N loss_ticket_close_pos

ulong          loss_ticket_close_pos=0;      // B8:5B ?>78F88, :>B>@CN =C6=> 70:@KBL

bool           bln_profit_close_pos=false;   // true -> =C6=> 70:@KBL ?>78F8N profit_ticket_close_pos

ulong          profit_ticket_close_pos=0;    // B8:5B ?>78F88, :>B>@CN =C6=> 70:@KBL

double         ExtLot=0.0;

double         start_balance=0.0;

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

//| Expert initialization function                                   |

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

int OnInit()

  {

   SetMarginMode();

   if(!IsHedging())

     {

      Print("Hedging only!");

      return(INIT_FAILED);

     }

//--- ?@>25@:0 ?5@8>4>2 "0H5:"

   if(Inp_ma_period_slow<=Inp_ma_period_fast)

     {

      Print("5?@028;L=K5 ?0@0<5B@K ?5@8>4>2 8=48:0B>@>2!");

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   m_symbol.Name(Symbol());                  // sets symbol name

   if(!RefreshRates())

     {

      Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),

            ", Ask=",DoubleToString(m_symbol.Ask(),Digits()));

      return(INIT_FAILED);

     }

   m_symbol.Refresh();

//---

   m_trade.SetExpertMagicNumber(m_magic);    // sets magic number

   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;

//---

   ExtLot=InpLot;

   start_balance=m_account.Balance();

//--- create handle of the indicator iMA

   handle_iMA_fast=iMA(m_symbol.Name(),Period(),Inp_ma_period_fast,0,MODE_SMMA,PRICE_CLOSE);

//--- if the handle is not created 

   if(handle_iMA_fast==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);

     }

//--- create handle of the indicator iMA

   handle_iMA_slow=iMA(m_symbol.Name(),Period(),Inp_ma_period_slow,0,MODE_SMMA,PRICE_CLOSE);

//--- if the handle is not created 

   if(handle_iMA_slow==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);

     }

//---

   m_first=true;

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---



  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

//--- 70:@KB85 C1KB>G=>9 ?>78F88

   if(bln_loss_close_pos)

     {

      if(PositionSelectByTicket(loss_ticket_close_pos))

        {

         if(m_trade.PositionClose(loss_ticket_close_pos))

           {

            Print("Close loss position -> true. Result Retcode: ",m_trade.ResultRetcode(),

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

            //---

            loss_ticket_close_pos=0;

            bln_loss_close_pos=false;

           }

         else

           {

            Print("Close loss position -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

           }

        }

      else

        {

         //--- B0:>9 ?>78F88 C65 =5B (PositionSelectByTicket 25@=C; false)

         loss_ticket_close_pos=0;

         bln_loss_close_pos=false;



        }

     }

//--- 70:@KB85 ?@81K;L=>9 ?>78F88

   if(bln_profit_close_pos)

     {

      if(PositionSelectByTicket(profit_ticket_close_pos))

        {

         if(m_trade.PositionClose(profit_ticket_close_pos))

           {

            Print("Close profit position -> true. Result Retcode: ",m_trade.ResultRetcode(),

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

            //---

            profit_ticket_close_pos=0;

            bln_profit_close_pos=false;

           }

         else

           {

            Print("Close profit position -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

           }

        }

      else

        {

         //--- B0:>9 ?>78F88 C65 =5B (PositionSelectByTicket 25@=C; false)

         profit_ticket_close_pos=0;

         bln_profit_close_pos=false;

        }

     }

//--- 5A;8 <K C25;8G8;8 10;0=A - B> C25;8G8< ;>B

   if(start_balance*1.6<m_account.Balance())

     {

      start_balance=m_account.Balance();

      ExtLot*=1.6;

      ExtLot=LotCheck(ExtLot);

      if(ExtLot==0)

         return;

      Print(__FUNCTION__,", B5?5@L 107>2K9 10;0=A ",DoubleToString(start_balance,2),", ;>B ",DoubleToString(ExtLot,2));

     }

//--- 70I8B0 ?> A@54AB20<: 5A;8 ?@>A04:0 ?@52KH05B 7040==K9 ?@>F5=B 

//--- 7=0G8B 2AQ 70:@K205<

   static double max_equity=0;

   double equity=m_account.Equity();

   double balance=m_account.Balance();



   if((balance-equity)*100.0/balance>InpPersent)

     {

      CloseAllPositions();

      bln_buy=false;

      bln_sell=false;

      //return;

     }



   datetime time_0=iTime(0);

//---

   if(!RefreshRates())

      return;



   if(m_first)

     {

      //--- 70I8B0 >B ?5@570?CA:0 B5@<8=0;0:

      int total=0;

      for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open 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)

               total++;

      //--- 5A;8 =0 B>@3>2>< AGQB5 C65 5ABL ?>78F88 >B:@KBK5 40==K< M:A?5@B>< - 

      //--- 7=0G8B 8=8F80;878@C5< ?5@5<5==K5 B0:8< >1@07><, GB> 2@>45 C65 1K; ?5@2K9 @07

      if(total>0)

        {

         bln_buy=true;

         bln_sell=true;

         m_first=false;

         return;

        }



      if(OpenBuy(ExtLot))

         bln_buy=true;

      if(OpenSell(ExtLot))

         bln_sell=true;

      m_first=false;

     }

//---

   if(!bln_buy)

     {

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

      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),ExtLot,m_symbol.Ask(),ORDER_TYPE_BUY);

      if(chek_volime_lot!=0.0)

         if(chek_volime_lot<ExtLot)

            return; // 45=53 =5 E20B8B =0 >B:@KB85 ?>78F88

      if(OpenBuy(ExtLot))

         bln_buy=true;

     }

   if(!bln_sell)

     {

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

      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),ExtLot,m_symbol.Bid(),ORDER_TYPE_SELL);

      if(chek_volime_lot!=0.0)

         if(chek_volime_lot<ExtLot)

            return; // 45=53 =5 E20B8B =0 >B:@KB85 ?>78F88

      if(OpenSell(ExtLot))

         bln_sell=true;

     }

//--- 8I5< ?5@5A5G5=85 42CE iMA

   double slow_2=iMAGet(handle_iMA_slow,2);

   double slow_1=iMAGet(handle_iMA_slow,1);

   double fast_2=iMAGet(handle_iMA_fast,2);

   double fast_1=iMAGet(handle_iMA_fast,1);



   if((slow_2>fast_2 && slow_1<fast_1) || (slow_2<fast_2 && slow_1>fast_1)) // MB> ?5@5A5G5=85!

     {

      static datetime crossing=0;

      if(crossing==time_0)

         return;

      crossing=time_0;

      Print("1=0@C65=> ?5@5A5G5=85!");

      //--- ?>8A: A0<>9 C1KB>G=>9 8 A0<>9 ?@81K;L=>9 ?>78F88 8 >?@545;5=85 8E =0?@02;5=8O

      //DebugBreak();

      ENUM_POSITION_TYPE loss_type=-1;    double loss_volume=0.0;    ulong loss_ticket=0;

      ENUM_POSITION_TYPE profit_type=-1;  double profit_volume=0.0;  ulong profit_ticket=0;

      FindMaxMinProfitPositions(loss_type,loss_volume,loss_ticket,

                                profit_type,profit_volume,profit_ticket);

      if(loss_ticket!=0)

        {

         loss_volume*=1.6;//  C25;8G8< ;>B

         loss_volume=LotCheck(loss_volume);

         if(loss_volume==0)

            return;



         Print("5@5A5G5=85. #25;8G8< ;>B - B5?5@L >= @025=: ",DoubleToString(loss_volume,2));



         if(loss_type==POSITION_TYPE_BUY)

           {

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

            double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),loss_volume,m_symbol.Ask(),ORDER_TYPE_BUY);

            if(chek_volime_lot!=0.0)

               if(chek_volime_lot<loss_volume)

                  return; // 45=53 =5 E20B8B =0 >B:@KB85 ?>78F88

            Print("5@5A5G5=85. #1KB>G=0O ?>87F8O 8<55B B8? POSITION_TYPE_BUY. >?KB:0 >B:@KBL Buy");

            if(!OpenBuy(loss_volume))

               crossing-=1;

           }

         if(loss_type==POSITION_TYPE_SELL)

           {

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

            double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),loss_volume,m_symbol.Bid(),ORDER_TYPE_SELL);

            if(chek_volime_lot!=0.0)

               if(chek_volime_lot<loss_volume)

                  return; // 45=53 =5 E20B8B =0 >B:@KB85 ?>78F88

            Print("5@5A5G5=85. #1KB>G=0O ?>87F8O 8<55B B8? POSITION_TYPE_SELL. >?KB:0 >B:@KBL Sell");

            if(!OpenSell(loss_volume))

               crossing-=1;

           }

         if(profit_ticket!=0)

           {

            //--- 70:@KB85 1C45B 2 OnTick

            Print("5@5A5G5=85. B40= ?@8:07 =0 70:@KB85 ?@81K;L=>9 ?>78F88 A B8:5B>< ",profit_ticket);

            profit_ticket_close_pos=profit_ticket;

            bln_profit_close_pos=true;

            //Print(__FUNCTION__,": Close profit position");

            //m_trade.PositionClose(profit_ticket);

           }

        }

     }

//---

   return;

  }

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

//| 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_entry        =0;

      double   deal_profit       =0.0;

      double   deal_volume       =0.0;

      long     deal_type         =0;

      string   deal_symbol       ="";

      string   deal_comment      ="";

      long     deal_magic        =0;

      if(HistoryDealSelect(trans.deal))

        {

         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);

         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);

         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);

         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);

         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);

         deal_comment=HistoryDealGetString(trans.deal,DEAL_COMMENT);

         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);

        }

      else

         return;

      if(deal_symbol==Symbol() && deal_magic==m_magic)

         if(deal_entry==DEAL_ENTRY_OUT)

           {

            if(deal_profit>0)

              {

               //--- 5ABL H0=A, GB> MB> 1K;> 70:@KB85 ?> TakeProfit

               if(StringFind(deal_comment,"tp",0)==-1)

                  return;

               Print("1=0@C65=> 70:@KB85 ?> TakeProfit!");

               //--- 5A;8 70:@K;8 BUY

               if(deal_type==DEAL_TYPE_SELL)

                 {

                  //--- >1=C;5=85 4;O BUY

                  Print("TakeProfit. B40= ?@8:07 =0 >B:@KB85 Buy");

                  bln_buy=false;

                 }

               //--- 5A;8 70:@K;8 SELL

               if(deal_type==DEAL_TYPE_BUY)

                 {

                  //--- >1=C;5=85 4;O SELL

                  Print("TakeProfit. B40= ?@8:07 =0 >B:@KB85 Sell");

                  bln_sell=false;

                 }

               ////--- ?>8A: A0<>9 C1KB>G=>9 ?>78F88 8 >?@545;5=85 5Q =0?@02;5=8O

               ////DebugBreak();

               //ENUM_POSITION_TYPE pos_type=-1;

               //double pos_volume=-1;

               //ulong loss_ticket=MostUnprofitablePosition(pos_type,pos_volume);

               //if(loss_ticket!=0)

               //  {

               //   Print(__FUNCTION__,": TakeProfit volume ",DoubleToString(deal_volume,2),

               //         ", close volume ",DoubleToString(pos_volume,2));

               //   m_trade.PositionClose(loss_ticket);

               //  }



               //--- ?>8A: A0<>9 C1KB>G=>9 8 A0<>9 ?@81K;L=>9 ?>78F88 8 >?@545;5=85 8E =0?@02;5=8O

               //DebugBreak();

               ENUM_POSITION_TYPE loss_type=-1;    double loss_volume=0.0;    ulong loss_ticket=0;

               ENUM_POSITION_TYPE profit_type=-1;  double profit_volume=0.0;  ulong profit_ticket=0;

               FindMaxMinProfitPositions(loss_type,loss_volume,loss_ticket,

                                         profit_type,profit_volume,profit_ticket);

               if(loss_ticket!=0)

                 {

                  //--- 70:@KB85 1C45B 2 OnTick

                  Print("TakeProfit. B40= ?@8:07 =0 70:@KB85 C1KB>G=>9 ?>78F88 A B8:5B>< ",loss_ticket);

                  loss_ticket_close_pos=loss_ticket;

                  bln_loss_close_pos=true;

                  //Print(__FUNCTION__,": Close loss position");

                  //m_trade.PositionClose(loss_ticket);

                 }

               if(profit_ticket!=0)

                 {

                  //--- 70:@KB85 1C45B 2 OnTick

                  Print("TakeProfit. B40= ?@8:07 =0 70:@KB85 ?@81K;L=>9 ?>78F88 A B8:5B>< ",profit_ticket);

                  profit_ticket_close_pos=profit_ticket;

                  bln_profit_close_pos=true;

                  //Print(__FUNCTION__,": Close profit position");

                  //m_trade.PositionClose(profit_ticket);

                 }

              }

           }

     }

  }

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

//|                                                                  |

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

void SetMarginMode(void)

  {

   m_margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);

  }

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

//|                                                                  |

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

bool IsHedging(void)

  {

   return(m_margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);

  }

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

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

  }

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

//| Get value of buffers for the iMA                                 |

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

double iMAGet(int handle_iMA,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]);

  }

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

//| >8A: A0<>9 C1KB>G=>9 8 A0<>9 ?@81K;L=>9 ?>78F88                 |

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

void FindMaxMinProfitPositions(ENUM_POSITION_TYPE &loss_type,double &loss_volume,ulong &loss_ticket,

                               ENUM_POSITION_TYPE &profit_type,double &profit_volume,ulong &profit_ticket)

  {

   loss_type=-1;     loss_volume=0.0;     loss_ticket=0;

   profit_type=-1;   profit_volume=0.0;   profit_ticket=0;

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open 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)

           {

            if(m_position.Profit()<loss_volume)

              {

               loss_type=m_position.PositionType();

               loss_volume=m_position.Volume();

               loss_ticket=m_position.Ticket();

              }

            if(m_position.Profit()>profit_volume)

              {

               profit_type=m_position.PositionType();

               profit_volume=m_position.Volume();

               profit_ticket=m_position.Ticket();

              }

           }

//---

   return;

  }

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

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

  }

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

//| Get Time for specified bar index                                 | 

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

datetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)

  {

   if(symbol==NULL)

      symbol=Symbol();

   if(timeframe==0)

      timeframe=Period();

   datetime Time[1];

   datetime time=0;

   int copied=CopyTime(symbol,timeframe,index,1,Time);

   if(copied>0) time=Time[0];

   return(time);

  }

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

//| Close All Positions                                              |

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

void CloseAllPositions(void)

  {

//--- 70:@K205< 2A5 ?>78F88 (?> 2A5< <038:0< 8 ?> 2A5< A8<2>;0<)

   bool res=false;



   while(!res)

     {

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

         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)

           {

            res=m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol

            if(!res)

               break;

           }

     }

  }

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

//| B:@KB85 BUY ?>78F88 ?> A8<2>;C                                  |

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

bool OpenBuy(const double lot)

  {

   bool res=false;



   double price=m_symbol.Ask();

   double tp=m_symbol.NormalizePrice(m_symbol.Bid()+InpTP*m_adjusted_point);

   if(m_trade.Buy(lot,m_symbol.Name(),price,0.0,tp))

      if(m_trade.ResultDeal()>0)

         res=true;



   return(res);

  }

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

//| B:@KB85 SELL ?>78F88 ?> A8<2>;C                                 |

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

bool OpenSell(const double lot)

  {

   bool res=false;



   double price=m_symbol.Bid();

   double tp=m_symbol.NormalizePrice(m_symbol.Ask()-InpTP*m_adjusted_point);

   if(m_trade.Sell(lot,m_symbol.Name(),price,0.0,tp))

      if(m_trade.ResultDeal()>0)

         res=true;



   return(res);

  }

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

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