bleh
[mqlkit.git] / libraries / OrderLib.mq4
blob1ab5ffa67de003c2120194a3a51ccd7587d34ba3
1 /*=============================================================\r
2  Info:    Order Library \r
3  Name:    OrderLib.mq4\r
4  Author:  Eric Pribitzer\r
5  Version: 0.92\r
6  Update:  2011-05-05\r
7  Notes:   add OP_ALL at OL_enumOrderList(...), OL_PROFITPIPS (calc TP+SL)\r
8  Version: 0.9\r
9  Update:  2011-03-30\r
10  Notes:   LotSize Calculation Update, CUSTOM_TICKVALUE\r
11  Version: 0.8\r
12  Update:  2011-03-28\r
13  Notes:   Bug WriteBuffer removed in TestingMode\r
14           OL_RISK_PIPS and OL_PROFIT_PIPS added and tested\r
15           OL_MAX_ORDERS added \r
16  Version: 0.7\r
17  Update:  2010-02-11 \r
18  Notes:   ---\r
19   \r
20  Copyright (C) 2010 Erich Pribitzer\r
21 =============================================================*/\r
23 #property copyright "Copyright © 2011, Erich Pribitzer"\r
24 #property link      "http://www.wartris.com"\r
25 #property library\r
27 #include <BasicH.mqh>\r
28 #include <OrderLibH.mqh>\r
31 bool   OL_ALLOW_ORDER           = true;\r
32 double OL_RISK_PERC             = 0;                                  // in %\r
33 int    OL_RISK_PIPS             = 0;                                  // 0=auto (calc price-stoploss)\r
34 int    OL_PROFIT_PIPS           = 0;\r
35 int    OL_TRAILING_STOP         = 0;\r
36 double OL_LOT_SIZE              = 1;                                  // 0=auto lot depends on risk pips and risk percent per trade\r
37 double OL_INITIAL_LOT           = 0;\r
38 double OL_CUSTOM_TICKVALUE      = 0;                                  // 0=no custom tickvalue\r
39 int    OL_SLIP_PAGE             = 0;\r
40 bool   OL_STOPSBYMODIFY         = false;                              // true = sl,tp will set by modify order\r
41 double OL_MAX_LOT               = 2;\r
42 int    OL_MAGIC                 = 0xA1200;                           // 0xA12xx Note: the first two digits must be zero\r
43 int    OL_MAX_ORDERS            = 3;\r
44 bool   OL_ORDER_DUPCHECK        = true;\r
45 bool   OL_OPPOSITE_CLOSE        = false;                             // oder will only closed when the new TP lies between SL and Price of an active order    \r
46 bool   OL_ORDER_COLOR           = true;\r
47 bool   OL_MYSQL_LOG             = true;    \r
49 double orderInfo[OL_SIZE][OL_ORDER_BUFFER_SIZE];\r
50 string orderInfoDesc[OL_ORDER_BUFFER_SIZE];\r
51 double orderProp[OL_SIZE];\r
52 string orderDesc;\r
54 #define OL_ORDER_OPEN_CLR Red\r
55 #define OL_ORDER_CLOSE_CLR Green\r
56 #define OL_ORDER_MODIFY_CLR Violet\r
58 #define OL_CL_OPPOSITCLOSE 1\r
59 #define OL_CL_TIMEEXPIRE 2\r
60 #define OL_CL_STOPLOSS 3\r
61 #define OL_CL_TAKEPROFIT 4\r
62 #define OL_CL_UNKNOWN 5\r
63 #define OL_CL_BYEA 6\r
64 #define OL_CL_DUPCHECK 7\r
65 #define OL_CL_SIZE 8\r
67 string OL_CL_STRING[OL_CL_SIZE]={"","Opposit","Expire","StopLoss","TakePorfit","Unknown","ByEA","Dupcheck"};\r
69 double OL_BUFFER_COUNT = 0;\r
71 bool OrderLib_Initialized;\r
73 int OL_Init(bool ALLOW_ORDER,double RISK_PERC,int RISK_PIPS,int PROFIT_PIPS,int TRAILING_STOP, double LOT_SIZE,double INITIAL_LOT,double CUSTOM_TICKVALUE, int SLIPPAGE, bool STOPSBYMODIFY, double MAX_LOT, int MAX_ORDERS, int MAGIC, bool ORDER_DUPCHECK, bool OPPOSITE_CLOSE, bool ORDER_COLOR, bool MYSQL_LOG)\r
74 {\r
75    OL_ALLOW_ORDER           = ALLOW_ORDER;\r
76    OL_RISK_PERC             = RISK_PERC;\r
77    OL_RISK_PIPS             = RISK_PIPS;\r
78    OL_PROFIT_PIPS           = PROFIT_PIPS;\r
79    OL_TRAILING_STOP         = TRAILING_STOP;\r
80    OL_LOT_SIZE              = LOT_SIZE;\r
81    OL_INITIAL_LOT           = INITIAL_LOT;\r
82    OL_CUSTOM_TICKVALUE      = CUSTOM_TICKVALUE;\r
83    OL_SLIP_PAGE             = SLIPPAGE;\r
84    OL_STOPSBYMODIFY          = STOPSBYMODIFY;\r
85    OL_MAX_LOT               = MAX_LOT;\r
86    OL_MAX_ORDERS            = MAX_ORDERS;\r
87    OL_MAGIC                 = MAGIC;\r
88    OL_ORDER_DUPCHECK        = ORDER_DUPCHECK;\r
89    OL_OPPOSITE_CLOSE        = OPPOSITE_CLOSE;\r
90    OL_ORDER_COLOR           = ORDER_COLOR;\r
91    OL_MYSQL_LOG             = MYSQL_LOG;\r
92    \r
93    BA_Init();\r
96    if(IsTesting()==true)\r
97    {\r
98       OL_ClearBuffer();\r
99       Print("Testing Mode: Clear Order Buffer");\r
100    }\r
102    if(OrderLib_Initialized==false)\r
103    {         \r
104      Print("Init OrderLib");\r
105      OL_ReadBuffer();\r
106      OL_SyncBuffer();\r
107      OrderLib_Initialized=true; \r
108    }   \r
112 int OL_Deinit()\r
114    OL_WriteBuffer();\r
115    OrderLib_Initialized=false;\r
116    Print("Deinit OrderLib");\r
119 int OL_SyncBuffer()\r
122    if(IsTesting()==true) return;\r
123       \r
124    int total=OrdersTotal();\r
125    int magic=0;\r
126    string symbol="";\r
127    double tp=0;\r
128    double sl=0;\r
129    double lot=0;\r
130    int ma=0;\r
131    int inx=0;\r
132    double buff[OL_ORDER_BUFFER_SIZE];\r
133    \r
134    ArrayInitialize(buff,0);\r
135    \r
136    \r
137    for(int pos=0;pos<total;pos++)\r
138    {\r
139       if(OrderSelect(pos,SELECT_BY_POS)==false) continue;\r
140       magic=OrderMagicNumber();\r
141       symbol=OrderSymbol();\r
142       if( (magic&0xFFFFF00) == OL_MAGIC && Symbol() == symbol)\r
143       {         \r
144          // change local order buffer, mark order as aktive \r
145          buff[magic&0xFF]=1;\r
146 /*\r
147          tp=NormalizeDouble(OrderTakeProfit(),DIGITS);\r
148          sl=NormalizeDouble(OrderTakeProfit(),DIGITS);\r
149          lot=NormalizeDouble(OrderLots(),LOTDIGITS);\r
150          if(orderInfo[OL_TAKEPROFIT][magic&0xFF]!=tp || orderInfo[OL_STOPLOSS][magic&0xFF]!=sl || orderInfo[OL_LOTSIZE][magic&0xFF]!=lot)\r
151          {\r
152 */\r
153          if(orderInfo[OL_ID][magic&0xFF]>0)\r
154          {  \r
155             tp=NormalizeDouble(OrderTakeProfit(),DIGITS);\r
156             sl=NormalizeDouble(OrderStopLoss(),DIGITS);\r
157             \r
158             if(tp>0)\r
159                orderInfo[OL_TAKEPROFIT][magic&0xFF]=tp;\r
160             if(sl>0)\r
161                orderInfo[OL_STOPLOSS][magic&0xFF]=sl;\r
162                \r
163             orderInfo[OL_LOTSIZE][magic&0xFF]=NormalizeDouble(OrderLots(),LOTDIGITS);\r
164          }\r
165 //       }\r
166       }      \r
167    }\r
169    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
170    { \r
171       // sync local order buffer via real active orders\r
172       if(buff[binx]==0 && orderInfo[OL_ID][binx]>0)     // only running orders\r
173       {\r
174          orderInfo[OL_ID][binx]=0;\r
175          orderInfo[OL_CLOSEREASON][binx]=OL_CL_UNKNOWN;\r
176          Print("Clear Index: ",binx);\r
177       }   \r
178    }\r
182 int OL_ReadBuffer()\r
184       \r
185       string key="";\r
186       int count=0;\r
187       \r
188       ArrayInitialize(orderProp,0);\r
189        \r
190       for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
191       {\r
192          if(IsTesting()==false)\r
193          {\r
194             if(GlobalVariableCheck(OL_FIX + Symbol()  + "_BI" + binx + "I" + OL_ID)==true) \r
195             {\r
196                count++;\r
197             }\r
198             else\r
199             {\r
200                orderInfo[OL_ID][binx]=0;\r
201                continue;  \r
202             }\r
203          \r
204             for(int inx=0;inx<OL_SIZE;inx++)\r
205             {\r
206                orderInfo[inx][binx]=GlobalVariableGet(OL_FIX + Symbol()  + "_BI" + binx + "I" + inx);\r
207             }\r
208          }\r
209              \r
210          if(orderInfo[OL_ID][binx]!=0)\r
211             OL_Update(binx);\r
212       }\r
213       return (count);\r
216 int OL_WriteBuffer()\r
217 {     \r
218       string key="";\r
219       int count=0;\r
220       for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
221       {\r
222          if(orderInfo[OL_ID][binx]!=0) \r
223          {\r
224             count++;\r
225             OL_Update(binx);\r
226          }\r
227          \r
228          //order has closed state ?? >>\r
229          if(orderInfo[OL_CLOSEREASON][binx]>0)\r
230          {\r
231             int clinx=orderInfo[OL_CLOSEREASON][binx];\r
232             orderInfo[OL_CTIME][binx]=TimeCurrent();\r
233             orderInfo[OL_CBAR][binx]=Bars;\r
234             orderInfo[OL_CSPREAD][binx]=NormalizeDouble(Ask-Bid,DIGITS)/POINT;\r
235             orderInfo[OL_CTICKCOUNT][binx]= GetTickCount() & 0x7FFFFFFF;  \r
237             // was active ?\r
238             if(orderInfo[OL_OID][binx]>0) // yes >>\r
239             {\r
240                // print stats                          \r
241                Print("Close reason: ",OL_CL_STRING[clinx],\r
242                " / Order ID: ",orderInfo[OL_OID][binx],\r
243                " / Minutes: ",NormalizeDouble((orderInfo[OL_CTIME][binx]-orderInfo[OL_OTIME][binx])/60,1),\r
244                " / HiProfit: ",orderInfo[OL_HIPROFIT][binx],\r
245                " / LoProfit: ",orderInfo[OL_LOPROFIT][binx],\r
246                " / Profit: ",orderInfo[OL_PROFIT][binx],\r
247                " / Desc: ",orderInfoDesc[binx]);\r
248              \r
249             } \r
251             int xx=orderInfo[OL_CLOSEREASON][binx];         \r
252             orderInfo[OL_CLOSEREASON][binx]=0;\r
253             orderInfo[OL_ERRORNO][binx]=0;\r
254             Print("Clear ",binx,",",OL_CL_STRING[xx]);\r
255             \r
256          }\r
258          if(IsTesting()==false )\r
259          {\r
260             for(int inx=0;inx<OL_SIZE;inx++)\r
261             {            \r
262                key=OL_FIX + Symbol()  + "_BI" + binx + "I" + inx;\r
263                if(orderInfo[OL_ID][binx]==0)\r
264                {\r
265                   GlobalVariableDel(key);    \r
266                }\r
267                else\r
268                {\r
269                   //Print("Write Global....",key);\r
270                   GlobalVariableSet( key,  orderInfo[inx][binx]);              \r
271                }\r
272             }\r
273          }\r
274       }\r
278 void OL_ClearBuffer()\r
280    string key;\r
281    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
282    {\r
283       for(int inx=0;inx<OL_SIZE;inx++)\r
284       {            \r
285          key=OL_FIX + Symbol()  + "_BI" + binx + "I" + inx;\r
286          GlobalVariableDel(key);\r
287          orderInfo[OL_ID][binx]=0;\r
288          orderInfo[OL_CLOSEREASON][binx]=0;   \r
289       }\r
290    }\r
294 void OL_addOrderProperty(int property,double value)\r
296    orderProp[property]=value;      \r
299 void OL_addOrderDescription(string desc)\r
301    orderDesc=desc;      \r
304 int OL_registerOrder()\r
306    \r
307    int buy=OL_orderCount(OP_BUY);\r
308    int sell=OL_orderCount(OP_SELL);\r
309    \r
310    if(buy+sell >= OL_MAX_ORDERS)\r
311    {\r
312       Print("Error: max order limit reached");\r
313       return (0);\r
314    }\r
315    \r
316    int inx;\r
317    int binx=OL_GetFreeIndex();\r
318    if(binx==-1) \r
319    {\r
320       \r
321       ArrayInitialize(orderProp,0);\r
322       return (-1);\r
323    }\r
324    \r
325    if(OL_OPPOSITE_CLOSE==true)\r
326       OL_processOppositClose(orderProp[OL_TYPE],orderProp[OL_TAKEPROFIT]);\r
327       \r
328    orderProp[OL_OPRICE]=NormalizeDouble(orderProp[OL_OPRICE],DIGITS);\r
329    orderProp[OL_TAKEPROFIT]=NormalizeDouble(orderProp[OL_TAKEPROFIT],DIGITS);\r
330    orderProp[OL_STOPLOSS]=NormalizeDouble(orderProp[OL_STOPLOSS],DIGITS);\r
333    if(orderProp[OL_OPRICE]==0)\r
334    {\r
335       if(orderProp[OL_TYPE]==OP_BUY)\r
336          orderProp[OL_OPRICE]=NormalizeDouble(Ask,DIGITS);\r
337       else\r
338          orderProp[OL_OPRICE]=NormalizeDouble(Bid,DIGITS);\r
339    }\r
341    if(OL_ORDER_DUPCHECK==true)\r
342    {\r
343       for(inx=0;inx<OL_ORDER_BUFFER_SIZE;inx++)\r
344       {\r
345          if(orderInfo[OL_TYPE][inx]==orderProp[OL_TYPE] && orderProp[OL_OPRICE]==orderInfo[OL_OPRICE][inx] )\r
346          {\r
347             if(orderInfo[OL_ID][inx]<0)\r
348             {\r
349                orderInfo[OL_ID][inx]=0;                        // clear pending\r
350                orderInfo[OL_CLOSEREASON][inx]=OL_CL_DUPCHECK;\r
352             }\r
353             else if(orderInfo[OL_ID][inx]>0)\r
354             {\r
355                ArrayInitialize(orderProp,0);\r
356                return (-1);                                    // same order is running!! cancel register order\r
357             }      \r
358          }     \r
359       }\r
360    }\r
362    orderInfo[OL_ID][binx]=OL_SCHEDULED;                     // oder SCHEDULED!!\r
363    for(inx=1;inx<OL_SIZE;inx++)\r
364    {\r
365       orderInfo[inx][binx]=orderProp[inx];      \r
366    }\r
367    orderInfoDesc[binx]=orderDesc;   \r
368    orderDesc="";\r
369    ArrayInitialize(orderProp,0);\r
370    return (binx);   \r
373 double OL_getOrderProperty(int binx,int property)\r
374 \r
375   return (orderInfo[property][binx]);\r
378 void OL_setOrderProperty(int binx,int property,double value)\r
379 {   \r
380    if(orderInfo[OL_ID][binx]>0 && orderInfo[OL_CLOSEREASON][binx]==0)     // change only active and none closed orders\r
381    {\r
382       orderInfo[property][binx]=value;      \r
383    }\r
387 // Modify or open new order\r
388 void OL_processOrder()\r
390    OL_processClose(); \r
391    double price=0;\r
392    \r
393    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
394    {\r
395       double bid=NormalizeDouble(Bid,DIGITS);\r
396       double ask=NormalizeDouble(Ask,DIGITS);\r
397       \r
398       if(orderInfo[OL_ID][binx]==OL_SCHEDULED) // Open Order\r
399       {\r
400  \r
401          if(OL_ALLOW_ORDER==false) \r
402          {\r
403             Print("Erro: order disallowed");\r
404             orderInfo[OL_ID][binx]=0;\r
405             return;\r
406          }\r
407          \r
408       // To do: add pending orders, add hidden sl tp\r
409          if(\r
410              ((orderInfo[OL_TYPE][binx]==OP_BUY)  && ( (bid < orderInfo[OL_TAKEPROFIT][binx] || orderInfo[OL_TAKEPROFIT][binx]==0) )) ||\r
411              ((orderInfo[OL_TYPE][binx]==OP_SELL) && ( (ask >= orderInfo[OL_TAKEPROFIT][binx] || orderInfo[OL_TAKEPROFIT][binx]==0) )) ||\r
412              (orderInfo[OL_OTIME][binx]>0 && orderInfo[OL_OTIME][binx] >= TimeCurrent())\r
413            )\r
414          {\r
415              if(OL_orderOpen(binx)==false)\r
416              {             \r
417                   // clear order\r
418                   orderInfo[OL_ID][binx]=0;\r
419              }\r
420              else if(OL_STOPSBYMODIFY==true && orderInfo[OL_TAKEPROFIT][binx]>0 || orderInfo[OL_STOPLOSS][binx]>0)\r
421              {\r
422                \r
423                // set stoploss and takeprofit\r
424                OL_orderModify(binx);\r
426              }\r
427          }\r
429       }\r
430       else if(orderInfo[OL_ID][binx]>0) // Modify active Order\r
431       {\r
432          if(orderInfo[OL_FLAG][binx] == OL_FL_MODIFY)\r
433          {\r
434             // clear flag\r
435             orderInfo[OL_FLAG][binx]=0;\r
436             OL_orderModify(binx);\r
437          }\r
438       }            \r
439    } \r
443 int OL_orderCount(int cmd)\r
445       int count=0;\r
446       int bx=0;\r
447       while (bx!=-1)\r
448       {   \r
449          bx=OL_enumOrderList(bx,cmd);\r
450          if(bx>=0)\r
451          { \r
452             count++;\r
453             bx++;\r
454          }\r
455       }\r
456       \r
457       return (count);\r
460 // return the order buffer index\r
461 // -1 = no elements left\r
462 int OL_enumOrderList(int inx, int cmd)\r
464    int binx=inx;\r
465    \r
466    while(binx<OL_ORDER_BUFFER_SIZE)\r
467    {     \r
468       if(orderInfo[OL_ID][binx] > 0 && (orderInfo[OL_TYPE][binx]==cmd || (cmd==OL_ALL && (orderInfo[OL_TYPE][binx]==OP_SELL || orderInfo[OL_TYPE][binx]==OP_BUY))) )\r
469       {\r
470          return(binx);      \r
471       }\r
472       binx++;\r
473    }\r
474    return (-1);\r
477 void OL_processOppositClose(int cmd, double tp)\r
479    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
480    {\r
481       if(\r
482          (cmd==OP_BUY && orderInfo[OL_TYPE][binx]==OP_SELL && orderInfo[OL_ID][binx]!=0 && (tp >= orderInfo[OL_OPRICE][binx] || tp==0) ) ||\r
483          (cmd==OP_SELL && orderInfo[OL_TYPE][binx]==OP_BUY && orderInfo[OL_ID][binx]!=0 && (tp <= orderInfo[OL_OPRICE][binx]|| tp==0) )\r
484         )\r
485       {\r
486             if(orderInfo[OL_ID][binx]>0)\r
487             {\r
488                if(OL_orderClose(binx)==true)\r
489                {              \r
490                   orderInfo[OL_ID][binx]=0;\r
491                   orderInfo[OL_CLOSEREASON][binx]=OL_CL_OPPOSITCLOSE;\r
492                }\r
493                else if(orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET)\r
494                {\r
495                   orderInfo[OL_ID][binx]=0;\r
496                   orderInfo[OL_CLOSEREASON][binx]=OL_CL_UNKNOWN;\r
497                }\r
498                else\r
499                   Print("Error: close opposite order");\r
500             }\r
501             else if(orderInfo[OL_ID][binx]==OL_SCHEDULED)  // scheduled\r
502             {\r
503               orderInfo[OL_ID][binx]=0; \r
504               orderInfo[OL_CLOSEREASON][binx]=OL_CL_OPPOSITCLOSE;\r
505             }       \r
506       }\r
507    }\r
510 void OL_processClose()\r
511 {  \r
512    double bid=NormalizeDouble(Bid,DIGITS);\r
513    double ask=NormalizeDouble(Ask,DIGITS);\r
514    \r
515    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
516    {\r
517       if(orderInfo[OL_ID][binx]!=0)\r
518       {\r
519      \r
520          if(orderInfo[OL_TAKEPROFIT][binx]>0 && ((orderInfo[OL_TYPE][binx]==OP_BUY && bid >= orderInfo[OL_TAKEPROFIT][binx]) || (orderInfo[OL_TYPE][binx]==OP_SELL && ask <= orderInfo[OL_TAKEPROFIT][binx])) ) \r
521          {\r
522             orderInfo[OL_CLOSEREASON][binx]=OL_CL_TAKEPROFIT;\r
523          }\r
524          else if(orderInfo[OL_STOPLOSS][binx]>0 && ((orderInfo[OL_TYPE][binx]==OP_BUY && bid <= orderInfo[OL_STOPLOSS][binx]) || (orderInfo[OL_TYPE][binx]==OP_SELL && ask >= orderInfo[OL_STOPLOSS][binx])) ) \r
525          {      \r
526             orderInfo[OL_CLOSEREASON][binx]=OL_CL_STOPLOSS;         \r
527          }\r
528          else if( orderInfo[OL_EXPIRATION][binx]>0 && orderInfo[OL_EXPIRATION][binx] <= TimeCurrent() )\r
529          {\r
530             orderInfo[OL_CLOSEREASON][binx]=OL_CL_TIMEEXPIRE;                  \r
531          }\r
532          else if(orderInfo[OL_FLAG][binx]==OL_FL_CLOSE)\r
533          {\r
534             orderInfo[OL_FLAG][binx]=0;\r
535             orderInfo[OL_CLOSEREASON][binx]=OL_CL_BYEA;                              \r
536          }\r
537          else\r
538             continue;\r
540          if(orderInfo[OL_ID][binx]>0)\r
541          {\r
542             if(OL_orderClose(binx)==true)\r
543             {\r
544                orderInfo[OL_ID][binx]=0;\r
545             }\r
546             else if(orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET)\r
547             {\r
549                orderInfo[OL_ID][binx]=0;\r
550             }\r
551             else\r
552                Print("Error: order close failed");\r
553          }\r
554          else\r
555          {                  \r
556            orderInfo[OL_ID][binx]=0;\r
557          }     \r
558       }\r
559    }             \r
562 int OL_GetFreeIndex()\r
564    for(int binx=0;binx<OL_ORDER_BUFFER_SIZE;binx++)\r
565    {\r
566       if(orderInfo[OL_ID][binx]==0  && orderInfo[OL_CLOSEREASON][binx]==0  )\r
567          return (binx);\r
568    }\r
569    return (-1);  \r
573 bool OL_orderOpen(int binx)\r
576    if(orderInfo[OL_TRAILINGSTOP][binx]==0)\r
577       orderInfo[OL_TRAILINGSTOP][binx]=OL_TRAILING_STOP;\r
578       \r
579    if(orderInfo[OL_SLIPPAGE][binx]==0)\r
580       orderInfo[OL_SLIPPAGE][binx]=OL_SLIP_PAGE;      \r
582    // Calc OL_STOPLOSS only if OL_RISK_PIPS or orderInfo[OL_RISKPIPS][binx] is given\r
583    if(orderInfo[OL_STOPLOSS][binx]==0 && (OL_RISK_PIPS > 0 || orderInfo[OL_RISKPIPS][binx]>0))\r
584    {   \r
585       int rp=OL_RISK_PIPS;\r
586       if(orderInfo[OL_RISKPIPS][binx]>0)\r
587          rp=orderInfo[OL_RISKPIPS][binx];\r
589       orderInfo[OL_STOPLOSS][binx]=OL_calcStopLoss(orderInfo[OL_TYPE][binx],rp,OL_OPEN,0);\r
590    }\r
592    // Calc TAKEPROFIT only if OL_PROFIT_PIPS or orderInfo[OL_PROFITPIPS][binx] is given\r
593    if(orderInfo[OL_TAKEPROFIT][binx]==0 && (OL_PROFIT_PIPS > 0 || orderInfo[OL_PROFITPIPS][binx]>0))\r
594    {\r
595       int pp=OL_PROFIT_PIPS;\r
596       \r
597       if(orderInfo[OL_PROFITPIPS][binx]>0)\r
598          pp=orderInfo[OL_PROFITPIPS][binx];//+MarketInfo(Symbol(),MODE_SPREAD);\r
600       orderInfo[OL_TAKEPROFIT][binx]=OL_calcTakeProfit(orderInfo[OL_TYPE][binx],pp,OL_OPEN,0);                              \r
601    }\r
602    \r
603    \r
604    int profitPip=MathAbs(orderInfo[OL_TAKEPROFIT][binx]-orderInfo[OL_OPRICE][binx]);\r
605    double money=AccountFreeMargin();\r
606    \r
607    // Calc LOTSIZE \r
608    if((orderInfo[OL_LOTSIZE][binx]==0 || OL_LOT_SIZE==0) && (orderInfo[OL_RISKPERC][binx]>0 || OL_RISK_PERC>0) && (OL_RISK_PIPS>0 || orderInfo[OL_RISKPIPS][binx]>0))\r
609    {\r
610       int    riskPip;\r
611       double riskPerc;\r
612       \r
613       if(orderInfo[OL_RISKPERC][binx]>0)\r
614          riskPerc=orderInfo[OL_RISKPERC][binx];\r
615       else      \r
616          riskPerc=OL_RISK_PERC;\r
617             \r
618       if(orderInfo[OL_RISKPIPS][binx]>0)\r
619          riskPip=orderInfo[OL_RISKPIPS][binx];   \r
620       else if(OL_RISK_PIPS>0)\r
621          riskPip=OL_RISK_PIPS;\r
622       else\r
623          riskPip=NormalizeDouble(MathAbs(orderInfo[OL_STOPLOSS][binx]-orderInfo[OL_OPRICE][binx]),DIGITS)/POINT;   \r
625       double tickvalue=MarketInfo(Symbol(),MODE_TICKVALUE);\r
626       if(OL_CUSTOM_TICKVALUE>0)\r
627          tickvalue=OL_CUSTOM_TICKVALUE;\r
628          \r
629       orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(1.0/tickvalue*(money/100*riskPerc/(riskPip)),LOTDIGITS);\r
630    }\r
631    else\r
632    {      \r
633       if(orderInfo[OL_LOTSIZE][binx]>0)\r
634       {      \r
635          orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(orderInfo[OL_LOTSIZE][binx],LOTDIGITS);\r
636       }\r
637       else if(OL_LOT_SIZE>0)\r
638       {\r
639          orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS)+NormalizeDouble(OL_LOT_SIZE,LOTDIGITS);\r
640       }\r
641       else if(OL_INITIAL_LOT>0)\r
642       {\r
643          orderInfo[OL_LOTSIZE][binx]=NormalizeDouble(OL_INITIAL_LOT,LOTDIGITS);\r
644       }   \r
645       else\r
646       {\r
647          Print("Error: wrong lotsize");\r
648          return (false);\r
649       }\r
650    }   \r
651    \r
652    if(orderInfo[OL_LOTSIZE][binx]>OL_MAX_LOT) orderInfo[OL_LOTSIZE][binx]=OL_MAX_LOT;\r
654           \r
655    int      ticketID =0;\r
656    \r
657    color    col=CLR_NONE;\r
658    if(OL_ORDER_COLOR)\r
659       col=OL_ORDER_OPEN_CLR;\r
661    if(orderInfo[OL_TYPE][binx]==OP_SELL)\r
662    {\r
663       if(orderInfo[OL_OPRICE][binx]==0)\r
664          orderInfo[OL_OPRICE][binx]=NormalizeDouble(Bid,DIGITS);\r
665    }\r
666    else\r
667    {\r
668       if(orderInfo[OL_OPRICE][binx]==0)\r
669          orderInfo[OL_OPRICE][binx]=NormalizeDouble(Ask,DIGITS);   \r
670    }\r
672    int      start    = GetTickCount()& 0x7FFFFFFF;\r
673    int      stop;\r
674    int      loop     = 1;\r
675    int      cmd      = orderInfo[OL_TYPE][binx];\r
676    double   sl       = 0;\r
677    double   tp       = 0;\r
678    \r
679    if(OL_STOPSBYMODIFY==false)\r
680    {\r
681      sl=orderInfo[OL_STOPLOSS][binx];\r
682      tp=orderInfo[OL_TAKEPROFIT][binx];\r
683    }\r
684    \r
685    while(loop>=0)\r
686    {\r
687       ticketID=OrderSend(Symbol(),cmd,orderInfo[OL_LOTSIZE][binx],orderInfo[OL_OPRICE][binx],orderInfo[OL_SLIPPAGE][binx],sl,tp,NULL,(OL_MAGIC|binx),0);\r
689       if(loop>0 && ticketID<1 && IsTradeBusy(4,100)==false)\r
690       {\r
691          RefreshRates();\r
692       }\r
693       else\r
694          break;\r
695                \r
696       loop--;\r
697    }\r
699    if(ticketID<1)\r
700    {     \r
701       Print("Error: ",ErrorDescription(GetLastError())); \r
702       orderInfo[OL_ERRORNO][binx]=GetLastError();\r
703       return(false);\r
704    }\r
705    else\r
706       stop=(GetTickCount()& 0x7FFFFFFF)-start;\r
707       \r
708         orderInfo[OL_OTICKCOUNT][binx]= GetTickCount() & 0x7FFFFFFF;   \r
709    orderInfo[OL_ID][binx]=ticketID;\r
710    orderInfo[OL_OID][binx]=ticketID;\r
711    orderInfo[OL_OBAR][binx]=Bars;\r
712    orderInfo[OL_OSPREAD][binx]=NormalizeDouble(Ask-Bid,DIGITS);\r
713       \r
714    if(OrderSelect(ticketID,SELECT_BY_TICKET)==true)\r
715    {\r
716       orderInfo[OL_OPRICE][binx]=NormalizeDouble(OrderOpenPrice(),DIGITS);\r
717       orderInfo[OL_OTIME][binx]=OrderOpenTime();\r
718       orderInfo[OL_HIPROFITTIME][binx]=orderInfo[OL_OTIME][binx];\r
719       orderInfo[OL_LOPROFITTIME][binx]=orderInfo[OL_OTIME][binx];   \r
720    }\r
721    else\r
722    {\r
723       orderInfo[OL_OTIME][binx]=TimeCurrent();\r
724       orderInfo[OL_HIPROFITTIME][binx]=orderInfo[OL_OTIME][binx];\r
725       orderInfo[OL_LOPROFITTIME][binx]=orderInfo[OL_OTIME][binx];\r
727    }\r
728  \r
729    orderInfo[OL_ERRORNO][binx]=0;\r
730           \r
731    return(true); \r
735 // mode=OL_OPEN or OL_CLOSE\r
736 double OL_calcStopLoss(int cmd, int pips, int mode, double price=0)\r
738    price=NormalizeDouble(price,DIGITS);\r
739    \r
740    if(cmd==OP_BUY)\r
741    {\r
742       if(price==0)\r
743       {\r
744          if(mode==OL_OPEN)\r
745             price=NormalizeDouble(Ask,DIGITS);\r
746          else\r
747             price=NormalizeDouble(Bid,DIGITS);\r
748       }            \r
749       return (NormalizeDouble(price-(pips*POINT),DIGITS));\r
750    }\r
751    else if(cmd==OP_SELL)\r
752    {\r
753       if(price==0) \r
754       {\r
755          if(mode==OL_OPEN)\r
756             price=NormalizeDouble(Bid,DIGITS);\r
757          else\r
758             price=NormalizeDouble(Ask,DIGITS);         \r
759       }\r
760       return (NormalizeDouble(price+(pips*POINT),DIGITS));  \r
761    }\r
762    \r
763    return (0);\r
766 double OL_calcTakeProfit(int cmd, int pips, int mode, double price=0)\r
768    price=NormalizeDouble(price,DIGITS);\r
769  \r
770  \r
771    if(cmd==OP_BUY)\r
772    {\r
773       if(price==0) \r
774       {\r
775          if(mode==OL_OPEN)         \r
776             price=NormalizeDouble(Ask,DIGITS);\r
777          else\r
778             price=NormalizeDouble(Bid,DIGITS);         \r
779       }\r
780       return (NormalizeDouble(price+(pips*POINT),DIGITS));\r
781    }\r
782    else if(cmd==OP_SELL)\r
783    {\r
784       if(price==0) \r
785       {\r
786          if(mode==OL_OPEN)\r
787             price=NormalizeDouble(Bid,DIGITS);                  \r
788          else\r
789             price=NormalizeDouble(Ask,DIGITS);                  \r
790       }\r
791       return (NormalizeDouble(price-(pips*POINT),DIGITS));  \r
792    }\r
793    \r
794    return (0);\r
799 bool OL_orderModify(int binx)\r
802    double sl,tp;   \r
803    bool ret=true;\r
804    color col=CLR_NONE;\r
805    \r
806    if(OL_ORDER_COLOR)\r
807       col=OL_ORDER_MODIFY_CLR;\r
808    \r
809    if(orderInfo[OL_ID][binx]<1) \r
810    {\r
811       orderInfo[OL_ERRORNO][binx]=ERR_INVALID_TICKET;\r
812       return (false);\r
813    }\r
814  \r
815    int      ticketID = orderInfo[OL_ID][binx];\r
816    int      loop     = 1;\r
817         \r
818    while(loop>=0)\r
819    {\r
820       ret=OrderModify(ticketID,orderInfo[OL_OPRICE][binx],orderInfo[OL_STOPLOSS][binx],orderInfo[OL_TAKEPROFIT][binx],NULL,col);\r
821       orderInfo[OL_ERRORNO][binx]=GetLastError();\r
822       \r
823       if(loop>0 && ret==false && orderInfo[OL_ERRORNO][binx]!=ERR_INVALID_TICKET && IsTradeBusy(4,100)==false) \r
824       {\r
825          RefreshRates();\r
826       }\r
827       else\r
828          break;\r
829       \r
830       loop--;\r
831    }\r
832    \r
833    if(ret==false)\r
834       Print("Error: ",ErrorDescription(orderInfo[OL_ERRORNO][binx]));\r
835       \r
836    return(ret);\r
839 bool OL_orderClose(int binx)\r
841    Print("OL_Close");\r
842    double price;\r
843    bool ret    = false;\r
844    int ticket  = orderInfo[OL_ID][binx];\r
845  \r
846    \r
847    if(orderInfo[OL_ID][binx]<1) \r
848    {\r
849       orderInfo[OL_ERRORNO][binx]=ERR_INVALID_TICKET;\r
850       return (false);\r
851    }\r
853    int start=GetTickCount()& 0x7FFFFFFF;\r
855    color col=CLR_NONE;\r
856    if(OL_ORDER_COLOR)\r
857       col=OL_ORDER_CLOSE_CLR;   \r
860    if(orderInfo[OL_TYPE][binx]==OP_SELL)\r
861    {\r
862       if(orderInfo[OL_CPRICE][binx]==0)\r
863          orderInfo[OL_CPRICE][binx]=NormalizeDouble(Ask,DIGITS);\r
864    }\r
865    else\r
866    {\r
867       if(orderInfo[OL_CPRICE][binx]==0)\r
868          orderInfo[OL_CPRICE][binx]=NormalizeDouble(Bid,DIGITS);   \r
869    }\r
870    \r
871    int loop=1;\r
872    while(loop>=0)\r
873    {\r
874    \r
875       \r
876       ret=OrderClose(ticket,orderInfo[OL_LOTSIZE][binx],orderInfo[OL_CPRICE][binx],orderInfo[OL_SLIPPAGE][binx],col);\r
877    \r
878       orderInfo[OL_ERRORNO][binx]=GetLastError();\r
880       if(loop>0 && ret==false && orderInfo[OL_ERRORNO][binx]!=ERR_INVALID_TICKET && IsTradeBusy(4,100)==false) \r
881       {\r
882          RefreshRates();\r
883       }\r
884       else\r
885          break;\r
886                \r
887       loop--;\r
888    }\r
889    \r
890    if(ret==true /* || orderInfo[OL_ERRORNO][binx]==ERR_INVALID_TICKET */ )\r
891    {\r
892       if(OrderSelect(ticket,SELECT_BY_TICKET)==true)\r
893          orderInfo[OL_CPRICE][binx]=OrderClosePrice();\r
894    }\r
895    else\r
896       Print("Error: ",ErrorDescription(orderInfo[OL_ERRORNO][binx]));\r
898    return(ret);\r
901 bool IsTradeBusy(int retries,int sleep)\r
902 \r
903    while(retries>0)\r
904    {  \r
905       if(IsTradeContextBusy() || !IsTradeAllowed())\r
906       {\r
907          Print("Sleep ",sleep);\r
908          Sleep(sleep);\r
909       }\r
910       else return (false);\r
911       \r
912       retries--;\r
913    }\r
914    Print("Trade Busy");\r
915    return (true);\r
919 void OL_Update(int binx)\r
921    if(orderInfo[OL_ID][binx]==0)\r
922    {\r
923       return;\r
924    }\r
926    // activ order?\r
927    if(orderInfo[OL_ID][binx]>0)\r
928    {           \r
929       if(orderInfo[OL_TYPE][binx]==OP_SELL)\r
930       {\r
931          orderInfo[OL_PROFIT][binx]=NormalizeDouble(orderInfo[OL_OPRICE][binx]-Ask,DIGITS)/POINT;\r
932       }\r
933       else\r
934       {\r
935          orderInfo[OL_PROFIT][binx]=NormalizeDouble(Bid-orderInfo[OL_OPRICE][binx],DIGITS)/POINT;\r
936       }\r
937    \r
938       if(orderInfo[OL_PROFIT][binx] > 0 && orderInfo[OL_PROFIT][binx]>orderInfo[OL_HIPROFIT][binx])\r
939       {\r
941          orderInfo[OL_HIPROFITTIME][binx]=TimeCurrent();\r
942          orderInfo[OL_HIPROFIT][binx]=orderInfo[OL_PROFIT][binx];      \r
943                \r
944       }\r
945       \r
946       if(orderInfo[OL_PROFIT][binx] < 0 && orderInfo[OL_PROFIT][binx] < orderInfo[OL_LOPROFIT][binx])\r
947       {\r
948          orderInfo[OL_LOPROFITTIME][binx]=TimeCurrent();\r
949          orderInfo[OL_LOPROFIT][binx]=orderInfo[OL_PROFIT][binx];\r
950       }\r
951       \r
952       // TRAILINGSTOP UPDATES==================\r
953       if(orderInfo[OL_PROFIT][binx]>0)\r
954       {\r
955          if(orderInfo[OL_TRAILINGSTOP][binx]>0)\r
956          {\r
957                double ask=NormalizeDouble(Ask,DIGITS);\r
958                double bid=NormalizeDouble(Bid,DIGITS);\r
960                if(orderInfo[OL_TYPE][binx]==OP_SELL)\r
961                { \r
962                   if(orderInfo[OL_TRAILING][binx]==0 || ask<orderInfo[OL_TRAILING][binx])\r
963                   {              \r
964                      orderInfo[OL_TRAILING][binx]=ask;\r
965                      orderInfo[OL_STOPLOSS][binx]=NormalizeDouble(ask+(orderInfo[OL_TRAILINGSTOP][binx]*POINT),DIGITS);\r
966                      OL_orderModify(binx);\r
967                   }                   \r
968                }\r
969                else\r
970                {               \r
971                   if(orderInfo[OL_TRAILING][binx]==0 || bid>orderInfo[OL_TRAILING][binx])\r
972                   {\r
973                      orderInfo[OL_TRAILING][binx]=bid;\r
974                      orderInfo[OL_STOPLOSS][binx]=NormalizeDouble(bid-(orderInfo[OL_TRAILINGSTOP][binx]*POINT),DIGITS);\r
975                      OL_orderModify(binx);\r
976                   }                                  \r
977                }\r
978          }\r
979       }\r
982    }\r
984    //active && inactiv orders \r
985    orderInfo[OL_CTIME][binx]=TimeCurrent();   \r
986     \r
987    return;   \r