Author: Maxim Kuznetsov
Price Data Components
Series array that contains close prices for each bar
Orders Execution
Checks for the total of open ordersChecks for the total of closed ordersIt Closes Orders by itself It automatically opens orders when conditions are reached
Miscellaneous
It issuies visual alerts to the screenUses files from the file systemIt reads information from a file
0 Views
0 Downloads
0 Favorites
Jax
ÿþ//+------------------------------------------------------------------+

//|                                                          Jax.mq4 |

//|                                                  Maxim Kuznetsov |

//|                                          https://www.luxtrade.tk |

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

#property copyright "Maxim Kuznetsov"

#property link      "https://www.luxtrade.tk"

#property version   "1.06"

#property description "Trade using all margin. Jax!"

#property strict



string prefix;

string jax_button;

string buy_button;

string sell_button;

string close_button;



/* >B>1@0605<K5 C@>2=8 */

enum ENUM_LEVEL {

   LEVEL_PRICE,   // F5=0 >B:@KB8O (A@54=OO)

   LEVEL_STOPOUT, // AB>?-0CB

   LEVEL_FIASKO,  // ?>;=K9 A;82

   LEVEL_TWICE,   // C42>5=85

   // >=8-65 5A;8 %#",

   LEVEL_JAX_PRICE,

   LEVEL_JAX_STOPOUT,

   LEVEL_JAX_FIASKO,

   LEVEL_JAX_TWICE,

   // 2A53> 2>7<>6=> C@>2=59:

   TOTAL_LEVELS

};



struct TheLevelStyle {

   string name;

   int id;

   int type;

   int width;  // H8@8=0 ;8=88

   int style;  // AB8;L ;8=88

   color clr;  // F25B

};

TheLevelStyle level_styles[TOTAL_LEVELS][2]={

   { { "buy_price",LEVEL_PRICE, OP_BUY, 0 , STYLE_SOLID, clrNONE },{ "sell_price",LEVEL_PRICE, OP_SELL, 0 , STYLE_SOLID, clrNONE } },

   { { "buy_stopout",LEVEL_STOPOUT, OP_BUY, 1 , STYLE_SOLID, clrDarkOrange },{ "sell_stopout",LEVEL_STOPOUT, OP_SELL, 1 , STYLE_SOLID, clrDarkOrange } },

   { { "buy_fiasko",LEVEL_FIASKO, OP_BUY, 2 , STYLE_SOLID, clrDarkOrange },{ "sell_fiasko",LEVEL_FIASKO, OP_SELL, 2 , STYLE_SOLID, clrDarkOrange } },

   { { "buy_twice",LEVEL_TWICE, OP_BUY, 1 , STYLE_SOLID, clrDarkGreen },{ "sell_twice",LEVEL_FIASKO, OP_SELL, 1 , STYLE_SOLID, clrDarkGreen } },

   

   { { "jax_buy_price",LEVEL_JAX_PRICE, OP_BUY, 0 , STYLE_SOLID, clrNONE },{ "jax_sell_price",LEVEL_PRICE, OP_SELL, 0 , STYLE_SOLID, clrNONE } },

   { { "jax_buy_stopout",LEVEL_JAX_STOPOUT, OP_BUY, 1 , STYLE_DOT, clrDarkGray },{ "jax_sell_stopout",LEVEL_JAX_STOPOUT, OP_SELL, 1 , STYLE_DOT, clrDarkGray } },

   { { "jax_buy_fiasko",LEVEL_JAX_FIASKO, OP_BUY, 1 , STYLE_SOLID, clrDarkGray },{ "jax_sell_fiasko",LEVEL_JAX_FIASKO, OP_SELL, 1 , STYLE_SOLID, clrDarkGray } },

   { { "jax_buy_twice",LEVEL_JAX_TWICE, OP_BUY, 1 , STYLE_SOLID, clrDarkGray },{ "jax_sell_twice",LEVEL_JAX_TWICE, OP_SELL, 1 , STYLE_SOLID, clrDarkGray } }

};

sinput int MAGIC=0x112233;

sinput int SLIPPAGE=10;



#include <stdlib.mqh>

//#include <SimpleConfig.mqh>



string BUTTON_FONT="Arial Black";

int BUTTON_FONTSIZE=12;



int total_jax=0;



string JAX_TEXT="Jax";

string TOTAL_JAX_TEXT="Total JAX !";



color JAX_BG=clrLightGray;

color TOTAL_JAX_BG=clrGreen;



color JAX_COLOR=clrBlack;

color TOTAL_JAX_COLOR=clrDarkOrange;



string BUY_TEXT="Buy";

string SELL_TEXT="Sell";

string CLOSE_TEXT="Close";



color BUY_BG=clrLightBlue;

color SELL_BG=clrLightCoral;   

color CLOSE_BG=clrLightGray;



color ON_COLOR=clrDarkGreen;

color OFF_COLOR=clrDarkOrange;



color LOSS_COLOR=clrBrown;

color PROFIT_COLOR=clrDarkGreen;



int BUTTON_WIDTH=100;

int BUTTON_HEIGHT=50;

