Exp_TrailingStop

Author: Copyright © 2017, Nikolay Kositsin
Orders Execution
It automatically opens orders when conditions are reached
Miscellaneous
It plays sound alerts
0 Views
0 Downloads
0 Favorites
Exp_TrailingStop
ÿþ//+------------------------------------------------------------------+

//|                                             Exp_TrailingStop.mq5 |

//|                               Copyright © 2017, Nikolay Kositsin | 

//|                              Khabarovsk,   farria@mail.redcom.ru | 

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

#property copyright "Copyright © 2017, Nikolay Kositsin"

#property link "farria@mail.redcom.ru"

#property version   "1.00"

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

//| E>4=K5 ?0@0<5B@K M:A?5@B0                   |

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

input uint   StopLoss_=1000;      //AB>?;>AA 2 ?C=:B0E

input int    TralStart=1000;      //AB0@B B@59;8=30 2 ?C=:B0E

input uint   TralStep=200;        //H03 B@59;8=AB>?0 2 ?C=:B0E

input uint   Deviation_=10;       //<0:A. >B:;>=5=85 F5=K 2 ?C=:B0E

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



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

//| Expert initialization function                                   |

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

int OnInit()

  {

//----

   

//---- 7025@H5=85 8=8F80;870F88

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//----



//----

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

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

//| 28305< B@0;K 2A5E >B:@KBKE ?>78F89 ?> A8<2>;C |

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

   BuyTrailingStopBySymbol(Symbol(),StopLoss_,TralStart,TralStep,Deviation_);

   SellTrailingStopBySymbol(Symbol(),StopLoss_,TralStart,TralStep,Deviation_);

//----

  }

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

//| 28305< B@0;K >B:@KBKE 2A5E 4;8==KE ?>78F89 ?> A8<2>;C           |

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

bool BuyTrailingStopBySymbol(string Symb, uint Stop, int StartLevel, uint Step, uint deviation)

  {

//----

   uint deals=PositionsTotal();

//--- B5?5@L >1@01>B05< :064CN A45;:C 

   for(int pos=int(deals)-1; pos>=0; pos--)

     {

      //---- =094Q< B8:5B ?>A;54=59 ?>78F88

      ulong deal_ticket=PositionGetTicket(pos);

      if(!PositionSelectByTicket(deal_ticket)) continue;

      if(PositionGetString(POSITION_SYMBOL)!=Symb) continue;

      if(PositionGetInteger(POSITION_TYPE)!=POSITION_TYPE_BUY) continue;

      //----

      double openprice=PositionGetDouble(POSITION_PRICE_OPEN);      

      double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);

      double Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

      if(!point || !Ask) return(false);

      double diff=Ask-openprice;

      if(diff<=StartLevel*point) continue;  //?@>25@:0 B@59;8=30 =0 AB0@B         

      double loss=Ask-Stop*point;

      double loss_prev=PositionGetDouble(POSITION_SL); 

      bool Signal=true;    

      if((loss_prev && loss-loss_prev>Step*point) || !loss_prev) dBuyPositionModify_(Signal,Symb,deviation,loss,NULL);//5A;8 F5=0 2K@>A;0 1>;LH5, G5< Step, 428305< B@0;

     }

//----

   return(true);

  }

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

//| 28305< B@0;K 2A5E >B:@KBKE :>@>B:8E ?>78F89  ?> A8<2>;C         |

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

bool SellTrailingStopBySymbol(string Symb, uint Stop, int StartLevel, uint Step, uint deviation)

  {

//----

   uint deals=PositionsTotal();

//--- B5?5@L >1@01>B05< :064CN A45;:C 

   for(int pos=int(deals)-1; pos>=0; pos--)

     {

      //---- =094Q< B8:5B ?>A;54=59 ?>78F88

      ulong deal_ticket=PositionGetTicket(pos);

      if(!PositionSelectByTicket(deal_ticket)) continue;

      if(PositionGetString(POSITION_SYMBOL)!=Symb) continue;

      if(PositionGetInteger(POSITION_TYPE)!=POSITION_TYPE_SELL) continue;

      //----

      double openprice=PositionGetDouble(POSITION_PRICE_OPEN);      

      double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);

      double Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);

      if(!point || !Bid) return(false);

      double diff=openprice-Bid;

      if(diff<=StartLevel*point) continue;  //?@>25@:0 B@59;8=30 =0 AB0@B         

      double loss=Bid+Stop*point;

      double loss_prev=PositionGetDouble(POSITION_SL); 

      bool Signal=true;     

      if((loss_prev && loss_prev-loss>Step*point) || !loss_prev) dSellPositionModify_(Signal,Symb,deviation,loss,NULL); //5A;8 F5=0 C?0;0 1>;LH5, G5< Step, 428305< B@0;

     }

