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
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
38 //+------------------------------------------------------------------+
\r
39 //| expert initialization function |
\r
40 //+------------------------------------------------------------------+
\r
43 if(Digits==3||Digits==5){D_Factor=10;}
\r
45 Orders_Filename = StringConcatenate(WindowExpertName(),"_Ordersfile.csv");
\r
46 int Loaded_Orders = Load_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
52 else Print("Orders file loaded....." + Loaded_Orders + " orders found.");
\r
53 Permanent_Display();
\r
56 //+------------------------------------------------------------------+
\r
57 //| expert deinitialization function |
\r
58 //+------------------------------------------------------------------+
\r
64 if(IsTesting())FileDelete(Orders_Filename);
\r
68 //+------------------------------------------------------------------+
\r
69 //| expert start function |
\r
70 //+------------------------------------------------------------------+
\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
80 //-------------------------------------------------------------------
\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
102 Pip = MarketInfo(OrderSymbol(),MODE_POINT)*D_Factor;
\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
109 if(OrderMagicNumber()==MagicNumber||MagicNumber==-1){
\r
110 l_Trail_Percent = Get_Trail_Percent(OrderTicket(),OrderSymbol());
\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
122 if(My_SL-OrderStopLoss() > l_Min_Mod)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);
\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
136 if(OrderStopLoss()-My_SL > l_Min_Mod)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0,CLR_NONE);
\r
141 if(!mod)Print("Error entering Trailing Stop - Error (" + GetLastError() + "} " );
\r
144 else Print("Error selecting order in Trailing_Stop function. Error = " + GetLastError());
\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
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
156 CreateTextLable("Trade_No","No Open trades for us at the moment.........",Text_Color,0,100);
\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
163 string label_name,label_name2,label_name3,label_name4;
\r
166 CreateTextLable("Trade_No3","No trails active at the moment.......waiting",Yellow,0,120);
\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
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
186 CreateTextLable("My_Pips","Total Safe Pips : " + DoubleToStr(Locked_Pips(),1),LawnGreen,0,140+(line_cnt*20));
\r
191 //+------------------------------------------------------------------+
\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
214 //+------------------------------------------------------------------+
\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
225 if(OrderMagicNumber()==MagicNumber||MagicNumber==-1)counter++;
\r
229 //+------------------------------------------------------------------+
\r
230 void CreateTextLable(string TextLableName,string Text,color l_Text_Color,int X,int Y)
\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
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
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
274 //+------------------------------------------------------------------+
\r
280 Array_Size = ArrayRange(Trade_Info,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
288 for (int i = 0;i<OrdersTotal();i++){
\r
289 OrderSelect(i,SELECT_BY_POS);
\r
291 for (int cnt = 0;cnt<ArrayRange(Trade_Info,0);cnt++){
\r
292 if(OrderTicket()==Trade_Info[cnt][0]){
\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
303 //+------------------------------------------------------------------+
\r
304 void Delete_Ticket()
\r
306 if(!Trade_Count()){
\r
307 ArrayResize(Trade_Info,0);
\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
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
327 else Print("Error selecting order in Delete_Ticket function. Error - " + GetLastError());
\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
346 //+------------------------------------------------------------------+
\r
347 bool Create_OrderState()
\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
363 //+------------------------------------------------------------------+
\r
370 handle=FileOpen(Orders_Filename, FILE_BIN|FILE_READ);
\r
372 Print("No previous records exist.......");
\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
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
385 for(int i=0;i<OrdersTotal();i++){
\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
396 Temp_Orders[i][0]=OrderTicket();
\r
397 Temp_Orders[i][1]=0;
\r
398 Print("New order discovered....added to file.");
\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
409 handle=FileOpen(Orders_Filename, FILE_BIN|FILE_WRITE),
\r
410 Num_Orders = FileWriteArray(handle,Trade_Info,0,ArraySize(Trade_Info));
\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
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
435 l_Decay_Rate = Decay_Rate;
\r
438 if(Profit_Time(l_Ticket)>0)Bar_Shift = iBarShift(l_Pair,0,Profit_Time(l_Ticket));
\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
446 else l_Trail_Percent = Trail_Percent;
\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