//+------------------------------------------------------------------+ //| adxpsar_v4.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| adxpsar_v4.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ADXPSAR_MCEA.mq5 | //| Copyright 2023, Roberto Jacobs (3rjfx) ~ Date: 2023-07-13 | //| https://www.mql5.com/en/users/3rjfx | //+------------------------------------------------------------------+ /** * aqui eh o tutorial oficial deste robo => * Criando um Expert Advisor simples multimoeda usando MQL5 (Parte 1): * Sinais baseados no ADX em combinação com o Parabolic SAR * https://www.mql5.com/pt/articles/13008 * * este projeto aqui eh relacionado a um tutorial de como criar um robo no MT5 * que ultilize uma combinacao de indicadores de analise grafica * 1.grafico com indicador ADX * 2.grafico com indicador Parabolic SAR * estes dois indicadores de analise grafica sao ultilizados em conjuntos para * trades, eu nao conheco nao tenho ideia de como funcionam eles, precisaria ao menos * de uma ideia de como eles fazem o gatilho de entrada como funciona este setup, * agora estos fazendo back-testes na ferramenta pra entender o nivel de assertividade; * * ############################### * #Detalhes sobre esta versao v4# * ############################### * este projeto se refere a versao 4 deste robozinho, que pegamos em um tutorial, * estamos em fase de aprendizado da linguagem MQL5, estamos lendo, fazendo debuggers * lendo o livro oficial, compilando e rodando os back-testes para testar e entender * ateh onde este robozinho pode nos ajudar e tentando aprender como toda a plataforma * funciona para quem sabe um dia agente seja um expert em criação de robos no MT; * * Na versao v2, agente apenas pegou o codigo fonte original, para que nao mechesse agente * criou um projeto v2 apenas para que pudessimos compilar e rodar do jeito que ele estava, * pode ate ser que agente mude alguma coisa no codigo fonte porem ali eu quero apenas executar * nos back-testes automatizados para que eu consiga compreender como ele funciona como eh o * comportamento do robo na sua originalidade; * * porque estamos criando agora esta versao v4??? * simplesmente pelo motivo que eu acredito que seja impossivel ser lucrativo no mercado mesmo * que seja usando robos, mas abrindo muitas boletagens ao mesmo tempo em diversos ativos * aleatorios, eu nao acredito nisto nao acho isto legal nem lucrativo porque ja tentei fazer * isto em trade manual em futuros e eh dificil acompanhar tudo, e as vezes o q vc ja lucrou * em um ativo vc devolve o dobrou ou triplo em outros entao nao acredito que seja lucrativo; * Eu gostaria de criar uma versao que apenas ultilize o AUD/USD, para que agente teste ele * e veja se apenas usando um par de Forex agente consiga uma boa oportunidade; * Entao resumindo esta versao V4 sera uma refatoração para que o robozinho apenas ultilize * o par AUD/USD, vamos ver no que vai dar kkk * */ #property copyright "Copyright 2023, Roberto Jacobs (3rjfx) ~ Date: 2023-07-13" #property link "https://www.mql5.com/en/users/3rjfx" #property version "1.00" #property strict #property description "The Expert ADXPSAR_MCEA is the Automated Trading Multi Currency Forex Expert Advisor for MetaTrader 5" #property description "by using a combination of ADX and Parabolic SAR SAR indicators which trade Multiple Pairs in one Chart." #property description "esta eh a versao v4-debugger ultilizando H1" #property description "nesta versao vamos tentar remover esta caracteristica deste robo ser multimoeda" #property description "pois ateh mesmo quando agente vai tentar fazer um back-test quando o MT5 começa" #property description "a coletar dados historicos para começar a trabalhar, ele consome todo espaço em disco" #property description "do computador, vamos tentar deixar este robo especialista em AUD/USD;" //#property icon "\\Images\\ADXPSAR_MCEA.ico"; //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include #include #include #include CTrade mc_trade; CSymbolInfo mc_symbol; CPositionInfo mc_position; CAccountInfo mc_account; enum YN { No, Yes }; enum mmt { FixedLot, // Fixed Lot Size DynamLot // Dynamic Lot Size }; enum TFX { TFH1, // PERIOD_H1 TFH2, // PERIOD_H2 TFH3, // PERIOD_H3 TFH4, // PERIOD_H4 TFH6, // PERIOD_H6 TFH8, // PERIOD_H8 TFH12, // PERIOD_H12 TFD1 // PERIOD_D1 }; input group "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter input TFX TimeFrames = TFH1; // Select Expert TimeFrame, default PERIOD_H1 input int ADXPeriod = 7; // Input ADX Period input group "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter input mmt mmlot = DynamLot; // Money Management Type input double Risk = 10.0; // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%) input double Lots = 0.01; // Input Manual Lot Size FixedLot //--Day Trading On/Off input group "=== Day Trading On/Off ==="; // Day Trading On/Off input YN ttd0 = Yes; // Select Trading on Sunday (Yes) or (No) input YN ttd1 = Yes; // Select Trading on Monday (Yes) or (No) input YN ttd2 = Yes; // Select Trading on Tuesday (Yes) or (No) input YN ttd3 = Yes; // Select Trading on Wednesday (Yes) or (No) input YN ttd4 = Yes; // Select Trading on Thursday (Yes) or (No) input YN ttd5 = Yes; // Select Trading on Friday (Yes) or (No) input YN ttd6 = No; // Select Trading on Saturday (Yes) or (No) //--Trade & Order management Parameter input group "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter input YN use_sl = No; // Use Order Stop Loss (Yes) or (No) input YN autosl = Yes; // Use Automatic Calculation Stop Loss (Yes) or (No) input double SLval = 30; // If Not Use Automatic SL - Input SL value in Pips input YN use_tp = No; // Use Order Take Profit (Yes) or (No) input YN autotp = Yes; // Use Automatic Calculation Take Profit (Yes) or (No) input double TPval = 50; // If Not Use Automatic TP - Input TP value in Pips input YN TrailingSLTP = Yes; // Use Trailing SL/TP (Yes) or (No) input YN autotrl = No; // Use Automatic Trailing (Yes) or (No) input double TSval = 5; // If Not Use Automatic Trailing Input Trailing value in Pips input double TSmin = 5; // Minimum Pips to start Trailing Stop input YN Close_by_Opps = Yes; // Close Trade By Opposite Signal (Yes) or (No) input YN SaveOnRev = Yes; // Close Trade and Save profit due to weak signal (Yes) or (No) //--Others Expert Advisor Parameter input group "=== Others Expert Advisor Parameter ==="; // Others EA Parameter input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No) input YN UseEmailAlert = No; // Email Alert (Yes) or (No) input YN UseSendnotify = Yes; // Send Notification (Yes) or (No) input YN trade_info_display = Yes; // Select Display Trading Info on Chart (Yes) or (No) input ulong magicEA = 202307; // Expert ID (Magic Number) //+------------------------------------------------------------------+ //| Class for working Expert Advisor | //+------------------------------------------------------------------+ class MCEA { private: int x_year, // Year x_mon, // Month x_day, // Day of the month x_hour, // Hour in a day x_min, // Minutes x_sec, // Seconds oBm, oSm, ldig, posCur1, posCur2; double LotPS, difDi, slv, tpv, pip, xpip, floatprofit, fixclprofit, ADXDIp[], ADXDIm[], OPEN[], HIGH[], LOW[], CLOSE[]; string pairs, hariini, daytrade, trade_mode; datetime TIME[], closetime; int iADXCross(const string symbol); int iADXpct(const string symbol,const int index); int PARSAR05(const string symbol); int PARSAR15(const string symbol); int PARSAROp(const string symbol); int LotDig(const string symbol); double MLots(const string symbx); double NonZeroDiv(double val1,double val2); double OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice); double SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice); double TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type); string ReqDate(int d,int h,int m); string TF2Str(ENUM_TIMEFRAMES period); string timehr(int hr,int mn); string TradingDay(void); string AccountMode(); string GetCommentForOrder(void) { return(expname); } public: //-- ADXPSAR_MCEA Config -- int Buy, Sell, ccur, psec, xtto, checktml, OpOr[], xob[], xos[], year, // Year mon, // Month day, // Day hour, // Hour min, // Minutes sec, // Seconds dow, // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) doy, // Day number of the year (January 1st is assigned the number value of zero) handADX[], hParOp[], hPar15[], hPar05[], ALO, dgts, arrsymbx, sall, arper; string DIRI[], AS30[], expname; ulong slip; ENUM_TIMEFRAMES TFt, TFT15, TFT05; double SARstep, SARmaxi, profitb[], profits[]; bool PanelExtra; /** precisamos entender o q significa isto aqui, se eh alguma declaracao ou invocacao simplesmente uma chamada pq ela esta aqui no meio das declaracoes das propriedades da classe MCEA(); */ MCEA(void); ~MCEA(void); /** o q eh virtual void??? */ virtual void ADXPSAR_MCEA_Config(void); virtual void ExpertActionTrade(void); void ArraySymbolResize(void); void CurrentSymbolSet(const string symbol); void Pips(const string symbol); void TradeInfo(void); void Do_Alerts(const string symbx,string msgText); void CheckOpenPMx(const string symbx); void SetSLTPOrders(void); void CloseBuyPositions(const string symbol); void CloseSellPositions(const string symbol); void CloseAllOrders(void); void CheckClose(const string symbx); void TodayOrders(void); void UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf); void RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars); bool RefreshTick(const string symbx); bool TradingToday(void); bool OpenBuy(const string symbol); bool OpenSell(const string symbol); bool ModifyOrderSLTP(double mStop,double ordtp); bool ModifySLTP(const string symbx,int TS_type); bool CloseAllProfit(void); bool ManualCloseAllProfit(void); int PairsIdxArray(const string symbol); int GetOpenPosition(const string symbol); int DirectionMove(const string symbol); int GetCloseInWeakSignal(const string symbol,int exis); int CheckToCloseInWeakSignal(const string symbol,int exis); int ThisTime(const int reqmode); string getUninitReasonText(int reasonCode); }; //-end class MCEA /** * aqui eh uma instancia da classe criada acima eh a classe principal para o * robozinho, mc eh a variavel da instancia que representa esta classe; */ MCEA mc; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ MCEA::MCEA(void): x_year(0), x_mon(0), x_day(0), x_hour(0), x_min(0), x_sec(0), year(0), mon(1), day(2), hour(3), min(4), sec(5), dow(6), doy(7), psec(0), Buy(1), Sell(-1), slip(16), arper(25), checktml(0), difDi(0.34), SARstep(0.02), SARmaxi(0.2), TFT05(PERIOD_M5), TFT15(PERIOD_M15), expname("ADXPSAR_MCEA-v4 robo para AUD/USD - M15"), closetime(TimeCurrent()) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ MCEA::~MCEA(void) { } //+------------------------------------------------------------------+ //| Expert Configuration | //+------------------------------------------------------------------+ void MCEA::ADXPSAR_MCEA_Config(void) { /** * array original onde tem todos os pares usados pelo robo para realizar as operacoes * ele executa operacoes nos 30 pares de moedas, eu mesmo acredito que isto eh um absurdo * porque eu nao quero acreditar que existe uma soh estrategia que funcione para todos * os ativos existentes, ateh porque cada ativo eh unico, cada ativo funciona de uma * maneira unica se comporta de maneira unica a velocidade de movimentação de cada uma * funciona de um jeito muito particular, duvido muito que uma soh estrategia funcione para * todos os ativos existentes, entao nossa estrategia neste v4 seria especializar este * robozinho apenas para o ativo AUD/USD, apenas este ativo de forex que eu quero trabalhar * e de preferencia em timeframes menores como M5 ou M15, eu acho que robos com tempos * maiores nao sei se seria assertivo, e gostaria que fosse scalper; * * entao vamos manter em originalidade este array abaixo nesta refatoracao porem vamos * manter o nome dela para nao ter problema no funcionamento; * * string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP", * "EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD", * "GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF", * "NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs */ string All30[] = {"AUDUSD"}; /* obtem a quantidade total de todos os arrays, agora retornara apenas 1 */ sall=ArraySize(All30); /** * A função define um tamanho novo para a primeira dimensão * int ArrayResize( * void& array[], // array passado por referência * int new_size, // novo tamanho de array * int reserve_size=0 // valor do tamanho de reserva (excesso) * ); */ ArrayResize(AS30,sall,sall); /** * Copia um array em um outro array. * * int ArrayCopy( * void& dst_array[], // array de destino * const void& src_array[], // array de origem * int dst_start=0, // índice de início do array destino a partir do qual se escreve * int src_start=0, // primeiro índice de um array de origem * int count=WHOLE_ARRAY // número de elementos * ); * */ ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY); arrsymbx=sall; /** * chamada da function que limpa algumas variaveis de array, * da resize nas mesmas na sequencia e depois seta alguns arrays como series; */ ArraySymbolResize(); //faz copia de array de um para outro ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY); /** * neste for ele usa uma variavel de array q eh uma copia daquele array que contem * todos os pares que no original seriam 30, ele diz para o MT5 que ira dar foco para * aquele par de forex naquele grafico; * no nosso caso ele precisa abrir somente para o AUD/USD; * Selects a symbol in the Market Watch window or removes a symbol from the window. * * bool SymbolSelect( * string name, // symbol name * bool select // add or remove * ); */ for(int x=0; xarrsymbx ? arrsymbx : (int)mc_account.LimitOrders(); //faz o parser de integer para double para atribuir em outra variavel LotPS=(double)ALO; mc_trade.SetExpertMagicNumber(magicEA); mc_trade.SetDeviationInPoints(slip); mc_trade.SetMarginMode(); return; } //-end ADXPSAR_MCEA_Config() //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { Print("inicializando OnInit(); function;"); mc.ADXPSAR_MCEA_Config(); return(INIT_SUCCEEDED); } //-end OnInit() //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("inicializando OnInit(); function;"); Comment("inicializando OnDeinit(); function;"); //-- Release all handle indicators for all symbols for(int x=0; x0) mc.CloseSellPositions(symbol); if(mc.xob[x]==0 && mc.xtto=mc.ALO) { //-- mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); //-- mc.CheckOpenPMx(symbol); //-- if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0) {mc.CloseSellPositions(symbol); mc.OpenBuy(symbol);} else if(SaveOnRev==Yes) mc.CloseAllProfit(); } } //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Sell" (value=-1) if(mc.OpOr[x]==mc.Sell) { mc.CheckOpenPMx(symbol); if(Close_by_Opps==Yes && mc.xob[x]>0) mc.CloseBuyPositions(symbol); if(mc.xos[x]==0 && mc.xtto=mc.ALO) { mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+ "\n the limit = "+string(mc.ALO)+" Orders "); mc.CheckOpenPMx(symbol); if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0) { mc.CloseBuyPositions(symbol); mc.OpenSell(symbol); } else if(SaveOnRev==Yes) { mc.CloseAllProfit(); } } } mc.CheckOpenPMx(symbol); if(mc.xob[x]>0 && mc.CheckToCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) {mc.CloseBuyPositions(symbol); mc.OpenSell(symbol);} if(mc.xos[x]>0 && mc.CheckToCloseInWeakSignal(symbol,mc.Sell)==mc.Buy) {mc.CloseSellPositions(symbol); mc.OpenBuy(symbol);} } if(mc.xtto>0) { //-- Close Trade and Save profit due to weak signal (Yes) if(SaveOnRev==Yes) { mc.CheckOpenPMx(symbol); if(mc.profitb[x]>0.02 && mc.xob[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) { mc.CloseBuyPositions(symbol); mc.Do_Alerts(symbol,"Close BUY order "+symbol+" to save profit due to weak signal."); } if(mc.profits[x]>0.02 && mc.xos[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Sell)==mc.Buy) { mc.CloseSellPositions(symbol); mc.Do_Alerts(symbol,"Close SELL order "+symbol+" to save profit due to weak signal."); } if(mc.xob[x]>0 && mc.CheckToCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) mc.CloseBuyPositions(symbol); if(mc.xos[x]>0 && mc.CheckToCloseInWeakSignal(symbol,mc.Sell)==mc.Buy) mc.CloseSellPositions(symbol); } //-- Use Trailing SL/TP (Yes) if(TrailingSLTP==Yes) { if(autotrl==Yes) mc.ModifySLTP(symbol,1); //-- If Use Automatic Trailing (Yes) if(autotrl==No) mc.ModifySLTP(symbol,0); //-- Use Automatic Trailing (No) } } mc.CheckClose(symbol); } mc.psec=mc.ccur; } return; } //-end ExpertActionTrade() int MCEA::PairsIdxArray(const string symbol) { int pidx=0; for(int x=0; xOPEN[0]+difud) ret=rise; if(CLOSE[0]answer2) mv=rise; if(answer1ADXDIm[1]+difDi && ADXDIp[0]>ADXDIp[1] && GiADXc==rise); bool gadxdown=(ADXDIp[2]>=ADXDIm[2] && ADXDIp[1]ADXDIm[0] && GiADXp==down); bool gadxdownR=(ADXDIp[0]HIG0) ret=down; return(ret); } //-end PARSAROp() // formula Parabolic SAR M5 int MCEA::PARSAR05(const string symbol) { int ret=0, rise=1, down=-1, br=2; double PSAR[]; ArrayResize(PSAR,br,br); ArraySetAsSeries(PSAR,true); int xx=PairsIdxArray(symbol); CopyBuffer(hPar05[xx],0,0,br,PSAR); RefreshPrice(symbol,TFT05,br); double HIG0=iHigh(symbol,TFT05,0); double LOW0=iLow(symbol,TFT05,0); if(PSAR[0]HIG0) ret=down; return(ret); } //-end PARSAR05() // formula Parabolic SAR M15 int MCEA::PARSAR15(const string symbol) { int ret=0, rise=1, down=-1, br=2; double PSAR[]; ArrayResize(PSAR,br,br); ArraySetAsSeries(PSAR,true); int xx=PairsIdxArray(symbol); CopyBuffer(hPar15[xx],0,0,br,PSAR); RefreshPrice(symbol,TFT15,br); double HIG0=iHigh(symbol,TFT15,0); double LOW0=iLow(symbol,TFT15,0); if(PSAR[0]HIG0) ret=down; return(ret); } //-end PARSAR15() bool MCEA::OpenBuy(const string symbol) { ResetLastError(); bool buyopen = false; string ldComm = GetCommentForOrder()+"_Buy"; double ldLot = MLots(symbol); ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY; MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; ZeroMemory(req); ZeroMemory(res); ZeroMemory(check); CurrentSymbolSet(symbol); double SL=OrderSLSet(symbol,type_req,mc_symbol.Bid()); double TP=OrderTPSet(symbol,type_req,mc_symbol.Ask()); if(RefreshTick(symbol)) buyopen=mc_trade.Buy(ldLot,symbol,mc_symbol.Ask(),SL,TP,ldComm); int error=GetLastError(); if(buyopen||error==0) { string bsopen="Open BUY Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!"; Do_Alerts(symbol,bsopen); } else { mc_trade.CheckResult(check); Do_Alerts(Symbol(),"Open BUY order for "+symbol+" FAILED!!. Return code= "+ (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]"); return(false); } return(buyopen); } //-end OpenBuy bool MCEA::OpenSell(const string symbol) { ResetLastError(); bool selopen = false; string sdComm = GetCommentForOrder()+"_Sell"; double sdLot = MLots(symbol); ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL; MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; ZeroMemory(req); ZeroMemory(res); ZeroMemory(check); CurrentSymbolSet(symbol); double SL=OrderSLSet(symbol,type_req,mc_symbol.Ask()); double TP=OrderTPSet(symbol,type_req,mc_symbol.Bid()); if(RefreshTick(symbol)) selopen=mc_trade.Sell(sdLot,symbol,mc_symbol.Bid(),SL,TP,sdComm); int error=GetLastError(); if(selopen||error==0) { string bsopen="Open SELL Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!"; Do_Alerts(symbol,bsopen); } else { mc_trade.CheckResult(check); Do_Alerts(Symbol(),"Open SELL order for "+symbol+" FAILED!!. Return code= "+ (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]"); return(false); } return(selopen); } //-end OpenSell double MCEA::OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice) { slv=0.0; int x=PairsIdxArray(xsymb); Pips(xsymb); RefreshTick(xsymb); switch(type) { case (ORDER_TYPE_BUY): { if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice-38*pip); else if(use_sl==Yes && autosl==No) slv=mc_symbol.NormalizePrice(atprice-SLval*pip); else slv=0.0; break; } case (ORDER_TYPE_SELL): { if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice+38*pip); else if(use_sl==Yes && autosl==No) slv=mc_symbol.NormalizePrice(atprice+SLval*pip); else slv=0.0; } } return(slv); } //-end OrderSLSet() double MCEA::OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice) { tpv=0.0; int x=PairsIdxArray(xsymb); Pips(xsymb); RefreshTick(xsymb); switch(type) { case (ORDER_TYPE_BUY): { if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice+50*pip); else if(use_tp==Yes && autotp==No) tpv=mc_symbol.NormalizePrice(atprice+TPval*pip); else tpv=0.0; //-- break; } case (ORDER_TYPE_SELL): { if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice-50*pip); else if(use_tp==Yes && autotp==No) tpv=mc_symbol.NormalizePrice(atprice-TPval*pip); else tpv=0.0; } } return(tpv); } //-end OrderTPSet() //-- function: CheckOpenTrade void MCEA::CheckOpenPMx(const string symbx) { int totalorder=PositionsTotal(), xi=PairsIdxArray(symbx); xtto=totalorder; xob[xi]=0; xos[xi]=0; profitb[xi]=0; profits[xi]=0; double pos_profit = 0.0, pos_swap = 0.0, pos_comm = 0.0; for(int i=0; iiHigh(xsymb,TFt,0))) pval=PSAR[0]; break; } } return(pval); } //-end TSPrice() bool MCEA::ModifySLTP(const string symbx,int TS_type) { ResetLastError(); MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; int TRSP=TS_type; bool modist=false; int x=PairsIdxArray(symbx); Pips(symbx); int total=PositionsTotal(); for(int i=total-1; i>=0; i--) { string symbol=PositionGetSymbol(i); if(symbol==symbx && mc_position.Magic()==magicEA) { ENUM_POSITION_TYPE opstype = mc_position.PositionType(); if(opstype==POSITION_TYPE_BUY) { RefreshTick(symbol); double price = mc_position.PriceCurrent(), vtrsb = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP)), pos_open = mc_position.PriceOpen(), pos_stop = mc_position.StopLoss(), pos_profit = mc_position.Profit(), pos_swap = mc_position.Swap(), pos_comm = mc_position.Commission(), netp=pos_profit+pos_swap+pos_comm, modstart=mc_symbol.NormalizePrice(pos_open+TSmin*pip), modminsl=mc_symbol.NormalizePrice(vtrsb+TSmin*pip), modbuysl=vtrsb, modbuytp=mc_symbol.NormalizePrice(price+TPval*pip); bool modbuy = (price>modminsl && modbuysl>modstart && (pos_stop==0.0||modbuysl>pos_stop)); if(modbuy && netp > 0.05) { modist=mc_trade.PositionModify(symbol,modbuysl,modbuytp); } } if(opstype==POSITION_TYPE_SELL) { RefreshTick(symbol); double price = mc_position.PriceCurrent(), vtrss = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP)), pos_open = mc_position.PriceOpen(), pos_stop = mc_position.StopLoss(), pos_profit = mc_position.Profit(), pos_swap = mc_position.Swap(), pos_comm = mc_position.Commission(), netp=pos_profit+pos_swap+pos_comm, modstart=mc_symbol.NormalizePrice(pos_open-TSmin*pip), modminsl=mc_symbol.NormalizePrice(vtrss-TSmin*pip), modselsl=vtrss, modseltp=mc_symbol.NormalizePrice(price-TPval*pip); bool modsel = (price0.05) { modist=mc_trade.PositionModify(symbol,modselsl,modseltp); } } } } return(modist); } //-end ModifySLTP() void MCEA::SetSLTPOrders(void) { ResetLastError(); MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; double modbuysl=0; double modselsl=0; double modbuytp=0; double modseltp=0; string position_symbol; int totalorder=PositionsTotal(); for(int i=totalorder-1; i>=0; i--) { string symbol=PositionGetSymbol(i); position_symbol=symbol; if(mc_position.Magic()==magicEA) { ENUM_POSITION_TYPE opstype = mc_position.PositionType(); if(opstype==POSITION_TYPE_BUY) { Pips(symbol); RefreshTick(symbol); double price = mc_position.PriceCurrent(), pos_open = mc_position.PriceOpen(), pos_stop = mc_position.StopLoss(), pos_take = mc_position.TakeProfit(); modbuysl=SetOrderSL(symbol,opstype,pos_open); if(pricemodbuytp) modbuytp=mc_symbol.NormalizePrice(price+slip*pip); if(pos_stop==0.0 || pos_take==0.0) { if(!mc_trade.PositionModify(position_symbol,modbuysl,modbuytp)) { mc_trade.CheckResult(check); Do_Alerts(symbol,"Set SL and TP for "+EnumToString(opstype)+" on "+symbol+" FAILED!!. Return code= "+ (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]"); } } } if(opstype==POSITION_TYPE_SELL) { Pips(symbol); RefreshTick(symbol); double price = mc_position.PriceCurrent(), pos_open = mc_position.PriceOpen(), pos_stop = mc_position.StopLoss(), pos_take = mc_position.TakeProfit(); modselsl=SetOrderSL(symbol,opstype,pos_open); if(price>modselsl) modselsl=mc_symbol.NormalizePrice(price+slip*pip); modseltp=SetOrderTP(symbol,opstype,pos_open); if(price=0; i--) { if(mc_position.SelectByIndex(i)) { //--- Parameters of the order string position_Symbol = PositionGetSymbol(i); ulong position_ticket = PositionGetTicket(i); ENUM_POSITION_TYPE type = mc_position.PositionType(); //--- if the MagicNumber matches if((position_Symbol==symbol) && (mc_position.Magic()==magicEA)) { if(type==closetype) { RefreshTick(position_Symbol); bool buyclose=mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close Buy #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } } } } return; } //-end CloseBuyPositions() void MCEA::CloseSellPositions(const string symbol) { ResetLastError(); int total=PositionsTotal(); // number of open positions ENUM_POSITION_TYPE closetype = POSITION_TYPE_SELL; ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY; MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; //--- iterate over all open positions for(int i=total-1; i>=0; i--) { if(mc_position.SelectByIndex(i)) { //--- Parameters of the order string position_Symbol = PositionGetSymbol(i); ulong position_ticket = PositionGetTicket(i); ENUM_POSITION_TYPE type = mc_position.PositionType(); //--- if the MagicNumber matches if((position_Symbol==symbol) && (mc_position.Magic()==magicEA)) { if(type==closetype) { RefreshTick(position_Symbol); bool sellclose=mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close Sell #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } } } } return; } //-end CloseSellPositions() bool MCEA::CloseAllProfit(void) { ResetLastError(); int up=1, dw=-1; bool orclose=false; MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; int ttlorder=PositionsTotal(); // number of open positions for(int x=0; x=0; i--) { string position_Symbol = PositionGetSymbol(i); ENUM_POSITION_TYPE type = mc_position.PositionType(); if((position_Symbol==symbol) && (mc_position.Magic()==magicEA)) { double pos_profit = mc_position.Profit(); double pos_swap = mc_position.Swap(); double pos_comm = mc_position.Commission(); double cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2); ulong position_ticket = PositionGetTicket(i); if(type==POSITION_TYPE_BUY && cur_profit>0.02 && hps==dw) { RefreshTick(position_Symbol); orclose = mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } else if(hps==up) { PrintFormat("Close #%I64d %s %s",position_ticket,"trend is still good"); } if(type==POSITION_TYPE_SELL && cur_profit>0.02 && hps==up) { RefreshTick(position_Symbol); orclose = mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } else if(hps==dw) { PrintFormat("Close #%I64d %s %s",position_ticket,"trend is still good"); } } } } return(orclose); } //-end CloseAllProfit() bool MCEA::ManualCloseAllProfit(void) { ResetLastError(); bool orclose=false; MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; int ttlorder=PositionsTotal(); // number of open positions for(int x=0; x=0; i--) { string position_Symbol = PositionGetSymbol(i); ENUM_POSITION_TYPE type = mc_position.PositionType(); if((position_Symbol==symbol) && (mc_position.Magic()==magicEA)) { double pos_profit = mc_position.Profit(), pos_swap = mc_position.Swap(), pos_comm = mc_position.Commission(), cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2); ulong position_ticket = PositionGetTicket(i); if(type==POSITION_TYPE_BUY && cur_profit>0.02) { RefreshTick(position_Symbol); orclose = mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } if(type==POSITION_TYPE_SELL && cur_profit>0.02) { RefreshTick(position_Symbol); orclose = mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } } } } return(orclose); } //-end ManualCloseAllProfit() //-- function: close all order void MCEA::CloseAllOrders(void) { ResetLastError(); MqlTradeRequest req={}; MqlTradeResult res={}; MqlTradeCheckResult check={}; int total=PositionsTotal(); // number of open positions //--- iterate over all open positions for(int i=total-1; i>=0; i--) { //--- if the MagicNumber matches if(mc_position.Magic()==magicEA) { string position_Symbol = PositionGetSymbol(i); // symbol of the position ulong position_ticket = PositionGetTicket(i); // ticket of the the opposite position ENUM_POSITION_TYPE type = mc_position.PositionType(); RefreshTick(position_Symbol); bool closepos = mc_trade.PositionClose(position_Symbol,slip); //--- output information about the closure PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type)); } } return; } //-end CloseAllOrders() void MCEA::CheckClose(const string symbx) { ResetLastError(); Pips(symbx); datetime to=TimeCurrent(), from=to-(60), deal_time =0; // time of a deal execution int deals=0; //--- total number in the list of deals double profit_loss =0.0, // Order profit or loss deal_price =0.0, // deal/order CLOSE price deal_profit =0.0, // deal profit deal_swap =0.0, // position swap deal_comm =0.0; // position commission long deal_magic =0, // deal magic number deal_type =0; // Order Type ulong deal_ticket =0; // deal ticket string deal_symbol =""; // symbol of the deal ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry closetime=TimeCurrent()-(6); // 6 seconds ago //--- request the entire history HistorySelect(from,to); deals=HistoryDealsTotal(); //--- total number in the list of deals //--- go through deals in a loop for(int z=deals-1; z>=0 && !IsStopped(); z--) { deal_ticket = HistoryDealGetTicket(z); deal_symbol = HistoryDealGetString(deal_ticket,DEAL_SYMBOL); deal_magic = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC); deal_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY); deal_type = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE); if(deal_symbol==symbx && deal_magic==magicEA) { if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY)) { deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME); if((deal_time>0) && (deal_time>=closetime)) { deal_price = HistoryDealGetDouble(deal_ticket,DEAL_PRICE); deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT); deal_swap = HistoryDealGetDouble(deal_ticket,DEAL_SWAP); deal_comm = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION); profit_loss = NormalizeDouble(deal_profit+deal_swap+deal_comm,2); string xtype = deal_type==DEAL_TYPE_BUY ? "SELL" : deal_type==DEAL_TYPE_SELL ? "BUY": ""; if(profit_loss>0) { string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+ " OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+ " in profit : "+DoubleToString(profit_loss,2); Do_Alerts(symbx,ckclose); } if(profit_loss<=0) { string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+ " OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+ " in loss : "+DoubleToString(profit_loss,2); Do_Alerts(symbx,ckclose); } break; } } } } return; } //-end CheckClose() void MCEA::TodayOrders(void) { ResetLastError(); datetime from=StringToTime(ReqDate(ThisTime(day),0,0)); datetime to=TimeCurrent(); //--- request the entire history HistorySelect(from,to); //--- total number in the list of deals int deals=HistoryDealsTotal(); datetime deal_time =0; // time of a deal execution ulong deal_ticket =0; // deal ticket long deal_magic =0, // deal magic number deal_type =0; // Order Type double deal_price =0.0, // deal/order CLOSE price deal_profit =0.0, // deal profit deal_swap =0.0, // position swap deal_comm =0.0; // position commission ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry string pos_symbol =""; // Position symbol fixclprofit =0.0; // Order Close profit floatprofit =0.0; // float position profit oBm=0; // Order buy oSm=0; // Order sell int totalorder=PositionsTotal(); for(int i=0; i0) && (deal_time>=from)) { deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT); deal_swap = HistoryDealGetDouble(deal_ticket,DEAL_SWAP); deal_comm = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION); fixclprofit += NormalizeDouble(deal_profit+deal_swap+deal_comm,2); } } } } return; } //-end TodayOrders() // function: calculation lots size double MCEA::MLots(const string symbx) { int pil, Lpair, xsym=-1; double Lsize=0.0, sym_Lm=0.0; string sym_use ="", sCur1=StringSubstr(symbx,posCur1,3), sCur2=StringSubstr(symbx,posCur2,3); if(sCur1=="EUR"||sCur1=="GBP"||sCur1=="AUD"||sCur1=="NZD") pil=0; if(sCur1=="CAD"||sCur1=="CHF") pil=1; if(sCur1=="XAU"||sCur1=="XAG") pil=2; if(sCur1=="USD") pil=3; switch(pil) { case 0: sym_use=sCur1+"USD"; break; case 1: sym_use="USD"+sCur1; break; case 2: sym_use=symbx; break; case 3: sym_use=symbx; break; } xsym=PairsIdxArray(sym_use); if(xsym!=-1) sym_use=DIRI[xsym]; Lpair = StringFind(sym_use,"USD",0); CurrentSymbolSet(sym_use); double csize = mc_symbol.ContractSize(), AFMar = mc_account.FreeMargin(), AFLev = (double)mc_account.Leverage(), symbid = mc_symbol.Bid(), Lmaxs = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MAX), Lmins = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MIN), useRisk = (Risk/100.0), PctUse = ((100.0-Risk)/100.0), NZ1=NonZeroDiv(AFMar*AFLev,csize), NZ2=NonZeroDiv(AFMar*AFLev,symbid); if(Lpair>=0 && Lpair Lmaxs) Lsize = Lmaxs; double lotsize=NormalizeDouble(Lsize,LotDig(symbx)); return(lotsize); } //-end MLots() int MCEA::LotDig(const string symbx) { double lots_step=SymbolInfoDouble(symbx,SYMBOL_VOLUME_STEP); if(lots_step==0.01) ldig=2;if(lots_step==0.1) ldig=1;if(lots_step==1.0) ldig=0; return(ldig); } //-end LotDig() double MCEA::NonZeroDiv(double val1,double val2) { return ((val1==0 || val2==0) ? (0.00) : (val1/val2)); } //-end NonZeroDiv() // function: write comments on the chart void MCEA::TradeInfo(void) { Pips(Symbol()); double spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)/xpip; string comm=""; TodayOrders(); comm="\n :: Server Date Time : "+string(ThisTime(year))+"."+string(ThisTime(mon))+"."+string(ThisTime(day))+ " "+TimeToString(TimeCurrent(),TIME_SECONDS)+ "\n ------------------------------------------------------------"+ "\n :: robo adxpsar-v4 : debugger e refatoracao para execucao no ativo forex AUD/USD " "\n :: Broker : "+ TerminalInfoString(TERMINAL_COMPANY)+ "\n :: Expert Name : "+ expname+ "\n :: Acc. Name : "+ mc_account.Name()+ "\n :: Acc. Number : "+ (string)mc_account.Login()+ "\n :: Acc. TradeMode : "+ AccountMode()+ "\n :: Acc. Leverage : 1 : "+ (string)mc_account.Leverage()+ "\n :: Acc. Equity : "+ DoubleToString(mc_account.Equity(),2)+ "\n :: Margin Mode : "+ (string)mc_account.MarginModeDescription()+ "\n :: Magic Number : "+ string(magicEA)+ "\n :: Trade on TF : "+ EnumToString(TFt)+ "\n :: Today Trading : "+ TradingDay()+" : "+hariini+ "\n ------------------------------------------------------------"+ "\n :: Trading Pairs : "+pairs+ "\n :: BUY Market : "+string(oBm)+ "\n :: SELL Market : "+string(oSm)+ "\n :: Total Order : "+string(oBm+oSm)+ "\n :: Order Profit : "+DoubleToString(floatprofit,2)+ "\n :: Fixed Profit : "+DoubleToString(fixclprofit,2)+ "\n :: Float Money : "+DoubleToString(floatprofit,2)+ "\n :: Nett Profit : "+DoubleToString(floatprofit+fixclprofit,2); Comment(comm); ChartRedraw(0); return; } //-end TradeInfo() string MCEA::TradingDay(void) { int trdday=ThisTime(dow); switch(trdday) { case 0: daytrade="Sunday"; break; case 1: daytrade="Monday"; break; case 2: daytrade="Tuesday"; break; case 3: daytrade="Wednesday"; break; case 4: daytrade="Thursday"; break; case 5: daytrade="Friday"; break; case 6: daytrade="Saturday"; break; } return(daytrade); } //-end TradingDay() string MCEA::timehr(int hr,int mn) { string scon=""; string men=mn==0 ? "00" : string(mn); int shr=hr==24 ? 0 : hr; if(shr<10) scon="0"+string(shr)+":"+men; else scon=string(shr)+":"+men; return(scon); } //-end timehr() bool MCEA::TradingToday(void) { bool tradetoday=false; int trdday=ThisTime(dow); hariini="No"; int ttd[]; ArrayResize(ttd,7); ttd[0]=ttd0; ttd[1]=ttd1; ttd[2]=ttd2; ttd[3]=ttd3; ttd[4]=ttd4; ttd[5]=ttd5; ttd[6]=ttd6; if(ttd[trdday]==Yes) {tradetoday=true; hariini="Yes";} return(tradetoday); } //-end TradingToday() string MCEA::ReqDate(int d,int h,int m) { MqlDateTime mdt; datetime t=TimeCurrent(mdt); x_year=mdt.year; x_mon=mdt.mon; x_day=d; x_hour=h; x_min=m; x_sec=mdt.sec; string mdr=string(x_year)+"."+string(x_mon)+"."+string(x_day)+" "+timehr(x_hour,x_min); return(mdr); } //-end ReqDate() int MCEA::ThisTime(const int reqmode) { MqlDateTime tm; TimeCurrent(tm); int valtm=0; switch(reqmode) { case 0: valtm=tm.year; break; // Return Year case 1: valtm=tm.mon; break; // Return Month case 2: valtm=tm.day; break; // Return Day case 3: valtm=tm.hour; break; // Return Hour case 4: valtm=tm.min; break; // Return Minutes case 5: valtm=tm.sec; break; // Return Seconds case 6: valtm=tm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) case 7: valtm=tm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero) } return(valtm); } //-end ThisTime() // function: to known account trade mode string MCEA::AccountMode() { //--- Demo, Contest or Real account ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE); trade_mode=""; switch(account_type) { case ACCOUNT_TRADE_MODE_DEMO: trade_mode="Demo"; break; case ACCOUNT_TRADE_MODE_CONTEST: trade_mode="Contest"; break; default: trade_mode="Real"; break; } return(trade_mode); } //-end AccountMode() void MCEA::Do_Alerts(const string symbol,string msgText) { Print("--- "+symbol+": "+msgText+ "\n--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES)); if(alerts==Yes) Alert("--- "+symbol+": "+msgText+ "--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES)); if(UseEmailAlert==Yes) SendMail(expname,"--- "+symbol+" "+TF2Str(PERIOD_CURRENT)+": "+msgText+ "\n--- at: "+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES)); if(UseSendnotify==Yes) SendNotification(expname+"--- "+symbol+" "+TF2Str(PERIOD_CURRENT)+": "+msgText+ "\n--- at: "+TimeToString(iTime(symbol,0,0),TIME_DATE|TIME_MINUTES)); return; } //-end Do_Alerts() string MCEA::TF2Str(ENUM_TIMEFRAMES period) { switch(period) { case PERIOD_M1: return("M1"); case PERIOD_M2: return("M2"); case PERIOD_M3: return("M3"); case PERIOD_M4: return("M4"); case PERIOD_M5: return("M5"); case PERIOD_M6: return("M6"); case PERIOD_M10: return("M10"); case PERIOD_M12: return("M12"); case PERIOD_M15: return("M15"); case PERIOD_M20: return("M20"); case PERIOD_M30: return("M30"); case PERIOD_H1: return("H1"); case PERIOD_H2: return("H2"); case PERIOD_H3: return("H3"); case PERIOD_H4: return("H4"); case PERIOD_H6: return("H6"); case PERIOD_H8: return("H8"); case PERIOD_H12: return("H12"); case PERIOD_D1: return("D1"); case PERIOD_W1: return("W1"); case PERIOD_MN1: return("MN1"); } return(string(period)); } //-end TF2Str() string MCEA::getUninitReasonText(int reasonCode) { string text=""; switch(reasonCode) { case REASON_PROGRAM: text="The EA has stopped working calling by remove function."; break; case REASON_REMOVE: text="Program "+__FILE__+" was removed from chart"; break; case REASON_RECOMPILE: text="Program recompiled."; break; case REASON_CHARTCHANGE: text="Symbol or timeframe was changed"; break; case REASON_CHARTCLOSE: text="Chart was closed"; break; case REASON_PARAMETERS: text="Input-parameter was changed"; break; case REASON_ACCOUNT: text="Account was changed"; break; case REASON_TEMPLATE: text="New template was applied to chart"; break; case REASON_INITFAILED: text="The OnInit() handler returned a non-zero value."; break; case REASON_CLOSE: text="Terminal closed."; break; default: text="Another reason"; break; } return text; } //-end getUninitReasonText() //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- handling CHARTEVENT_CLICK event ("Clicking the chart") ResetLastError(); ENUM_TIMEFRAMES CCS=mc.TFt; if(id==CHARTEVENT_OBJECT_CLICK) { int lensymbol=StringLen(Symbol()); int lensparam=StringLen(sparam); //--- if "Set SL All Orders" button is click if(sparam=="Set SL/TP All Orders") { mc.SetSLTPOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Set SL/TP All Orders"); //--- unpress the button ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_STATE,false); ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Order" button is click if(sparam=="Close All Order") { mc.CloseAllOrders(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Orders"); //--- unpress the button ObjectSetInteger(0,"Close All Order",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Order",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "Close All Profit" button is click if(sparam=="Close All Profit") { mc.ManualCloseAllProfit(); Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Profit"); //--- unpress the button ObjectSetInteger(0,"Close All Profit",OBJPROP_STATE,false); ObjectSetInteger(0,"Close All Profit",OBJPROP_ZORDER,0); CreateManualPanel(); } //--- if "X" button is click if(sparam=="X") { ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); //--- unpress the button ObjectSetInteger(0,"X",OBJPROP_STATE,false); ObjectSetInteger(0,"X",OBJPROP_ZORDER,0); //-- DeleteButtonX(); mc.PanelExtra=false; DisplayManualButton(); } //--- if "M" button is click if(sparam=="M") { //--- unpress the button ObjectSetInteger(0,"M",OBJPROP_STATE,false); ObjectSetInteger(0,"M",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateManualPanel(); } //--- if "C" button is click if(sparam=="C") { //--- unpress the button ObjectSetInteger(0,"C",OBJPROP_STATE,false); ObjectSetInteger(0,"C",OBJPROP_ZORDER,0); mc.PanelExtra=true; CreateSymbolPanel(); } //--- if "R" button is click if(sparam=="R") { Alert("-- "+mc.expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart."); ExpertRemove(); //--- unpress the button ObjectSetInteger(0,"R",OBJPROP_STATE,false); ObjectSetInteger(0,"R",OBJPROP_ZORDER,0); if(!ChartSetSymbolPeriod(0,Symbol(),Period())) ChartSetSymbolPeriod(0,Symbol(),Period()); DeletePanelButton(); ChartRedraw(0); } //--- if Symbol button is click if(lensparam==lensymbol) { int sx=mc.PairsIdxArray(sparam); ChangeChartSymbol(mc.AS30[sx],CCS); mc.PanelExtra=false; } } return; } //-end OnChartEvent() void ChangeChartSymbol(string c_symbol,ENUM_TIMEFRAMES cstf) { //--- unpress the button ObjectSetInteger(0,c_symbol,OBJPROP_STATE,false); ObjectSetInteger(0,c_symbol,OBJPROP_ZORDER,0); ObjectsDeleteAll(0,0,OBJ_BUTTON); ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); ChartSetSymbolPeriod(0,c_symbol,cstf); ChartRedraw(0); return; } //-end ChangeChartSymbol() // Width Scaling factor wide button int WS(int width) { int res=0, reswidth=0, //--- Calculating the scaling factor wide button on a screen scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI)); //--- Use of the scaling factor reswidth=(width * scale_factor) / 96; double res1=NormalizeDouble(reswidth*1.25,0); res=int(res1); return(res); } //-end WS() void CreateManualPanel() { CreateButtonTemplate(0,"TemplateSL",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,45,true); CreateButtonTemplate(0,"TempStatSL",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,48,true); CreateButtonClick(0,"Set SL/TP All Orders",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Set SL/TP All Orders",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,56,true,"Set SL/TP All Orders"); CreateButtonTemplate(0,"TemplateS",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,77,true); CreateButtonTemplate(0,"TempStats",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,79,true); CreateButtonClick(0,"Close All Order",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Order",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,88,true,"Close All Order"); CreateButtonTemplate(0,"TemplateC",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,109,true); CreateButtonTemplate(0,"TempStatC",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,111,true); CreateButtonClick(0,"Close All Profit",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Profit",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,120,true,"Close All Profit"); DeletePanelButton(); CreateButtonClick(0,"X",17,15,"Arial Black",12,BORDER_RAISED,"X",clrNONE,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,27,31,true,"Close panel"); ChartRedraw(0); return; } //-end CreateManualPanel() void DisplayManualButton(void) { DeleteButtonX(); CreateButtonClick(0,"M",17,16,"Arial Black",11,BORDER_FLAT,"M",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,61,21,true,"Open Manual Panel"); CreateButtonClick(0,"C",17,16,"Arial Black",11,BORDER_FLAT,"C",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,41,21,true,"Change Chart Symbol"); CreateButtonClick(0,"R",17,16,"Arial Black",11,BORDER_FLAT,"R",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,21,21,true,"Expert Remove"); ChartRedraw(0); return; } //-end DisplayManualButton() bool DisplayManualButton(string a,string b,string c) { if(ObjectFind(0,a)<0 && ObjectFind(0,b)<0 && ObjectFind(0,c)<0 && !mc.PanelExtra) return(false); return(true); } //-end DisplayManualButton() void DeleteButtonX(void) { ObjectDelete(0,"X"); ChartRedraw(0); return; } //-end DeleteButtonX() void DeletePanelButton(void) { ObjectDelete(0,"M"); ObjectDelete(0,"C"); ObjectDelete(0,"R"); return; } //-end DeletePanelButton() void CreateSymbolPanel() { ResetLastError(); DeletePanelButton(); int sydis=83; int tsatu=int(mc.sall/2); CreateButtonTemplate(0,"Template",180,367,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,187,45,true); CreateButtonTemplate(0,"TempCCS",167,25,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBlue,clrWhite,CORNER_RIGHT_UPPER,181,50,true); CreateButtonClick(0,"X",14,14,"Arial Black",10,BORDER_FLAT,"X",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,22,48,true,"Close Symbol Panel"); string chsym="Change SYMBOL"; int cspos=int(181/2)+int(StringLen(chsym)/2); CreateButtontLable(0,"CCS","Bodoni MT Black",chsym,11,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,cspos,62,true,"Change Chart Symbol"); for(int i=0; i