//----

   return(true);

  }

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

//| >48D8F8@C5< 4;8==CN ?>78F8N                                     |

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

bool dBuyPositionModify_

(

 bool &Modify_Signal,        // D;03 @07@5H5=8O <>48D8:0F88

 const string symbol,        // B>@3>20O ?0@0 A45;:8

 uint deviation,             // A;8??06

 double StopLoss,            // AB>?;>AA 2 01A>;NB=>< 7=0G5=88 F5=>2>3> 3@0D8:0

 double Takeprofit           // B59:?@>D8B 2 01A>;NB=>< 7=0G5=88 F5=>2>3> 3@0D8:0

 )

//dBuyPositionModify(Modify_Signal,symbol,deviation,StopLoss,Takeprofit);

  {

//----

   if(!Modify_Signal) return(true);



   ENUM_POSITION_TYPE PosType=POSITION_TYPE_BUY;



//---- 1JO2;5=85 AB@C:BC@ B>@3>2>3> 70?@>A0 8 @57C;LB0B0 B>@3>2>3> 70?@>A0

   MqlTradeRequest request;

   MqlTradeResult result;



//---- 1JO2;5=85 AB@C:BC@K @57C;LB0B0 ?@>25@:8 B>@3>2>3> 70?@>A0 

   MqlTradeCheckResult check;



//---- >1=C;5=85 AB@C:BC@

   ZeroMemory(request);

   ZeroMemory(result);

   ZeroMemory(check);

//----

   int digit=int(SymbolInfoInteger(symbol,SYMBOL_DIGITS));

   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);

   double Ask=SymbolInfoDouble(symbol,SYMBOL_ASK);

   if(!digit || !point || !Ask) return(true);



//---- =8F80;870F8O AB@C:BC@K B>@3>2>3> 70?@>A0 MqlTradeRequest 4;O >B:@K20=8O BUY ?>78F88

   request.type   = ORDER_TYPE_BUY;

   request.price  = Ask;

   request.action = TRADE_ACTION_SLTP;

   request.symbol = symbol;

   request.position=PositionGetInteger(POSITION_TICKET); 



//---- ?@545;5=85 @0AAB>O=8O 4> AB>?;>AA0 2 548=8F0E F5=>2>3> 3@0D8:0

   if(StopLoss)

     {

      int nStopLoss=int((Ask-StopLoss)/point);

      if(nStopLoss<0) return(false);

      if(!StopCorrect(symbol,nStopLoss))return(false);

      double dStopLoss=nStopLoss*point;

      request.sl=NormalizeDouble(request.price-dStopLoss,digit);

      if(request.sl<PositionGetDouble(POSITION_SL)) request.sl=PositionGetDouble(POSITION_SL);

     }

   else request.sl=PositionGetDouble(POSITION_SL);



//---- ?@545;5=85 @0AAB>O=8O 4> B59:?@>D8B0 548=8F0E F5=>2>3> 3@0D8:0

   if(Takeprofit)

     {

      int nTakeprofit=int((Takeprofit-Ask)/point);

      if(nTakeprofit<0) return(false);

      if(!StopCorrect(symbol,nTakeprofit))return(false);

      double dTakeprofit=nTakeprofit*point;

      request.tp=NormalizeDouble(request.price+dTakeprofit,digit);

      if(request.tp<PositionGetDouble(POSITION_TP)) request.tp=PositionGetDouble(POSITION_TP);

     }

   else request.tp=PositionGetDouble(POSITION_TP);



//----   

   if(request.tp==PositionGetDouble(POSITION_TP) && request.sl==PositionGetDouble(POSITION_SL)) return(true);

   request.deviation=deviation;

   request.type_filling=ORDER_FILLING_FOK;