int PANEL_XDISTANCE=-1;

int PANEL_YDISTANCE=17;

string PANEL_BUYSELL[]={"sell","buy"};



enum BUTTONS {

   BUTTON_JAX,

   BUTTON_BUY,

   BUTTON_SELL,

   BUTTON_CLOSE,

   

   TOTAL_BUTTONS

};

int layout[TOTAL_BUTTONS][2]; // @0A:;04:0 - :>>@48=0BK ?@82O7>: :=>?>:



void ReadConfig()

{

   // config

   Config cfg;

   // read config file

   cfg.ReadFile("jax.config");

   BUTTON_FONT=cfg.Get("button_font",BUTTON_FONT);

   BUTTON_FONTSIZE=(int)cfg.Get("button_fontsize",BUTTON_FONTSIZE);

   

   BUY_TEXT=cfg.Get("buy_text",BUY_TEXT);   

   SELL_TEXT=cfg.Get("sell_text",SELL_TEXT);   

   CLOSE_TEXT=cfg.Get("close_text",CLOSE_TEXT);



   BUY_BG=cfg.Get("buy_bg",BUY_BG);

   SELL_BG=cfg.Get("sell_bg",SELL_BG);

   CLOSE_BG=cfg.Get("close_bg",CLOSE_BG);

   ON_COLOR=cfg.Get("on_color",ON_COLOR);

   OFF_COLOR=cfg.Get("off_color",OFF_COLOR);

   LOSS_COLOR=cfg.Get("loss_color",LOSS_COLOR);

   PROFIT_COLOR=cfg.Get("profit_color",PROFIT_COLOR);   

   

   BUTTON_WIDTH=(int)cfg.Get("button_width",BUTTON_WIDTH);

   BUTTON_HEIGHT=(int)cfg.Get("button_height",BUTTON_HEIGHT);

   PANEL_XDISTANCE=(int)cfg.Get("panel_x",PANEL_XDISTANCE);      

   PANEL_YDISTANCE=(int)cfg.Get("panel_y",PANEL_YDISTANCE);

   if (cfg.Get("first_buy",0)) {

      PANEL_BUYSELL[0]="buy";

      PANEL_BUYSELL[1]="sell";

   } else {

      PANEL_BUYSELL[0]="sell";

      PANEL_BUYSELL[1]="buy";

   }

   for(int i=0;i<TOTAL_LEVELS;i++)

   for(int type=0;type<2;type++)

   {

      level_styles[i][type].style=(int)cfg.Get(level_styles[i][type].name+"_style",level_styles[i][type].style);

      level_styles[i][type].width=(int)cfg.Get(level_styles[i][type].name+"_width",level_styles[i][type].width);

      level_styles[i][type].clr=cfg.Get(level_styles[i][type].name+"_color",level_styles[i][type].clr);

   }

   JAX_TEXT=cfg.Get("jax_text",JAX_TEXT);

   JAX_COLOR=cfg.Get("jax_color",JAX_COLOR);

   JAX_BG=cfg.Get("jax_bg",JAX_BG);

   TOTAL_JAX_TEXT=cfg.Get("total_jax_text",TOTAL_JAX_TEXT);

   TOTAL_JAX_COLOR=cfg.Get("total_jax_color",TOTAL_JAX_COLOR);

   TOTAL_JAX_BG=cfg.Get("total_jax_bg",TOTAL_JAX_BG);

}

int OnInit()

{

   ReadConfig();

   prefix="jax.";

   if (ObjectFind(0,prefix+"jax")!=-1) {

      total_jax=(int)ObjectGetInteger(0,prefix+"jax",OBJPROP_STATE);

   } else {

      total_jax=0;

   }

   ObjectsDeleteAll(0,prefix);

   ChartRedraw();

   jax_button=prefix+"jax";

   buy_button=prefix+"buy";

   sell_button=prefix+"sell";

   close_button=prefix+"close";

   for(int t=0;t<TOTAL_LEVELS;t++) {

      level_styles[t][0].name=prefix+level_styles[t][0].name;

      level_styles[t][1].name=prefix+level_styles[t][1].name;

   }

   DrawPanel();   

   UpdateButtons();

   UpdateProfit();

   ChartRedraw();

   EventSetTimer(1);

   return(INIT_SUCCEEDED);

}





void OnDeinit(const int reason)

{

   if (reason!=REASON_CHARTCHANGE && reason!=REASON_RECOMPILE) ObjectsDeleteAll(0,prefix);

}



void OnTick()

{

   if (IsTesting()) {

      if (ObjectGetInteger(0,jax_button,OBJPROP_STATE)!=total_jax) {

         OnJaxPressed(jax_button);

      }

      if (ObjectGetInteger(0,buy_button,OBJPROP_STATE)!=0) {

         OnBuyPressed(buy_button);

      }

      if (ObjectGetInteger(0,sell_button,OBJPROP_STATE)!=0) {

         OnSellPressed(sell_button);

      }

      if (ObjectGetInteger(0,close_button,OBJPROP_STATE)!=0) {

         OnClosePressed(close_button);

      }

   }

   if (ObjectGetInteger(0,jax_button,OBJPROP_STATE)==1 && AccountFreeMargin()>0) {

      int type=CommonPosition();

      if (type!=-1 && MaxPossibleLot(type)>=MarketInfo(_Symbol,MODE_MINLOT)) {

         if (type==OP_BUY) Buy();

         else Sell();

      }

   }

   UpdateProfit();

   UpdateLevels();

   UpdateButtons();

}

