bleh
[mqlkit.git] / Compuforex_Trail_Multi_v1.1.mq4
bloba055707563360f2f8c28cae6a84001691c841b1e
1 //+------------------------------------------------------------------+\r
2 //|                                             Compuforex_Trail.mq4 |\r
3 //|                            Copyright © 2010, www.compu-forex.com |\r
4 //|                                              www.compu-forex.com |\r
5 //+------------------------------------------------------------------+\r
6 #property copyright "Copyright © 2010, www.compu-forex.com"\r
7 #property link      "www.compu-forex.com"\r
8 \r
9 //---- input parameters\r
10 extern int        MagicNumber    = -1;\r
11 //extern bool       Enable_Trade    = false;\r
12 extern bool       Own_Symbol_Only = false;\r
13 extern string     Note1          = "Trail_Start $ Trail_Max are pip values";\r
14 extern double     Trail_Start    = 15;\r
15 extern double     Trail_Max      = 50;\r
16 extern string     Note2          = "Bigger Trail % = longer trail";\r
17 extern string     Note3          = "Trail_Percent & Trail_Min are % values";\r
18 extern double     Trail_Percent  = 80;\r
19 extern double     Trail_Min      = 10;\r
20 extern bool       Use_Decay      = true;\r
21 extern string     Note4          = "Decay rate reduces Trail_Percent per bar";\r
22 extern double     Decay_Rate     = 0.8;\r
23 extern bool       Exp_Decay      = true;\r
24 extern int        Wait_Minutes   = 90;\r
25 extern double     Min_Mod        = 0.5;\r
26 extern bool       Audio_Alert    = true;\r
27 extern color      Text_Color     = White;\r
29 int\r
30    D_Factor = 1,\r
31    Trade_Info[][2];\r
32 double   \r
33    Stop_Level;\r
34 string\r
35    Orders_Filename;\r
38 //+------------------------------------------------------------------+\r
39 //| expert initialization function                                   |\r
40 //+------------------------------------------------------------------+\r
41 int init()\r
42 {\r
43    if(Digits==3||Digits==5){D_Factor=10;}\r
44 //----\r
45    Orders_Filename = StringConcatenate(WindowExpertName(),"_Ordersfile.csv");\r
46    int Loaded_Orders = Load_Orders();\r
47    if(!Loaded_Orders){\r
48       Create_OrderState();\r
49       int Num_Orders_Saved = Save_Orders();\r
50       Print("Order matrix re-created...." + Num_Orders_Saved + " orders saved to file.");\r
51    }\r
52    else Print("Orders file loaded....." + Loaded_Orders + " orders found.");\r
53    Permanent_Display();\r
54    return(0);\r
55   }\r
56 //+------------------------------------------------------------------+\r
57 //| expert deinitialization function                                 |\r
58 //+------------------------------------------------------------------+\r
59 int deinit()\r
60   {\r
61 //----\r
62    ObjectsDeleteAll();\r
63    Save_Orders();\r
64    if(IsTesting())FileDelete(Orders_Filename);\r
65 //----\r
66    return(0);\r
67   }\r
68 //+------------------------------------------------------------------+\r
69 //| expert start function                                            |\r
70 //+------------------------------------------------------------------+\r
71 int start()\r
72 {\r
73 //------------------------------------------------------------------- simple trade to enable testing\r
74 /*  if(Enable_Trade){\r
75       if (OrdersTotal() < 2){\r
76          OrderSend(Symbol(), 0, 0.1, Ask, 3, 0 ,0 ,0, MagicNumber, 0,Lime);\r
77          OrderSend(Symbol(), 1, 0.1, Bid, 3, 0 ,0 ,0, MagicNumber, 0,Red);\r
78       }\r
79    }*/\r
80 //-------------------------------------------------------------------\r
81 bool\r
82    mod,\r
83    Profit_Order;\r
84 double\r
85    l_Trail_Start,\r
86    l_Trail_Max,\r
87    l_Min_Mod,\r
88    My_Profit,\r
89    My_Trail,\r
90    My_SL,\r
91    l_Trail_Percent,\r
92    Pip;\r
93 int\r
94    Bar_Shift;\r
96 //----\r
97    for (int i=OrdersTotal()-1;i>=0;i--){\r
98       if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){\r
99          if(Own_Symbol_Only){\r
100             if(OrderSymbol()!=Symbol())continue;\r
101          }\r
102          Pip = MarketInfo(OrderSymbol(),MODE_POINT)*D_Factor;\r
103          mod=true;\r
104          l_Trail_Start  = Trail_Start * Pip;\r
105          l_Trail_Max    = Trail_Max * Pip;\r
106          l_Min_Mod      = Min_Mod * Pip;\r
107          Stop_Level = MarketInfo(Symbol(),MODE_STOPLEVEL)/D_Factor;\r
108          Stop_Level *= Pip;\r
109          if(OrderMagicNumber()==MagicNumber||MagicNumber==-1){\r
110             l_Trail_Percent = Get_Trail_Percent(OrderTicket(),OrderSymbol());\r
111             RefreshRates();\r
112             switch(OrderType()){\r
113                case OP_BUY :  My_Profit = OrderClosePrice() - OrderOpenPrice();\r
114                               My_Trail = MathMin(My_Profit * (l_Trail_Percent/100),l_Trail_Max);\r
115                               My_Trail = MathMax(My_Trail,Stop_Level);\r
116                               My_SL = NormalizeDouble(OrderClosePrice()-My_Trail,Digits);\r
117                               Print("Trail_Start = " + Trail_Start);\r
118                               if(My_Profit > l_Trail_Start){\r
119                                  Update_Info(OrderTicket());\r
120                                  if(OrderStopLoss() == 0)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);\r
121                                  else{\r
122                                     if(My_SL-OrderStopLoss() > l_Min_Mod)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);\r
123                                  }\r
124                               }\r
125                               break;\r
126                         \r
127                case OP_SELL : My_Profit = OrderOpenPrice() - OrderClosePrice();\r
128                               My_Trail = MathMin(My_Profit * (l_Trail_Percent/100),l_Trail_Max);\r
129                               My_Trail = MathMax(My_Trail,Stop_Level);\r
130                               My_SL = NormalizeDouble(OrderClosePrice()+My_Trail,Digits);\r
131                               Print("Trail_Start = " + Trail_Start);\r
132                               if(My_Profit > l_Trail_Start){\r
133                                  Update_Info(OrderTicket());\r
134                                  if(OrderStopLoss() == 0)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);\r
135                                  else{\r
136                                     if(OrderStopLoss()-My_SL > l_Min_Mod)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0,CLR_NONE);\r
137                                  }\r
138                               }\r
139                               break;\r
140             }\r
141             if(!mod)Print("Error entering Trailing Stop - Error (" + GetLastError() + "} " );\r
142          }\r
143       }\r
144       else Print("Error selecting order in Trailing_Stop function. Error = " + GetLastError());\r
145    } \r
146    Print("Trade_info array size = " + ArrayRange(Trade_Info,0));\r
147    if(Trade_Count()>ArrayRange(Trade_Info,0))Add_Ticket();\r
148    if(Trade_Count()<ArrayRange(Trade_Info,0))Delete_Ticket();\r
149    Save_Orders();\r
150    CreateTextLable("Trade_No2","Trade Status",Text_Color,80,80);\r
151    CreateTextLable("Trade_No2_Und","______________",Text_Color,70,82);\r
152    CreateTextLable("Trade_No","Number of Open Trades : " + Trade_Count(),Text_Color,0,100);\r
153    Print("Trade_Count() = " + Trade_Count());\r
154    if(!Trade_Count()){\r
155       Clean_Up();\r
156       CreateTextLable("Trade_No","No Open trades for us at the moment.........",Text_Color,0,100);\r
157       return;\r
158    }\r
159    Profit_Order=false;\r
160    for(int t = 0;t<ArrayRange(Trade_Info,0);t++){\r
161       if(Trade_Info[t][1]>0)Profit_Order=true;\r
162    }\r
163    string label_name,label_name2,label_name3,label_name4;\r
164    Clean_Up();\r
165    if(!Profit_Order){\r
166       CreateTextLable("Trade_No3","No trails active at the moment.......waiting",Yellow,0,120);\r
167       return;\r
168    }\r
169    CreateTextLable("Trade_No3","Ticket #         Pair          Trail Start Time",Text_Color,0,120);\r
170    CreateTextLable("Trade_No4","_______________________________________________",Text_Color,0,122);\r
171    CreateTextLable("Trade_No5"," Trail %    Locked Pips",Text_Color,230,120);\r
172    CreateTextLable("Trade_No6","______________________",Text_Color,240,122);\r
173    int line_cnt=0;\r
174    for(t = 0;t<ArrayRange(Trade_Info,0);t++){\r
175       label_name = StringConcatenate("Trade_Show",t);\r
176       label_name2 = StringConcatenate("Trade_Show2",t);\r
177       label_name3 = StringConcatenate("Trade_Show3",t);\r
178       label_name4 = StringConcatenate("Trade_Show4",t);\r
179       if(Trade_Info[t][1]==0)continue;\r
180       CreateTextLable(label_name,Trade_Info[t][0] + "   " + Get_Symbol(Trade_Info[t][0]) + "              " + TimeToStr(Trade_Info[t][1],TIME_MINUTES),Text_Color,0,140+(line_cnt*20));\r
181       l_Trail_Percent = Get_Trail_Percent(OrderTicket(),OrderSymbol());\r
182       CreateTextLable(label_name2,DoubleToStr(l_Trail_Percent,0) + "%                " + DoubleToStr(Get_Safe_Pips(Trade_Info[t][0]),1),Text_Color,240,140+(line_cnt*20));\r
183       \r
184       line_cnt++;\r
185    }\r
186    CreateTextLable("My_Pips","Total Safe Pips : " + DoubleToStr(Locked_Pips(),1),LawnGreen,0,140+(line_cnt*20));\r
187 //----\r
189    return(0);\r
190   }\r
191 //+------------------------------------------------------------------+\r
192 void Clean_Up()\r
194 string \r
195    label_name,\r
196    label_name2,\r
197    label_name3,\r
198    label_name4;\r
199    ObjectDelete("Trade_No3");\r
200    ObjectDelete("Trade_No4");\r
201    ObjectDelete("Trade_No5");\r
202    ObjectDelete("Trade_No6");\r
203    ObjectDelete("My_Pips");\r
204    for(int oc = 0;oc<=ObjectsTotal(OBJ_LABEL);oc++){\r
205       label_name = StringConcatenate("Trade_Show",oc);\r
206       label_name2 = StringConcatenate("Trade_Show2",oc);\r
207       label_name3 = StringConcatenate("Trade_Show3",oc);\r
208       label_name4 = StringConcatenate("Trade_Show4",oc);\r
209       if(ObjectFind(label_name)==-1)continue;\r
210       ObjectDelete(label_name);\r
211       ObjectDelete(label_name2);\r
212    }\r
214 //+------------------------------------------------------------------+\r
216 int Trade_Count()\r
218 int\r
219    counter = 0;\r
220    for(int i = OrdersTotal()-1;i>=0;i--){\r
221       OrderSelect(i,SELECT_BY_POS);\r
222       if(Own_Symbol_Only){\r
223          if(OrderSymbol()!=Symbol())continue;\r
224       }\r
225       if(OrderMagicNumber()==MagicNumber||MagicNumber==-1)counter++;\r
226    }\r
227    return(counter);\r
229 //+------------------------------------------------------------------+\r
230 void CreateTextLable(string TextLableName,string Text,color l_Text_Color,int X,int Y)\r
231 \r
232 int\r
233    TextSize = 10,\r
234    Corner = 0;\r
235    if(TextLableName=="Heading")TextSize = 15;\r
236    ObjectCreate(TextLableName, OBJ_LABEL, 0, TimeCurrent(), 0);\r
237    ObjectSet(TextLableName, OBJPROP_CORNER, Corner);\r
238    ObjectSet(TextLableName, OBJPROP_XDISTANCE, X);\r
239    ObjectSet(TextLableName, OBJPROP_YDISTANCE, Y);\r
240    ObjectSetText(TextLableName,Text,TextSize,"New Times Roman",l_Text_Color);\r
242 //+------------------------------------------------------------------+\r
243 void Permanent_Display()\r
245    CreateTextLable("Heading","Compuforex Trailing Stop EA",Text_Color,0,10);\r
246    CreateTextLable("Underline1","_____________________________________",Text_Color,0,20);\r
247    if(Own_Symbol_Only)CreateTextLable("Pairs","Managing " + Symbol() + " Trades ONLY.",Text_Color,0,40);\r
248    else CreateTextLable("Pairs","Managing Trade on ALL pairs",Text_Color,0,40);\r
249    if(MagicNumber==-1)CreateTextLable("Magic_No","Managing trades with ANY MagicNumber",Text_Color,0,60);\r
250    else CreateTextLable("Magic_No","Managing trades ONLY with MagicNumber : " + MagicNumber,Text_Color,0,60);\r
252 //+------------------------------------------------------------------+ \r
253 double Locked_Pips()\r
255 double\r
256    Pips = 0,\r
257    l_Pip;\r
258    for(int i = OrdersTotal()-1;i>=0;i--){\r
259       OrderSelect(i,SELECT_BY_POS);\r
260       if(Own_Symbol_Only){\r
261          if(OrderSymbol()==Symbol())continue;\r
262       }\r
263       l_Pip = MarketInfo(OrderSymbol(),MODE_POINT)*D_Factor;\r
264       if(OrderMagicNumber()==MagicNumber||MagicNumber==-1){\r
265          if(Profit_Time(OrderTicket())>0){\r
266             if(OrderStopLoss()==0)continue;\r
267             if(OrderType()==OP_BUY)Pips += (OrderStopLoss()-OrderOpenPrice())/l_Pip;\r
268             if(OrderType()==OP_SELL)Pips += (OrderOpenPrice() - OrderStopLoss())/l_Pip;\r
269          }\r
270       }\r
271    }\r
272    return(Pips);\r
274 //+------------------------------------------------------------------+\r
275 void Add_Ticket()\r
277 bool\r
278    Found_it;\r
279 int\r
280    Array_Size = ArrayRange(Trade_Info,0),\r
281    Temp_Array[][2];\r
282    if(Array_Size>0){\r
283       ArrayResize(Temp_Array,Array_Size);\r
284       ArrayCopy(Temp_Array,Trade_Info); \r
285       ArrayResize(Trade_Info,Trade_Count());\r
286       ArrayCopy(Trade_Info,Temp_Array);\r
287    }\r
288    for (int i = 0;i<OrdersTotal();i++){\r
289       OrderSelect(i,SELECT_BY_POS);\r
290       Found_it=false;\r
291       for (int cnt = 0;cnt<ArrayRange(Trade_Info,0);cnt++){\r
292          if(OrderTicket()==Trade_Info[cnt][0]){\r
293             Found_it=true;\r
294          }\r
295       }\r
296       if(!Found_it){\r
297          ArrayResize(Trade_Info,ArrayRange(Trade_Info,0)+1);\r
298          Trade_Info[ArrayRange(Trade_Info,0)-1][0] = OrderTicket();\r
299          Trade_Info[ArrayRange(Trade_Info,0)-1][1] = 0;\r
300       }\r
301    }\r
303 //+------------------------------------------------------------------+\r
304 void Delete_Ticket()\r
306    if(!Trade_Count()){\r
307       ArrayResize(Trade_Info,0);\r
308       return;\r
309    }\r
310 int \r
311    Temp_Array[][2];\r
312    ArrayResize(Temp_Array,Trade_Count());\r
313    for(int y = OrdersTotal()-1;y>=0;y--){\r
314       if(OrderSelect(y,SELECT_BY_POS)){\r
315          if(Own_Symbol_Only){\r
316             if(OrderSymbol()!=Symbol())continue;\r
317          }\r
318          if(OrderMagicNumber()==MagicNumber||MagicNumber==-1){\r
319             for(int x = ArrayRange(Trade_Info,0)-1;x>=0;x--){\r
320                if(OrderTicket()==Trade_Info[x][0]){\r
321                   Temp_Array[y][0] = Trade_Info[x][0];\r
322                   Temp_Array[y][1] = Trade_Info[x][1];\r
323                }\r
324             }\r
325          }\r
326       }\r
327       else Print("Error selecting order in Delete_Ticket function. Error - " + GetLastError());\r
328    }\r
329    ArrayResize(Trade_Info,ArrayRange(Temp_Array,0));\r
330    ArrayCopy(Trade_Info,Temp_Array);\r
332 //+------------------------------------------------------------------+\r
333 void Update_Info(int l_Ticket)\r
335    for(int x = ArrayRange(Trade_Info,0)-1;x>=0;x--){\r
336       if(Trade_Info[x][0]==l_Ticket){\r
337          if(Trade_Info[x][1]==0){\r
338             Trade_Info[x][1] = iTime(Symbol(),0,0);\r
339             PlaySound("alert2.wav");\r
340             return;\r
341          }\r
342       }\r
343    }\r
344    return;\r
346 //+------------------------------------------------------------------+\r
347 bool Create_OrderState()\r
349 int\r
350    cnt=0;\r
351    ArrayResize(Trade_Info,Trade_Count());\r
352    for (int i = OrdersTotal()-1;i>=0;i--){\r
353       if(!OrderSelect(i,SELECT_BY_POS))return(true);\r
354       if(OrderSymbol()==Symbol()){\r
355          if(OrderMagicNumber()==MagicNumber||MagicNumber==-1){\r
356             Trade_Info[i][0]=OrderTicket();\r
357             Trade_Info[i][1]=0;\r
358          }\r
359       }\r
360    }\r
361    return(false);\r
363 //+------------------------------------------------------------------+\r
364 int Load_Orders()\r
366 bool\r
367    Order_OK;\r
368 int\r
369    Temp_Orders[][2],\r
370    handle=FileOpen(Orders_Filename, FILE_BIN|FILE_READ);\r
371    if(handle<0){\r
372       Print("No previous records exist.......");\r
373       return(0);\r
374    }\r
375    ArrayResize(Temp_Orders,OrdersTotal());\r
376    ArrayResize(Trade_Info,FileSize(handle)/4);\r
377    int Loaded_Orders = FileReadArray(handle,Trade_Info,0,FileSize(handle)/4);\r
378    FileClose(handle);\r
379    Print("Previous Order File found.......verifying integrity.");\r
380    if(!OrdersTotal()){\r
381       ArrayResize(Trade_Info,0);\r
382       Print("No trades exist.....Order File discarded.");\r
383       return(0);\r
384    }\r
385    for(int i=0;i<OrdersTotal();i++){\r
386       Order_OK=false;\r
387       OrderSelect(i,SELECT_BY_POS);\r
388       for(int x=0;x<ArrayRange(Trade_Info,0);x++){\r
389          if(OrderTicket()==Trade_Info[x][0]){\r
390             Temp_Orders[i][0]=Trade_Info[x][0];\r
391             Temp_Orders[i][1]=Trade_Info[x][1];\r
392             Order_OK=true;\r
393          }\r
394       }\r
395       if(!Order_OK){\r
396          Temp_Orders[i][0]=OrderTicket();\r
397          Temp_Orders[i][1]=0;\r
398          Print("New order discovered....added to file.");\r
399       }\r
400    }\r
401    ArrayResize(Trade_Info,ArrayRange(Temp_Orders,0));\r
402    ArrayCopy(Trade_Info,Temp_Orders);\r
403    return(ArrayRange(Trade_Info,0));\r
405 //+------------------------------------------------------------------+\r
406 int Save_Orders()\r
408 int\r
409    handle=FileOpen(Orders_Filename, FILE_BIN|FILE_WRITE),\r
410    Num_Orders = FileWriteArray(handle,Trade_Info,0,ArraySize(Trade_Info));\r
411    FileClose(handle);\r
412    return(Num_Orders/2);\r
414 //+------------------------------------------------------------------+\r
415 int Profit_Time(int l_Ticket)\r
417    for(int y = ArrayRange(Trade_Info,0)-1;y>=0;y--){\r
418       if(Trade_Info[y][0]==l_Ticket)return(Trade_Info[y][1]);\r
419    }\r
420    return(0);\r
422 //+------------------------------------------------------------------+\r
423 double Get_Safe_Pips(int l_Ticket)\r
425    OrderSelect(l_Ticket,SELECT_BY_TICKET);\r
426    if(OrderStopLoss()==0)return(0);\r
427    double l_Pip = MarketInfo(OrderSymbol(),MODE_POINT)*D_Factor;\r
428    return(MathAbs(OrderOpenPrice()-OrderStopLoss())/l_Pip);\r
430 //+------------------------------------------------------------------+\r
431 int Get_Trail_Percent(int l_Ticket, string l_Pair)\r
433 double\r
434    l_Trail_Percent,\r
435    l_Decay_Rate = Decay_Rate;\r
436 int\r
437    Bar_Shift;\r
438    if(Profit_Time(l_Ticket)>0)Bar_Shift = iBarShift(l_Pair,0,Profit_Time(l_Ticket));\r
439    else Bar_Shift=0;\r
440    if(Use_Decay){\r
441       if(Bar_Shift>=Wait_Minutes/Period()){\r
442          Bar_Shift = Bar_Shift - Wait_Minutes/Period();\r
443          if(Exp_Decay)l_Decay_Rate = Bar_Shift * Decay_Rate;\r
444          l_Trail_Percent = Trail_Percent - (Bar_Shift * l_Decay_Rate);\r
445       }\r
446       else l_Trail_Percent = Trail_Percent;\r
447    }\r
448    else l_Trail_Percent = Trail_Percent;\r
449    l_Trail_Percent = MathMax(l_Trail_Percent,Trail_Min);\r
450    return(l_Trail_Percent);\r
452 //+------------------------------------------------------------------+\r
453 string Get_Symbol(int l_Ticket)\r
455    OrderSelect(l_Ticket, SELECT_BY_TICKET);\r
456    return(StringSubstr(OrderSymbol(),0,6));\r
458 //+------------------------------------------------------------------+\r