//---- @>25@:0 B>@3>2>3> 70?@>A0 =0 :>@@5:B=>ABL

   if(!OrderCheck(request,check))

     {

      Print(__FUNCTION__,"(): 525@=K5 40==K5 4;O AB@C:BC@K B>@3>2>3> 70?@>A0!");

      Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));

      return(false);

     }



   string comment="";

   StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): >48D8F8@C5< Buy ?>78F8N ?> ",symbol," ============ >>>");

   Print(comment);



//---- >48D8F8@C5< BUY ?>78F8N 8 45;05< ?@>25@:C @57C;LB0B0 B>@3>2>3> 70?@>A0

   if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)

     {

      Print(__FUNCTION__,"(): 52>7<>6=> <>48D8F8@>20BL ?>78F8N!");

      Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));

      return(false);

     }

   else

   if(result.retcode==TRADE_RETCODE_DONE)

     {

      Modify_Signal=false;

      comment="";

      StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Buy ?>78F8O ?> ",symbol," <>48D8F8@>20=0 ============ >>>");

      Print(comment);

      PlaySound("ok.wav");

     }

   else

     {

      Print(__FUNCTION__,"(): 52>7<>6=> <>48D8F8@>20BL ?>78F8N!");

      Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));

     }

//----

   return(true);

  }

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

//| >48D8F8@C5< :>@>B:CN ?>78F8N                                    |

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

bool dSellPositionModify_

(

 bool &Modify_Signal,        // D;03 @07@5H5=8O <>48D8:0F88

 const string symbol,        // B>@3>20O ?0@0 A45;:8

 uint deviation,             // A;8??06

 double StopLoss,            // AB>?;>AA 2 01A>;NB=>< 7=0G5=88 F5=>2>3> 3@0D8:0

 double Takeprofit           // B59:?@>D8B 2 01A>;NB=>< 7=0G5=88 F5=>2>3> 3@0D8:0

 )

//dSellPositionModify(Modify_Signal,symbol,deviation,StopLoss,Takeprofit);

  {

//----

   if(!Modify_Signal) return(true);



   ENUM_POSITION_TYPE PosType=POSITION_TYPE_SELL;





//---- 1JO2;5=85 AB@C:BC@ B>@3>2>3> 70?@>A0 8 @57C;LB0B0 B>@3>2>3> 70?@>A0

   MqlTradeRequest request;

   MqlTradeResult result;



//---- 1JO2;5=85 AB@C:BC@K @57C;LB0B0 ?@>25@:8 B>@3>2>3> 70?@>A0 

   MqlTradeCheckResult check;



//---- >1=C;5=85 AB@C:BC@

   ZeroMemory(request);

   ZeroMemory(result);

   ZeroMemory(check);

//----

   int digit=int(SymbolInfoInteger(symbol,SYMBOL_DIGITS));

   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);

   double Ask=SymbolInfoDouble(symbol,SYMBOL_ASK);

   if(!digit || !point || !Ask) return(true);



//---- =8F80;870F8O AB@C:BC@K B>@3>2>3> 70?@>A0 MqlTradeRequest 4;O >B:@K20=8O BUY ?>78F88

   request.type   = ORDER_TYPE_SELL;

   request.price  = Ask;

   request.action = TRADE_ACTION_SLTP;

   request.symbol = symbol;

   request.position=PositionGetInteger(POSITION_TICKET); 



//---- ?@545;5=85 @0AAB>O=8O 4> AB>?;>AA0 2 548=8F0E F5=>2>3> 3@0D8:0

   if(StopLoss!=0)

     {

      int nStopLoss=int((StopLoss-Ask)/point);

      if(nStopLoss<0) return(false);

      if(!StopCorrect(symbol,nStopLoss))return(false);

      double dStopLoss=nStopLoss*point;

      request.sl=NormalizeDouble(request.price+dStopLoss,digit);

      double laststop=PositionGetDouble(POSITION_SL);

      if(request.sl>laststop && laststop) request.sl=PositionGetDouble(POSITION_SL);

     }

   else request.sl=PositionGetDouble(POSITION_SL);



