robo-labs/adxpsar_v4.mq5
2026-01-19 20:05:37 -03:00

2349 lines
177 KiB
MQL5

//+------------------------------------------------------------------+
//| 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 <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
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; x<arrsymbx; x++) {SymbolSelect(DIRI[x],true);}
pairs="robo para operar adxpsar para o aud/usd";
/* enum de timeframes */
ENUM_TIMEFRAMES TFs[]={PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1};
/**
* obtem o tamanho da quantidade de timeframes declarados, ele percorre para saber
* qual o timeframe que foi selecionado, neste caso o default eh o H4;
*/
int arTFs=ArraySize(TFs);
for(int x=0; x<arTFs; x++) { if(x==TimeFrames) { TFt=TFs[x]; break; } }
/**
* neste trecho ele percorre pela quantidade de pares
* arrsymbx = quantidade de pares forex
* e aplica configurações de adx e sar
*/
for(int x=0; x<arrsymbx; x++) {
handADX[x] = iADX(DIRI[x],TFt,ADXPeriod);
hParOp[x] = iSAR(DIRI[x],TFt,SARstep,SARmaxi);
hPar15[x] = iSAR(DIRI[x],TFT15,SARstep,SARmaxi);
hPar05[x] = iSAR(DIRI[x],TFT05,SARstep,SARmaxi);
}
/**
* if ternario onde verifica se ja ultrapassou a quantidade de limit orders para
* aquela conta, ele verifica por exemplo se a quantidade de ordens eh maior que a quantidade
* de ativos forex no original do robo sao 30, como agora eh somente 1, precisamos estar atento
* para saber em que momento isto pode impactar no comportamento do robo;
*/
ALO = (int)mc_account.LimitOrders()>arrsymbx ? 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; x<mc.arrsymbx; x++) {
IndicatorRelease(mc.handADX[x]);
IndicatorRelease(mc.hParOp[x]);
IndicatorRelease(mc.hPar05[x]);
IndicatorRelease(mc.hPar15[x]);
}
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
Print(mc.getUninitReasonText(reason));
ObjectsDeleteAll(0,0,OBJ_BUTTON);
ObjectsDeleteAll(0,0,OBJ_LABEL);
ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
return;
} //-end OnDeinit()
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(void) {
mc.ExpertActionTrade();
return;
} //-end OnTick()
void MCEA::ExpertActionTrade(void) {
//Check Trading Terminal
ResetLastError();
//-- Check whether MT5 Algorithmic trading is Allow or Prohibit
if(!MQLInfoInteger(MQL_TRADE_ALLOWED) && mc.checktml==0) {
mc.Do_Alerts(Symbol(),"Trading Expert at "+Symbol()+" are NOT Allowed by Setting.");
mc.checktml=1; //-- Variable checktml is given a value of 1, so that the alert is only done once.
return;
}
//-- Show the expert manual button panel
if(!DisplayManualButton("M","C","R")) DisplayManualButton();
//-- Displayed Trading Info on Chart
if(trade_info_display==Yes) mc.TradeInfo();
int mcsec=mc.ThisTime(mc.sec);
if(fmod((double)mcsec,5.0)==0) mc.ccur=mcsec;
if(mc.ccur!=mc.psec) {
string symbol;
//-- Here we start with the rotation of the name of all symbol or pairs to be traded
for(int x=0; x<mc.arrsymbx && !IsStopped(); x++) {
if(mc.DIRI[x]==Symbol()) {
symbol=Symbol();
} else {
symbol=mc.DIRI[x];
}
//esta chamada de function seta o ativo para que seja o principal
mc.CurrentSymbolSet(symbol);
if(mc.TradingToday()) {
/**
* //-- Get trading signals to open positions
* //-- and store in the variable OpOr[x]
*/
mc.OpOr[x]=mc.GetOpenPosition(symbol);
//-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Buy" (value=1)
if(mc.OpOr[x]==mc.Buy) {
mc.CheckOpenPMx(symbol);
if(Close_by_Opps==Yes && mc.xos[x]>0) mc.CloseSellPositions(symbol);
if(mc.xob[x]==0 && mc.xtto<mc.ALO) {
mc.OpenBuy(symbol);
} else if(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.OpenSell(symbol);
} else if(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; x<arrsymbx; x++) { if(DIRI[x]==symbol) { pidx=x; break; } } return(pidx);
} //-end PairsIdxArray()
/**
* metodo ou function para ArraySymbolResize();
* Libera um buffer de qualquer array dinâmico e define o tamanho da dimensão zero para 0.
* void ArrayFree(
* void& array[] // array
* );
*
*
* 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)
* );
*
*
* A função define o flag AS_SERIES para um objeto de um array dinâmico, e os elementos serão indexados como em timeseries.
* bool ArraySetAsSeries(
* const void& array[], // array passado por referência
* bool flag // true significa ordem reversa de indexação
* );
*
*/
void MCEA::ArraySymbolResize(void) {
ArrayFree(DIRI);
ArrayFree(xob);
ArrayFree(xos);
ArrayFree(OpOr);
ArrayFree(profitb);
ArrayFree(profits);
ArrayFree(hPar15);
ArrayFree(hPar05);
ArrayFree(hParOp);
ArrayFree(ADXDIp);
ArrayFree(ADXDIm);
ArrayFree(handADX);
ArrayResize(DIRI,arrsymbx,arrsymbx);
ArrayResize(xob,arrsymbx,arrsymbx);
ArrayResize(xos,arrsymbx,arrsymbx);
ArrayResize(OpOr,arrsymbx,arrsymbx);
ArrayResize(profitb,arrsymbx,arrsymbx);
ArrayResize(profits,arrsymbx,arrsymbx);
ArrayResize(hPar15,arrsymbx,arrsymbx);
ArrayResize(hPar05,arrsymbx,arrsymbx);
ArrayResize(hParOp,arrsymbx,arrsymbx);
ArrayResize(handADX,arrsymbx,arrsymbx);
ArrayResize(ADXDIp,arrsymbx,arrsymbx);
ArrayResize(ADXDIm,arrsymbx,arrsymbx);
ArraySetAsSeries(ADXDIp,true);
ArraySetAsSeries(ADXDIm,true);
return;
} //-end ArraySymbolResize()
void MCEA::UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf) {
ArrayFree(OPEN);
ArrayFree(HIGH);
ArrayFree(LOW);
ArrayFree(CLOSE);
ArrayFree(TIME);
ArrayResize(OPEN,arper,arper);
ArrayResize(HIGH,arper,arper);
ArrayResize(LOW,arper,arper);
ArrayResize(CLOSE,arper,arper);
ArrayResize(TIME,arper,arper);
ArraySetAsSeries(OPEN,true);
ArraySetAsSeries(HIGH,true);
ArraySetAsSeries(LOW,true);
ArraySetAsSeries(CLOSE,true);
ArraySetAsSeries(TIME,true);
ArrayInitialize(OPEN,0.0);
ArrayInitialize(HIGH,0.0);
ArrayInitialize(LOW,0.0);
ArrayInitialize(CLOSE,0.0);
ArrayInitialize(TIME,0);
RefreshPrice(symbol,xtf,arper);
/**
Call by the first position and the number of required elements
int CopyOpen(
string symbol_name, // symbol name
ENUM_TIMEFRAMES timeframe, // period
int start_pos, // start position
int count, // data count to copy
double open_array[] // target array to copy open prices
);
Call by the start date and the number of required elements
int CopyOpen(
string symbol_name, // symbol name
ENUM_TIMEFRAMES timeframe, // period
datetime start_time, // start date and time
int count, // data count to copy
double open_array[] // target array for bar open prices
);
Call by the start and end dates of a required time interval
int CopyOpen(
string symbol_name, // symbol name
ENUM_TIMEFRAMES timeframe, // period
datetime start_time, // start date and time
datetime stop_time, // stop date and time
double open_array[] // target array for bar open values
);
*/
int co=CopyOpen(symbol,xtf,0,arper,OPEN);
int ch=CopyHigh(symbol,xtf,0,arper,HIGH);
int cl=CopyLow(symbol,xtf,0,arper,LOW);
int cc=CopyClose(symbol,xtf,0,arper,CLOSE);
int ct=CopyTime(symbol,xtf,0,arper,TIME);
return;
} //-end UpdatePrice()
void MCEA::RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars) {
MqlRates parray[];
ArraySetAsSeries(parray,true);
int copied=CopyRates(symbx,xtf,0,bars,parray);
return;
} //-end RefreshPrice()
bool MCEA::RefreshTick(const string symbx) {
mc_symbol.Name(symbx);
if(mc_symbol.RefreshRates()) return(true);
return(false);
} //-end RefreshTick()
void MCEA::CurrentSymbolSet(const string symbol) {
mc_symbol.Name(symbol);
mc_symbol.CheckMarketWatch();
mc_symbol.IsSynchronized();
mc_trade.SetTypeFillingBySymbol(symbol);
mc_symbol.Refresh();
mc_symbol.RefreshRates();
return;
} //-end CurrentSymbolSet()
void MCEA::Pips(const string symbol) {
CurrentSymbolSet(symbol);
double point=mc_symbol.Point();
dgts=(int)mc_symbol.Digits();
xpip=10.0;
pip=point*xpip;
return;
} //-end Pips()
// Bar Price Direction
int MCEA::DirectionMove(const string symbol) {
int ret=0;
int rise=1,
down=-1;
Pips(symbol);
double difud=mc_symbol.NormalizePrice(1.5*pip);
UpdatePrice(symbol,TFt);
if(CLOSE[0]>OPEN[0]+difud) ret=rise;
if(CLOSE[0]<OPEN[0]-difud) ret=down;
return(ret);
} //-end DirectionMove()
//ADX indicator function - input index of bar.
int MCEA::iADXpct(const string symbol,const int index) {
double answer1=0,
answer2=0,
pdi_now=0,
mdi_now=0,
pdi_prv=0,
mdi_prv=0;
int rise=1,
down=-1;
int mv=0;
int x=PairsIdxArray(symbol);
UpdatePrice(symbol,TFt);
CopyBuffer(handADX[x],1,0,3,ADXDIp);
CopyBuffer(handADX[x],2,0,3,ADXDIm);
pdi_now=ADXDIp[index];
mdi_now=ADXDIm[index];
pdi_prv=ADXDIp[index+1];
mdi_prv=ADXDIm[index+1];
if((pdi_now==0 || pdi_now==EMPTY_VALUE) || (mdi_now==0 || mdi_now==EMPTY_VALUE)) {
answer1=0.0;
} else {
answer1 = NormalizeDouble((pdi_now / mdi_now * 100) - 100,3);
}
if((pdi_prv==0 || pdi_prv==EMPTY_VALUE) || (mdi_prv==0 || mdi_prv==EMPTY_VALUE)) {
answer2=0.0;
} else {
answer2 = NormalizeDouble((pdi_prv / mdi_prv * 100) - 100,3);
}
if(answer1>answer2) mv=rise;
if(answer1<answer2) mv=down;
return(mv);
} //-end iADXpct()
int MCEA::iADXCross(const string symbol) {
int mv=0,
rise=1,
down=-1,
x=PairsIdxArray(symbol);
UpdatePrice(symbol,TFt);
int GiADXc=iADXpct(symbol,0);
CopyBuffer(handADX[x],1,0,3,ADXDIp);
CopyBuffer(handADX[x],2,0,3,ADXDIm);
bool gadxrise=(ADXDIp[2]<=ADXDIm[2] && ADXDIp[1]>ADXDIm[1]+difDi && ADXDIp[0]>ADXDIp[1] && GiADXc==rise);
bool gadxdown=(ADXDIp[2]>=ADXDIm[2] && ADXDIp[1]<ADXDIm[1]-difDi && ADXDIp[0]<ADXDIp[1] && GiADXc==down);
if(gadxrise) mv=rise;
if(gadxdown) mv=down;
return(mv);
} //- end iADXCross()
// Signal Open Position
int MCEA::GetOpenPosition(const string symbol) {
int ret=0,
rise=1,
down=-1,
dirmov=DirectionMove(symbol),
pars15=PARSAR15(symbol),
parsOp=PARSAROp(symbol),
sigADX=iADXCross(symbol);
if(sigADX==rise && parsOp==rise && dirmov==rise && pars15==rise) ret=rise;
if(sigADX==down && parsOp==down && dirmov==down && pars15==down) ret=down;
return(ret);
} //-end GetOpenPosition()
// Signal Indicator Position Close in profit
int MCEA::GetCloseInWeakSignal(const string symbol,int exis) {
int ret=0,
rise=1,
down=-1,
x=PairsIdxArray(symbol);
UpdatePrice(symbol,TFt);
CopyBuffer(handADX[x],1,0,3,ADXDIp);
CopyBuffer(handADX[x],2,0,3,ADXDIm);
int GiADXp=iADXpct(symbol,0);
bool gadxriseD=(ADXDIp[0]>ADXDIm[0] && GiADXp==down);
bool gadxdownR=(ADXDIp[0]<ADXDIm[0] && GiADXp==rise);
if(exis==down && gadxdownR) ret=rise;
if(exis==rise && gadxriseD) ret=down;
return(ret);
} //-end GetCloseInWeakSignal()
// Signal Indicator Position Close
int MCEA::CheckToCloseInWeakSignal(const string symbol,int exis) {
int ret=0,
rise=1,
down=-1,
xi=PairsIdxArray(symbol),
dirmov=DirectionMove(symbol),
pars15=PARSAR15(symbol),
parsop=PARSAROp(symbol);
if(exis==down && parsop==rise && pars15==rise && dirmov==rise) ret=rise;
if(exis==rise && parsop==down && pars15==down && dirmov==down) ret=down;
return(ret);
} //-end CheckToCloseInWeakSignal()
// formula Parabolic SAR in set timeframe
int MCEA::PARSAROp(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(hParOp[xx],0,0,br,PSAR);
RefreshPrice(symbol,TFt,br);
double HIG0=iHigh(symbol,TFt,0);
double LOW0=iLow(symbol,TFt,0);
if(PSAR[0]<LOW0) ret=rise;
if(PSAR[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]<LOW0) ret=rise;
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]<LOW0) ret=rise;
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; i<totalorder && !IsStopped(); i++) {
string position_symbol=PositionGetSymbol(i);
long magic = mc_position.Magic();
if(position_symbol==symbx && magic==magicEA) {
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY) {
xob[xi]++;
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
profitb[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
}
if(opstype == POSITION_TYPE_SELL) {
xos[xi]++;
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
profits[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
}
}
}
return;
} //-end CheckOpenPMx()
double MCEA::TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type) {
int br=2;
double pval=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
switch(TS_type) {
case 0:
{
RefreshTick(xsymb);
if(ptype==POSITION_TYPE_BUY) pval=mc_symbol.NormalizePrice(mc_symbol.Bid()-TSval*pip);
if(ptype==POSITION_TYPE_SELL) pval=mc_symbol.NormalizePrice(mc_symbol.Ask()+TSval*pip);
break;
}
case 1:
{
double PSAR[];
ArrayResize(PSAR,br,br);
ArraySetAsSeries(PSAR,true);
CopyBuffer(hParOp[x],0,0,br,PSAR);
RefreshPrice(xsymb,TFt,br);
//--
if(ptype==POSITION_TYPE_BUY && (PSAR[0]<iLow(xsymb,TFt,0))) pval=PSAR[0];
if(ptype==POSITION_TYPE_SELL && (PSAR[0]>iHigh(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 = (price<modminsl && modselsl<modstart && (pos_stop==0.0||modselsl<pos_stop));
if(modsel && netp>0.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(price<modbuysl) modbuysl=mc_symbol.NormalizePrice(price-slip*pip);
modbuytp=SetOrderTP(symbol,opstype,pos_open);
if(price>modbuytp) 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<modseltp) modseltp=mc_symbol.NormalizePrice(price-slip*pip);
if(pos_stop==0.0 || pos_take==0.0) {
if(!mc_trade.PositionModify(position_symbol,modselsl,modseltp)) {
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()+"]");
}
}
}
}
}
return;
} //-end SetSLTPOrders
double MCEA::SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice) {
slv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
switch(type) {
case (POSITION_TYPE_BUY):
{
slv=mc_symbol.NormalizePrice(atprice-SLval*pip);
break;
}
case (POSITION_TYPE_SELL):
{
slv=mc_symbol.NormalizePrice(atprice+SLval*pip);
break;
}
}
return(slv);
} //-end SetOrderSL()
double MCEA::SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice) {
tpv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
switch(type) {
case (POSITION_TYPE_BUY):
{
tpv=mc_symbol.NormalizePrice(atprice+TPval*pip);
break;
}
case (POSITION_TYPE_SELL):
{
tpv=mc_symbol.NormalizePrice(atprice-TPval*pip);
}
}
return(tpv);
} //-end SetOrderTP()
void MCEA::CloseBuyPositions(const string symbol) {
ResetLastError();
int total=PositionsTotal(); // number of open positions
ENUM_POSITION_TYPE closetype = POSITION_TYPE_BUY;
ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL;
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 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<arrsymbx; x++) {
string symbol=DIRI[x];
int hps=PARSAR05(symbol);
orclose=false;
for(int i=ttlorder-1; i>=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<arrsymbx; x++) {
string symbol=DIRI[x];
orclose=false;
for(int i=ttlorder-1; i>=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; i<totalorder && !IsStopped(); i++) {
pos_symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Symbol() == pos_symbol && magic==magicEA) {
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY) {oBm++; floatprofit += mc_position.Profit();}
if(opstype == POSITION_TYPE_SELL) {oSm++; floatprofit += mc_position.Profit();}
}
}
xtto=oBm+oSm;
//--- go through deals in a loop
for(int z=0; z<deals && !IsStopped(); z++) {
deal_ticket = HistoryDealGetTicket(z);
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_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>=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<posCur2) {sym_Lm = fmin(Lmaxs,NZ1);}
else {sym_Lm = fmin(Lmaxs,NonZeroDiv(NZ2,csize));}
double sym_Lc = NormalizeDouble(sym_Lm*useRisk,LotDig(symbx)),
asize = NormalizeDouble(sym_Lc/(double)LotPS,LotDig(symbx));
if(mmlot==DynamLot) {
Lsize = NormalizeDouble(asize*PctUse,LotDig(symbx));
} else {
Lsize = Lots;
}
if(Lsize < Lmins) Lsize = Lmins;
if(Lsize > 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<tsatu; i++) CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,180,sydis+(i*22),true,"Change to "+mc.AS30[i]);
for(int i=tsatu; i<mc.sall; i++) CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,94,sydis+((i-15)*22),true,"Change to "+mc.AS30[i]);
ChartRedraw(0);
return;
} //-end CreateSymbolPanel()
void CreateButtonClick(long chartid,
string button_name,
int button_x_size,
int button_y_size,
string button_font_model,
int button_font_size,
int button_border,
string button_name_text,
color button_bord_color,
color button_bg_color,
color button_color,
int button_anchor,
int button_corner,
int button_xdist,
int button_ydist,
bool button_hidden,
string tooltip) {
ObjectCreate(chartid,button_name,OBJ_BUTTON,0,0,0); // create button
ObjectSetInteger(chartid,button_name,OBJPROP_XSIZE,WS(button_x_size));
ObjectSetInteger(chartid,button_name,OBJPROP_YSIZE,button_y_size);
ObjectSetString(chartid,button_name,OBJPROP_TEXT,button_name_text);
ObjectSetString(chartid,button_name,OBJPROP_FONT,button_font_model);
ObjectSetInteger(chartid,button_name,OBJPROP_FONTSIZE,button_font_size);
ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_TYPE,button_border);
ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_COLOR,button_bord_color);
ObjectSetInteger(chartid,button_name,OBJPROP_BGCOLOR,button_bg_color);
ObjectSetInteger(chartid,button_name,OBJPROP_COLOR,button_color);
ObjectSetInteger(chartid,button_name,OBJPROP_ANCHOR,button_anchor);
ObjectSetInteger(chartid,button_name,OBJPROP_CORNER,button_corner);
ObjectSetInteger(chartid,button_name,OBJPROP_XDISTANCE,WS(button_xdist));
ObjectSetInteger(chartid,button_name,OBJPROP_YDISTANCE,button_ydist);
ObjectSetInteger(chartid,button_name,OBJPROP_HIDDEN,button_hidden);
ObjectSetString(chartid,button_name,OBJPROP_TOOLTIP,tooltip);
ChartRedraw(0);
return;
} //-end CreateButtonClick()
void CreateButtonTemplate(long chartid,
string obj_name,
int x_size,
int y_size,
int style,
int width,
int border,
color bordcolor,
color bgcolor,
color objcolor,
int corner,
int x_dist,
int y_dist,
bool hidden) {
ObjectCreate(chartid,obj_name,OBJ_RECTANGLE_LABEL,0,0,0); // create Rectangle Label
ObjectSetInteger(chartid,obj_name,OBJPROP_XSIZE,WS(x_size));
ObjectSetInteger(chartid,obj_name,OBJPROP_YSIZE,y_size);
ObjectSetInteger(chartid,obj_name,OBJPROP_STYLE,style);
ObjectSetInteger(chartid,obj_name,OBJPROP_WIDTH,width);
ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_TYPE,border);
ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_COLOR,bordcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_BGCOLOR,bgcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_COLOR,objcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_CORNER,corner);
ObjectSetInteger(chartid,obj_name,OBJPROP_XDISTANCE,WS(x_dist));
ObjectSetInteger(chartid,obj_name,OBJPROP_YDISTANCE,y_dist);
ObjectSetInteger(chartid,obj_name,OBJPROP_HIDDEN,hidden);
ChartRedraw(0);
return;
} //-end CreateButtonTemplate()
void CreateButtontLable(long chartid,
string lable_name,
string lable_font_model,
string lable_obj_text,
int lable_font_size,
color lable_color,
int lable_anchor,
int lable_corner,
int lable_xdist,
int lable_ydist,
bool lable_hidden,
string tooltip) {
ObjectDelete(chartid,lable_name);
ObjectCreate(chartid,lable_name,OBJ_LABEL,0,0,0,0,0); // create Lable
ObjectSetInteger(chartid,lable_name,OBJPROP_FONTSIZE,lable_font_size);
ObjectSetString(chartid,lable_name,OBJPROP_FONT,lable_font_model);
ObjectSetString(chartid,lable_name,OBJPROP_TEXT,lable_obj_text);
ObjectSetInteger(chartid,lable_name,OBJPROP_COLOR,lable_color);
ObjectSetInteger(chartid,lable_name,OBJPROP_ANCHOR,lable_anchor);
ObjectSetInteger(chartid,lable_name,OBJPROP_CORNER,lable_corner);
ObjectSetInteger(chartid,lable_name,OBJPROP_XDISTANCE,WS(lable_xdist));
ObjectSetInteger(chartid,lable_name,OBJPROP_YDISTANCE,lable_ydist);
ObjectSetInteger(chartid,lable_name,OBJPROP_HIDDEN,lable_hidden);
ObjectSetString(chartid,lable_name,OBJPROP_TOOLTIP,tooltip);
ChartRedraw(0);
return;
} //-end CreateButtontLable()