void UpdateLevels()

{

   double prices[TOTAL_LEVELS][2];

   if (CalcLevels(_Symbol,prices)) {

      for(int i=0;i<TOTAL_LEVELS;i++)

      for(int type=0;type<2;type++) {

         if (prices[i][type]==0) {

            if (ObjectFind(0,level_styles[i][type].name)>=0) ObjectDelete(0,level_styles[i][type].name);

         } else {

            Level(level_styles[i][type].name,prices[i][type],level_styles[i][type].style,level_styles[i][type].clr,level_styles[i][type].width);

         }

      }

   }

}

void UpdateButtons()

{

   color buyColor=(color)ObjectGetInteger(0,buy_button,OBJPROP_COLOR);

   color sellColor=(color)ObjectGetInteger(0,sell_button,OBJPROP_COLOR);

   double spread=MarketInfo(_Symbol,MODE_SPREAD);

   double tickValue=MarketInfo(_Symbol,MODE_TICKVALUE);

   double minLots=MarketInfo(_Symbol,MODE_MINLOT);

   double required=tickValue*spread*minLots;

   if ( AccountFreeMargin()>0 ) {

      if ( AccountFreeMarginCheck(_Symbol,OP_BUY,MarketInfo(_Symbol,MODE_MINLOT))>=required) {

         buyColor=ON_COLOR;

      } else {

         buyColor=OFF_COLOR;

      }

      if ( AccountFreeMarginCheck(_Symbol,OP_SELL,MarketInfo(_Symbol,MODE_MINLOT))>required) {

         sellColor=ON_COLOR;

      } else{

         sellColor=OFF_COLOR;

      }

   } else {

      buyColor=OFF_COLOR;

      sellColor=OFF_COLOR;

   }

   if (Color(buy_button)!=buyColor) { Color(buy_button,buyColor); ChartRedraw();}

   if (Color(sell_button)!=sellColor) { Color(sell_button,sellColor); ChartRedraw();}



   if (total_jax==1) {

      Color(jax_button,TOTAL_JAX_COLOR);

      BgColor(jax_button,TOTAL_JAX_BG);

      Text(jax_button,TOTAL_JAX_TEXT);

   } else {

      Color(jax_button,JAX_COLOR);

      BgColor(jax_button,JAX_BG);

      Text(jax_button,JAX_TEXT);

   }

}

void UpdateProfit() 

{

   double profit=AccountEquity()-AccountBalance();

   color oldColor=Color(close_button);

   color newColor=oldColor;

   if (OrdersTotal()!=0) {

      ObjectSetString(0,close_button,OBJPROP_TEXT,StringFormat(CLOSE_TEXT+" %.03f",profit));

      if (profit>0) {

         newColor=PROFIT_COLOR;

      } else {

         newColor=LOSS_COLOR;

      }

      ChartRedraw();

   } else {

      if (oldColor!=clrBlack) {

         ObjectSetString(0,close_button,OBJPROP_TEXT,CLOSE_TEXT);

         ChartRedraw();

      }

      newColor=clrBlack;

   }

   if (newColor!=oldColor) {

      Color(close_button,newColor);

      ChartRedraw();

   }

}

datetime uptime=0;

void OnTimer()

{

   if ((IsTradeAllowed() && TimeLocal()!=uptime) || (TimeLocal()>uptime+4)) {

      UpdateLevels();

      UpdateButtons();

      UpdateProfit();

      uptime=TimeLocal();

   }

}

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

{

   if (id==CHARTEVENT_OBJECT_CLICK) {

      if (sparam==jax_button) {

         OnJaxPressed(sparam);

      } else if (sparam==buy_button) {

         OnBuyPressed(sparam);

      } else if (sparam==sell_button) {

         OnSellPressed(sparam);

      } else if (sparam==close_button) {

         OnClosePressed(sparam);

      }

   } else if (id==CHARTEVENT_OBJECT_DELETE || id == CHARTEVENT_OBJECT_CHANGE) {

      if (StringFind(sparam,prefix)==0) {

         RefreshRates();

         OnTick();

      }

   }

}

void DrawPanel()

