2349 lines
177 KiB
MQL5
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()
|
|
|
|
|
|
|