//---- ?@545;5=85 @0AAB>O=8O 4> B59:?@>D8B0 548=8F0E F5=>2>3> 3@0D8:0

   if(Takeprofit!=0)

     {

      int nTakeprofit=int((Ask-Takeprofit)/point);

      if(nTakeprofit<0) return(false);

      if(!StopCorrect(symbol,nTakeprofit))return(false);

      double dTakeprofit=nTakeprofit*point;

      request.tp=NormalizeDouble(request.price-dTakeprofit,digit);

      double lasttake=PositionGetDouble(POSITION_TP);

      if(request.tp>lasttake && lasttake) request.tp=PositionGetDouble(POSITION_TP);

     }

   else request.tp=PositionGetDouble(POSITION_TP);



//----   

   if(request.tp==PositionGetDouble(POSITION_TP) && request.sl==PositionGetDouble(POSITION_SL)) return(true);

   request.deviation=deviation;

   request.type_filling=ORDER_FILLING_FOK;



//---- @>25@:0 B>@3>2>3> 70?@>A0 =0 :>@@5:B=>ABL

   if(!OrderCheck(request,check))

     {

      Print(__FUNCTION__,"(): 525@=K5 40==K5 4;O AB@C:BC@K B>@3>2>3> 70?@>A0!");

      Print(__FUNCTION__,"(): OrderCheck(): ",ResultRetcodeDescription(check.retcode));

      return(false);

     }



   string comment="";

   StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): >48D8F8@C5< Sell ?>78F8N ?> ",symbol," ============ >>>");

   Print(comment);



//---- >48D8F8@C5< SELL ?>78F8N 8 45;05< ?@>25@:C @57C;LB0B0 B>@3>2>3> 70?@>A0

   if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)

     {

      Print(__FUNCTION__,"(): 52>7<>6=> <>48D8F8@>20BL ?>78F8N!");

      Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));

      return(false);

     }

   else

   if(result.retcode==TRADE_RETCODE_DONE)

     {

      Modify_Signal=false;

      comment="";

      StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Sell ?>78F8O ?> ",symbol," <>48D8F8@>20=0 ============ >>>");

      Print(comment);

      PlaySound("ok.wav");

     }

   else

     {

      Print(__FUNCTION__,"(): 52>7<>6=> <>48D8F8@>20BL ?>78F8N!");

      Print(__FUNCTION__,"(): OrderSend(): ",ResultRetcodeDescription(result.retcode));

     }

//----

   return(true);

  }

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

//| :>@@5:F8O @07<5@0 >B;>65==>3> >@45@0 4> 4>?CAB8<>3> 7=0G5=8O     |

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

bool StopCorrect(string symbol,int &Stop)

  {

//----

   long Extrem_Stop;

   if(!SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL,Extrem_Stop)) return(false);

   if(Stop<Extrem_Stop) Stop=int(Extrem_Stop);

//----

   return(true);

  }

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

//| 2>72@0B AB@8=3>2>3> @57C;LB0B0 B>@3>2>9 >?5@0F88 ?> 53> :>4C     |

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