{

   int panel_x=0;

   int panel_y=0;

   int corner=CORNER_LEFT_UPPER;

   if (PANEL_XDISTANCE>=0) {

      layout[BUTTON_JAX][0]=PANEL_XDISTANCE;

      layout[BUTTON_SELL][0]=PANEL_XDISTANCE;

      layout[BUTTON_BUY][0]=PANEL_XDISTANCE+BUTTON_WIDTH;

      layout[BUTTON_CLOSE][0]=PANEL_XDISTANCE;

      if (PANEL_YDISTANCE>=0) {

         corner=CORNER_LEFT_UPPER;

      } else {

         corner=CORNER_LEFT_LOWER;

      }

   } else {

      layout[BUTTON_JAX][0]=-PANEL_XDISTANCE+2*BUTTON_WIDTH;

      layout[BUTTON_SELL][0]=-PANEL_XDISTANCE+2*BUTTON_WIDTH;

      layout[BUTTON_BUY][0]=-PANEL_XDISTANCE+BUTTON_WIDTH;

      layout[BUTTON_CLOSE][0]=-PANEL_XDISTANCE+2*BUTTON_WIDTH;

      if (PANEL_YDISTANCE>=0) {

         corner=CORNER_RIGHT_UPPER;

      } else {

         corner=CORNER_RIGHT_LOWER;

      }

   }

   if (PANEL_YDISTANCE>=0) {

      int y=PANEL_YDISTANCE;

      layout[BUTTON_JAX][1]=y;

      y+=+BUTTON_HEIGHT/2;

      layout[BUTTON_SELL][1]=y; //PANEL_YDISTANCE+BUTTON_HEIGHT;

      layout[BUTTON_BUY][1]=y;//PANEL_YDISTANCE+BUTTON_HEIGHT;;

      y+=BUTTON_HEIGHT;

      layout[BUTTON_CLOSE][1]=y;//PANEL_YDISTANCE+BUTTON_HEIGHT*2;

   } else {

      int y=-PANEL_YDISTANCE+BUTTON_HEIGHT;

      layout[BUTTON_CLOSE][1]=y;//-PANEL_YDISTANCE+1*BUTTON_HEIGHT;

      y+=BUTTON_HEIGHT;

      layout[BUTTON_SELL][1]=y;//-PANEL_YDISTANCE+2*BUTTON_HEIGHT;

      layout[BUTTON_BUY][1]=y;//-PANEL_YDISTANCE+2*BUTTON_HEIGHT;

      y+=BUTTON_HEIGHT;

      layout[BUTTON_JAX][1]=y;//-PANEL_YDISTANCE+3*BUTTON_HEIGHT;

   }

   Button(jax_button,""); WH(jax_button,BUTTON_WIDTH*2,BUTTON_HEIGHT/2);

   XY(jax_button,layout[BUTTON_JAX][0],layout[BUTTON_JAX][1]);

   ObjectSetInteger(0,jax_button,OBJPROP_CORNER,corner);



   Button(prefix+PANEL_BUYSELL[0],""); WH(prefix+PANEL_BUYSELL[0],BUTTON_WIDTH,BUTTON_HEIGHT);

   XY(prefix+PANEL_BUYSELL[0],layout[BUTTON_SELL][0],layout[BUTTON_SELL][1]);

   ObjectSetInteger(0,prefix+PANEL_BUYSELL[0],OBJPROP_CORNER,corner);



   Button(prefix+PANEL_BUYSELL[1],""); WH(prefix+PANEL_BUYSELL[1],BUTTON_WIDTH,BUTTON_HEIGHT);

   XY(prefix+PANEL_BUYSELL[1],layout[BUTTON_BUY][0],layout[BUTTON_BUY][1]);

   ObjectSetInteger(0,prefix+PANEL_BUYSELL[1],OBJPROP_CORNER,corner);

   

   Button(close_button,""); WH(close_button,BUTTON_WIDTH*2,BUTTON_HEIGHT);

   XY(close_button,layout[BUTTON_CLOSE][0],layout[BUTTON_CLOSE][1]);

   ObjectSetInteger(0,close_button,OBJPROP_CORNER,corner);

   

   if (total_jax==1) {

      Text(jax_button,TOTAL_JAX_TEXT);

      Color(jax_button,TOTAL_JAX_COLOR); BgColor(jax_button,TOTAL_JAX_BG);

      ObjectSetInteger(0,jax_button,OBJPROP_STATE,1);

   } else {

      Text(jax_button,JAX_TEXT);

      Color(jax_button,JAX_COLOR); BgColor(jax_button,JAX_BG);

      ObjectSetInteger(0,jax_button,OBJPROP_STATE,0);

   }

   

   Text(buy_button,BUY_TEXT);

   Color(buy_button,ON_COLOR); BgColor(buy_button,BUY_BG);

   

   Text(sell_button,SELL_TEXT);

   Color(sell_button,ON_COLOR); BgColor(sell_button,SELL_BG);

   

   Text(close_button,CLOSE_TEXT);

   Color(close_button,clrBlack); BgColor(close_button,CLOSE_BG);

   ChartRedraw();

}

void OnJaxPressed(string obj)

{

   PrintFormat("OnJaxPress total_jax=%d",total_jax);

   total_jax=(int)ObjectGetInteger(0,jax_button,OBJPROP_STATE);

   UpdateButtons();

   PrintFormat("AFTER OnJaxPress total_jax=%d",total_jax);

}



void OnBuyPressed(string obj)

{

   Buy();

   ObjectSetInteger(0,obj,OBJPROP_STATE,0);

}

void OnSellPressed(string obj)

{

   Sell();

   ObjectSetInteger(0,obj,OBJPROP_STATE,0);

}

void OnClosePressed(string obj)

{

   CloseAll();

   ObjectSetInteger(0,obj,OBJPROP_STATE,0);

}

void Buy() {

   CloseAllExcept(_Symbol,OP_BUY);

   double lots=MaxPossibleLot(OP_BUY);

   if (lots>0)

   for(int i=0;i<20 && lots>0; i++,lots-=MarketInfo(_Symbol,MODE_LOTSTEP)) {

      if (MarketOrder(OP_BUY,lots)>=0) break;

   }

}

void Sell() {

   CloseAllExcept(_Symbol,OP_SELL);

   double lots=MaxPossibleLot(OP_SELL);

   if (lots>0)

   for(int i=0;i<20 && lots>0; i++,lots-=MarketInfo(_Symbol,MODE_LOTSTEP)) {

      if (MarketOrder(OP_SELL,lots)>=0) break;

   }

}

void Close() {

   CloseAll();

}

void Color(string obj,color clr)

{

   ObjectSetInteger(0,obj,OBJPROP_COLOR,clr);

}

color Color(string obj)

{

   return (color)ObjectGetInteger(0,obj,OBJPROP_COLOR);

}



void BgColor(string obj,color clr)

{

   ObjectSetInteger(0,obj,OBJPROP_BGCOLOR,clr);

}

void XY(string obj,int x,int y)

{

   ObjectSetInteger(0,obj,OBJPROP_XDISTANCE,x);

   ObjectSetInteger(0,obj,OBJPROP_YDISTANCE,y);

}

void WH(string obj,int w,int h)

{

   ObjectSetInteger(0,obj,OBJPROP_XSIZE,w);

   ObjectSetInteger(0,obj,OBJPROP_YSIZE,h);

}

void FontSize(string obj,int fontsize)

{

   ObjectSetInteger(0,obj,OBJPROP_FONTSIZE,fontsize);

}

void Text(string obj,string text)

{

   ObjectSetString(0,obj,OBJPROP_TEXT,text);

}

string Button(string obj,string text,int x=100,int y=100,int width=200,int height=100) 

{

   if (ObjectType(obj)==OBJ_BUTTON || ObjectCreate(0,obj,OBJ_BUTTON,0,0,0)) {

      ObjectSetInteger(0,obj,OBJPROP_XDISTANCE,x);

      ObjectSetInteger(0,obj,OBJPROP_YDISTANCE,y);

      ObjectSetInteger(0,obj,OBJPROP_XSIZE,width);

      ObjectSetInteger(0,obj,OBJPROP_YSIZE,height);

      ObjectSetInteger(0,obj,OBJPROP_FONTSIZE,BUTTON_FONTSIZE);

      ObjectSetString(0,obj,OBJPROP_TEXT,text);

      ObjectSetString(0,obj,OBJPROP_FONT,BUTTON_FONT);

   }

   return obj;

}

string Level(string obj,double level,int style,color clr,int width)

{

   if (ObjectType(obj)==OBJ_HLINE || ObjectCreate(0,obj,OBJ_HLINE,0,0,0)) {

      ObjectSetDouble(0,obj,OBJPROP_PRICE,level);

      ObjectSetInteger(0,obj,OBJPROP_STYLE,style);

      ObjectSetInteger(0,obj,OBJPROP_COLOR,clr);

      ObjectSetInteger(0,obj,OBJPROP_WIDTH,width);

      ObjectSetInteger(0,obj,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,obj,OBJPROP_SELECTED,false);

      ObjectSetInteger(0,obj,OBJPROP_HIDDEN,true);

   }

   return obj;

}

/// from SimpleTrade.mqh

double MaxPossibleLot(int op)

{

   if (op!=OP_BUY && op!=OP_SELL) return 0;

   double lots;

   double maxLot=MarketInfo(_Symbol,MODE_MAXLOT);

   double lotStep=MarketInfo(_Symbol,MODE_LOTSTEP);

   double req=MarketInfo(_Symbol,MODE_MARGINMAINTENANCE);

   double tickValue=MarketInfo(_Symbol,MODE_TICKVALUE);

   double spread=MarketInfo(_Symbol,MODE_SPREAD);

   

   for(lots=0;lots<=maxLot;lots+=1.0) {

      double ost=AccountFreeMarginCheck(_Symbol,op,lots+1.0);

      if (ost<lots*req || ost<=lots*tickValue*spread || GetLastError()==134) break;

   }

   if (lotStep<=0.1)

   for(;lots<=maxLot;lots+=0.1) {

      double ost=AccountFreeMarginCheck(_Symbol,op,lots+0.1);

      if (ost<lots*req||  ost<=lots*tickValue*spread || GetLastError()==134) break;

   }

   if (lotStep<=0.01)

   for(;lots<=maxLot;lots+=0.01) {

      double ost=AccountFreeMarginCheck(_Symbol,op,lots+0.01);

      if (ost<lots*req ||  ost<=lots*tickValue*spread || GetLastError()==134) break;

   }

   return lots;

}



void CloseAll(int type=-1)