string ResultRetcodeDescription(int retcode)

  {

   string str;

//----

   switch(retcode)

     {

      case TRADE_RETCODE_REQUOTE: str=" 5:2>B0"; break;

      case TRADE_RETCODE_REJECT: str="0?@>A >B25@3=CB"; break;

      case TRADE_RETCODE_CANCEL: str="0?@>A >B<5=5= B@5945@><"; break;

      case TRADE_RETCODE_PLACED: str="@45@ @07<5I5="; break;

      case TRADE_RETCODE_DONE: str="0O2:0 2K?>;=5=0"; break;

      case TRADE_RETCODE_DONE_PARTIAL: str="0O2:0 2K?>;=5=0 G0AB8G=>"; break;

      case TRADE_RETCODE_ERROR: str="H81:0 >1@01>B:8 70?@>A0"; break;

      case TRADE_RETCODE_TIMEOUT: str="0?@>A >B<5=5= ?> 8AB5G5=8N 2@5<5=8";break;

      case TRADE_RETCODE_INVALID: str="5?@028;L=K9 70?@>A"; break;

      case TRADE_RETCODE_INVALID_VOLUME: str="5?@028;L=K9 >1J5< 2 70?@>A5"; break;

      case TRADE_RETCODE_INVALID_PRICE: str="5?@028;L=0O F5=0 2 70?@>A5"; break;

      case TRADE_RETCODE_INVALID_STOPS: str="5?@028;L=K5 AB>?K 2 70?@>A5"; break;

      case TRADE_RETCODE_TRADE_DISABLED: str="">@3>2;O 70?@5I5=0"; break;

      case TRADE_RETCODE_MARKET_CLOSED: str=" K=>: 70:@KB"; break;

      case TRADE_RETCODE_NO_MONEY: str="5B 4>AB0B>G=KE 45=56=KE A@54AB2 4;O 2K?>;=5=8O 70?@>A0"; break;

      case TRADE_RETCODE_PRICE_CHANGED: str="&5=K 87<5=8;8AL"; break;

      case TRADE_RETCODE_PRICE_OFF: str="BACBAB2CNB :>B8@>2:8 4;O >1@01>B:8 70?@>A0"; break;

      case TRADE_RETCODE_INVALID_EXPIRATION: str="525@=0O 40B0 8AB5G5=8O >@45@0 2 70?@>A5"; break;

      case TRADE_RETCODE_ORDER_CHANGED: str="!>AB>O=85 >@45@0 87<5=8;>AL"; break;

      case TRADE_RETCODE_TOO_MANY_REQUESTS: str="!;8H:>< G0ABK5 70?@>AK"; break;

      case TRADE_RETCODE_NO_CHANGES: str=" 70?@>A5 =5B 87<5=5=89"; break;

      case TRADE_RETCODE_SERVER_DISABLES_AT: str="2B>B@5948=3 70?@5I5= A5@25@><"; break;

      case TRADE_RETCODE_CLIENT_DISABLES_AT: str="2B>B@5948=3 70?@5I5= :;85=BA:8< B5@<8=0;><"; break;

      case TRADE_RETCODE_LOCKED: str="0?@>A 701;>:8@>20= 4;O >1@01>B:8"; break;

      case TRADE_RETCODE_FROZEN: str="@45@ 8;8 ?>78F8O 70<>@>65=K"; break;

      case TRADE_RETCODE_INVALID_FILL: str="#:070= =5?>445@68205<K9 B8? 8A?>;=5=8O >@45@0 ?> >AB0B:C"; break;

      case TRADE_RETCODE_CONNECTION: str="5B A>548=5=8O A B>@3>2K< A5@25@><"; break;

      case TRADE_RETCODE_ONLY_REAL: str="?5@0F8O @07@5H5=0 B>;L:> 4;O @50;L=KE AG5B>2"; break;

      case TRADE_RETCODE_LIMIT_ORDERS: str=">AB83=CB ;8<8B =0 :>;8G5AB2> >B;>65==KE >@45@>2"; break;

      case TRADE_RETCODE_LIMIT_VOLUME: str=">AB83=CB ;8<8B =0 >1J5< >@45@>2 8 ?>78F89 4;O 40==>3> A8<2>;0"; break;

      case TRADE_RETCODE_INVALID_ORDER: str="525@=K9 8;8 70?@5IQ==K9 B8? >@45@0"; break;

      case TRADE_RETCODE_POSITION_CLOSED: str=">78F8O A C:070==K< POSITION_IDENTIFIER C65 70:@KB0"; break;

      case TRADE_RETCODE_INVALID_CLOSE_VOLUME: str="0:@K205<K9 >1J5< ?@52KH05B B5:CI89 >1J5< ?>78F88"; break;

      case TRADE_RETCODE_CLOSE_ORDER_EXIST: str=";O C:070==>9 ?>78F88 C65 5ABL >@45@ =0 70:@KB85"; break;

      case TRADE_RETCODE_LIMIT_POSITIONS: str=">;8G5AB2> >B:@KBKE ?>78F89, :>B>@>5 <>6=> >4=>2@5<5==> 8<5BL =0 AG5B5, <>65B 1KBL >3@0=8G5=> =0AB@>9:0<8 A5@25@0"; break;

      //case : str=""; break;

      //case : str=""; break;

      //case : str=""; break;

      //case : str=""; break;

      default: str="58725AB=K9 @57C;LB0B";

     }

//----

   return(str);

  }

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

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