{

   if (type==OP_BUYLIMIT || type==OP_BUYSTOP) type=OP_BUY;

   if (type==OP_SELLLIMIT || type==OP_SELLSTOP) type=OP_SELL;

   for(int pos=OrdersTotal()-1;pos>=0;pos--) {

      if (!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) continue;

      //if (OrderSymbol()!=_Symbol) continue;

      if (OrderMagicNumber()!=MAGIC) continue;

      if (OrderCloseTime()!=0) continue;

      if (type==-1 || type==OrderType()) CloseOrder(OrderTicket());

   }      

}

void CloseAllExcept(string symbol,int type)

{

   for(int pos=OrdersTotal()-1;pos>=0;pos--) {

      if (!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) continue;

      if (OrderMagicNumber()!=MAGIC) continue;

      if (OrderCloseTime()!=0) continue;

      if (OrderSymbol() == symbol && type==OrderType() ) continue;

      CloseOrder(OrderTicket());

   }      

}

bool CloseOrder(int t)

{

   // >B:@K205< >@45@

   if (!IsTradeAllowed()) {

      Alert("IsTradeAllowed(): =04> 70:@KBL >@45@, => B>@3>2;O 70?@5I5=0");

      return false;

   }

   // 5 ?>?KB>: 4;O 70:@KB8O >@45@0

   for(int attempt=0;attempt<5;attempt++) {

      if (!(OrderSelect(t,SELECT_BY_TICKET))) {

         if (attempt) Sleep(50);

         RefreshRates();

         OrdersTotal();

         OrdersHistoryTotal();

         continue;

      }

      if (OrderCloseTime()!=0) {

         // >@45@ C65 70:@K;AO

         return true;

      }

      double lots=OrderLots();

      double bid=MarketInfo(OrderSymbol(),MODE_BID);

      double ask=MarketInfo(OrderSymbol(),MODE_ASK);

      if (!OrderClose(t,lots,OrderType()==OP_BUY?bid:ask,SLIPPAGE)) {

         int err=GetLastError();

         if (attempt==4) {

            Alert("AG5@?0=K ?>?KB:8 70:@KB8O >@45@0");

            return false;

         }

         PrintFormat("H81:0 ?@8 70:@KB88 >@45@0 %d %s",err,ErrorDescription(err));

         if (err==ERR_SERVER_BUSY || err==ERR_SYSTEM_BUSY || err==ERR_BROKER_BUSY || err==ERR_TRADE_CONTEXT_BUSY || err==ERR_REQUOTE || err==ERR_OFF_QUOTES || err==ERR_PRICE_CHANGED || err==ERR_INVALID_PRICE) {

            // 8A?@028<0O >H81:0, <>6=> ?5@5?>2B>@8BL

            if (attempt) Sleep(50);

            RefreshRates();

            continue;

         }

         Alert("58A?@028<0O >H81:0 ?@8 70:@KB88 >@45@0 "+ErrorDescription(err));

         return false;

      } else {

         // =>@<0;L=> 70:@K;8

         return true;

      }

   }

   return false;

}



int MarketOrder(int type,double lots)

{

   int result=-1;

   // ?@>25@:0 4>AB0B>G=>AB8 A@54AB2

   if(AccountFreeMarginCheck(Symbol(),type,lots)<=0 || GetLastError()==ERR_NOT_ENOUGH_MONEY) {

      PrintFormat("AccountFreeMarginCheck(): =54>AB0B>G=> A@54AB 4;O >B:@KB8O >@45@0 %f",lots);

      //ExpertRemove();

      return -1;

   }

   // >B:@K205< >@45@

   if (!IsTradeAllowed()) {

      Alert("IsTradeAllowed(): B>@3>2;O 70?@5I5=0");

      return -1;

   }

   // 5 ?>?KB>: =0 >B:@KB85 >@45@0

   for(int attempt=0;attempt<5;attempt++) {

      if (IsTradeContextBusy()) Sleep(50);

      result=OrderSend(_Symbol,type,lots,type==OP_BUY?Ask:Bid,SLIPPAGE,0,0,"",MAGIC,0);

      if (result>=0) {

         break;

      }

      if (result<0) {

         int err=GetLastError();

         if (attempt==4) {

            Alert("MarketOrder(): AG5@?0=K ?>?KB:8 >B:@KB8O >@45@0");

            return -1;

         }

         

         if (err==ERR_NOT_ENOUGH_MONEY) {

            PrintFormat("OrderSend(): 54>AB0B>G=> A@54AB2 4;O >B:@KB8O >@45@0 %f",lots);

            //ExpertRemove();

            return -1;

         }

         PrintFormat("OrderSend(): H81:0 ?@8 >B:@KB88 >@45@0 %d %s",err,ErrorDescription(err));

         if (err==ERR_SERVER_BUSY || err==ERR_SYSTEM_BUSY || err==ERR_BROKER_BUSY || err==ERR_TRADE_CONTEXT_BUSY || err==ERR_REQUOTE || err==ERR_OFF_QUOTES || err==ERR_PRICE_CHANGED) {

            // 8A?@028<0O >H81:0, <>6=> ?5@5?>2B>@8BL

            if (attempt) Sleep(50);

            RefreshRates();

            continue;

         }

         Alert("MarketOrder(): 58A?@028<0O >H81:0 ?@8 >B:@KB88 >@45@0 "+ErrorDescription(err));

      }

   }

   return result;

}



double NormalizeLots(double lots) 

{

   double minLot=MarketInfo(_Symbol,MODE_MINLOT);

   double maxLot=MarketInfo(_Symbol,MODE_MAXLOT);

   double lotStep=MarketInfo(_Symbol,MODE_LOTSTEP);

   if (lots<=minLot+DBL_EPSILON) return minLot;

   lots=minLot+MathRound((lots-minLot)/lotStep)*lotStep;

   if (lots>=maxLot+DBL_EPSILON) return maxLot;

   return lots;

}

// 25@=CBL B8? >1I59 ?>78F88 OP_BUY|OP_SELL

int CommonPosition(string symbol="")

{

   double lots[2]={0};

   if (symbol=="") symbol=_Symbol;

   for(int pos=OrdersTotal()-1;pos>=0;pos--) {

      if (!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) return false;

      int type=OrderType();

      if (type!=OP_BUY && type!=OP_SELL) continue;

      if (OrderSymbol()!=symbol) continue;

      if (OrderCloseTime()!=0) continue;

      lots[type]+=OrderLots();

   }

   if (lots[OP_BUY]>lots[OP_SELL]) return OP_BUY;

   if (lots[OP_BUY]<lots[OP_SELL]) return OP_SELL;

   return -1;

}

// 2KG8A;5=85 C@>2=59 stop-out,jax-stopout

bool CalcLevels(string symbol,double &levels[TOTAL_LEVELS][2])

{

   // 1. AG8B05< B5:CI85 >1JQ<K 

   double lots[2]={0},profit[2]={0},swap[2]={0},comission[2]={0},weight[2]={0};

   for(int i=0;i<TOTAL_LEVELS;i++) {

      levels[i][OP_BUY]=0;

      levels[i][OP_SELL]=0;

   }

   for(int pos=OrdersTotal()-1;pos>=0;pos--) {

      if (!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) return false;

      if (OrderSymbol()!=symbol) continue;

      if (OrderCloseTime()!=0) continue;

      int type=OrderType();

      if (type!=OP_BUY && type!=OP_SELL) continue;

      lots[type]+=OrderLots();

      weight[type]+=OrderLots()*OrderOpenPrice();

      profit[type]+=OrderProfit();

      swap[type]+=OrderSwap();

      comission[type]+=OrderCommission();

   }

   

   if (lots[OP_BUY]>0) {

      levels[LEVEL_PRICE][OP_BUY]=weight[OP_BUY]/lots[OP_BUY];

      if (lots[OP_BUY]>lots[OP_SELL]) {

         double volume=lots[OP_BUY]-lots[OP_SELL];

         double sliv = AccountEquity() / (MarketInfo(Symbol(), MODE_TICKVALUE) * volume);

         levels[LEVEL_STOPOUT][OP_BUY]=Bid -_Point * sliv * (100.0-AccountStopoutLevel())/100.0;

         levels[LEVEL_FIASKO][OP_BUY]=Bid -_Point * sliv;

         double twice= (AccountBalance()*2-AccountEquity()) / (MarketInfo(Symbol(), MODE_TICKVALUE) * volume);

         levels[LEVEL_TWICE][OP_BUY]=Bid+ _Point * twice;

      }

   }

   if (lots[OP_SELL]>0) {

      levels[LEVEL_PRICE][OP_SELL]=weight[OP_SELL]/lots[OP_SELL];

      if (lots[OP_SELL]>lots[OP_BUY]) {

         double volume=lots[OP_SELL]-lots[OP_BUY];

         double sliv = AccountEquity() / (MarketInfo(Symbol(), MODE_TICKVALUE) * volume);

         levels[LEVEL_STOPOUT][OP_SELL]=Ask+_Point * sliv * (100.0-AccountStopoutLevel())/100.0;

         levels[LEVEL_FIASKO][OP_SELL]=Ask+_Point * sliv;

         double twice= (AccountBalance()*2-AccountEquity()) / (MarketInfo(Symbol(), MODE_TICKVALUE) * volume);

         levels[LEVEL_TWICE][OP_SELL]=Ask-_Point * twice;

      }

   }

   double spreadprice=MarketInfo(_Symbol,MODE_SPREAD)*MarketInfo(_Symbol,MODE_TICKVALUE);

   double jax= (AccountMargin()+AccountFreeMargin()-spreadprice)/(MathMax(MarketInfo(_Symbol,MODE_MARGINREQUIRED),MarketInfo(_Symbol,MODE_MARGINMAINTENANCE)));

   double sliv = AccountEquity() / (MarketInfo(Symbol(), MODE_TICKVALUE) * jax);

   double twice= (AccountBalance()*2-AccountEquity()) / (MarketInfo(Symbol(), MODE_TICKVALUE) * jax);

   levels[LEVEL_JAX_STOPOUT][OP_BUY]=Bid -_Point * sliv * (100.0-AccountStopoutLevel())/100.0;

   levels[LEVEL_JAX_STOPOUT][OP_SELL]=Ask+ _Point * sliv * (100.0-AccountStopoutLevel())/100.0;

   levels[LEVEL_JAX_TWICE][OP_BUY]= Bid + _Point * twice;

   levels[LEVEL_JAX_TWICE][OP_SELL]=Ask - _Point * twice;

   

   return true;

}



/////////// 

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

//|                                                 SimpleConfig.mqh |

//|                                                  Maxim Kuznetsov |

//|                                          https://www.luxtrade.tk |

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





class Config {

public:

   Config();

   ~Config();

   bool Set(string key,string value);

   bool Set(string key,double value);

   bool Set(string key,long value);

   bool Set(string key,color value);

   

   string Get(string key,string dfl);

   double Get(string key,double dfl);

   long Get(string key,long dfl);

   color Get(string key,color dfl);

   

   bool ReadText(string content);

   bool ReadFile(string filename,bool common=false);

   int Total();

   int Names(string &out[]);

   void Clear();

protected:

   int Find(string key);

   bool ParseOne(string s);

   string kv[];   

};

Config::Config(void)

{

   ArrayResize(kv,0,16);

}

Config::~Config()

{

}

int Config::Find(string key)

{

   key=StringTrimLeft(StringTrimRight(key));

   StringToLower(key);

   

   for(int pos=ArraySize(kv)-2;pos>=0;pos-=2) {

      if (StringCompare(kv[pos],key,false)==0) return pos;

   }

   return -1;

}

bool Config::Set(string key,string value)

{

   key=StringTrimLeft(StringTrimRight(key));

   StringToLower(key);

   

   int pos=Find(key);

   if (pos<0) {

      pos=ArraySize(kv);

      if (ArrayResize(kv,pos+2)!=pos+2) {

         return false;

      }

      kv[pos]=StringTrimLeft(StringTrimRight(key));

   }

   kv[pos+1]=value;

   return true;

}

bool Config::Set(string key,double value) 

{

   return Set(key,DoubleToString(value));

}

bool Config::Set(string key,long value)

{

   return Set(key,IntegerToString(value));

}

bool Config::Set(string key,color clr)

{

   string value=ColorToString(clr,true);

   return Set(key,value);

}



string Config::Get(string key,string dfl)

{

   int pos=Find(key);

   if (pos<0) return dfl;

   return kv[pos+1];

}

double Config::Get(string key,double dfl)

{

   int pos=Find(key);

   if (pos<0) return dfl;

   return StringToDouble(kv[pos+1]);

}

long Config::Get(string key,long dfl)

{

   int pos=Find(key);

   if (pos<0) return dfl;

   return StringToInteger(kv[pos+1]);

}

color Config::Get(string key,color dfl)

{

   int pos=Find(key);

   if (pos<0) return dfl;

   return StringToColor(kv[pos+1]);

}



bool Config::ParseOne(string s)

{

   s=StringTrimLeft(StringTrimRight(s));

   if (StringGetChar(s,0)=='#') return false;

   if (StringGetChar(s,0)=='/' && StringGetChar(s,1)=='/') return false;

   if (StringGetChar(s,0)=='-' && StringGetChar(s,1)=='-') return false;

   if (StringGetChar(s,0)=='=' && StringGetChar(s,1)=='=') return false;

   if (StringGetChar(s,0)=='*' && StringGetChar(s,1)=='*') return false;

   int delim=-1;  // ?>78F8O @0745;8B5;O

   // @0745;8B5;8, ?> ?@8>@8B5BC = : ?@>15;

   int tmp=StringFind(s,"=");

   if (tmp>0) delim=tmp;

   tmp=StringFind(s,":");

   if (tmp>0 && tmp<delim) 

      delim=tmp;

   if (delim==-1) {

      tmp=StringFind(s," ");

      if (tmp>0)

         delim=tmp;

   }   

   if (delim<=0) return false;

   string key=StringTrimLeft(StringTrimRight(StringSubstr(s,0,delim)));

   string value=StringTrimLeft(StringTrimRight(StringSubstr(s,delim+1)));

   

   if (StringLen(key)==0) return false;

   if (StringLen(value)==0) value="1";

   return Set(key,value);   

}

bool Config::ReadText(string text)

{

   string tt[];

   int total=StringSplit(text,'\n',tt);

   for(int c=0;c<total;c++)

      ParseOne(tt[c]);

   return true;   

}

bool Config::ReadFile(string filename,bool common)

{

   int f = FileOpen(filename,FILE_READ|FILE_TXT|(common?FILE_COMMON:0));

   if (f==INVALID_HANDLE) return false;

   while(!FileIsEnding(f)) {

      string s=FileReadString(f);

      ParseOne(s);

   }

   FileClose(f);

   return true;

}

int Config::Total()

{

   return ArraySize(kv)/2;

}

int Config::Names(string &out[])

{

   int total=Total();

   ArrayResize(out,total);

   for(int c=0;c<total;c++)

      out[c]=kv[c*2];

   return total;   

}

void Config::Clear()

{

   ArrayResize(kv,0);

}

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