//+------------------------------------------------------------------+
//| ExpertAdvisor_Crash300.mq5 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
// Entradas del usuario
input int FastMA_Period = 100;
input int SlowMA_Period = 200;
static input long InpMagicNumber = 546812;
input int RSI_Period = 8;
input double RSI_Level = 30.0;
input double LotSize = 0.05;
input int InputSL = 100000;
input int InputTP = 100000;
input bool ImpCloseSignal = false;
// Variables globales
int ticket1 = 0;
int fastHandle;
int slowHandle;
double fastMA[];
double slowMA[];
double rsi[];
CTrade trade;
int handlersi;
bool CountOpenPositions;
MqlTick currentTick;
datetime openTimeBuy = 0;
datetime openTimeSell = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// check input rsi
if(InpMagicNumber <= 0){
Alert("Magic Number <=0");
return INIT_PARAMETERS_INCORRECT;
}
// check input rsi
if(LotSize <= 0 || LotSize >10){
Alert("lot not acepted <=0");
return INIT_PARAMETERS_INCORRECT;
}
// check input rsi
if(RSI_Period <= 1){
Alert("Rsi period <=0");
return INIT_PARAMETERS_INCORRECT;
}
// check input rsi
if(RSI_Level >= 100 || RSI_Level <= 50){
Alert("Rsi not accepted");
return INIT_PARAMETERS_INCORRECT;
}
// set magic number to objet
trade.SetExpertMagicNumber(InpMagicNumber);
//validate inputs
if(FastMA_Period <= 0){
Alert("Fast period <=0");
return INIT_PARAMETERS_INCORRECT;
}
if(SlowMA_Period <= 0){
Alert("Slow period <=0");
return INIT_PARAMETERS_INCORRECT;
}
if(SlowMA_Period <= FastMA_Period){
Alert("Fast period >= Slow period");
return INIT_PARAMETERS_INCORRECT;
}
if(InputSL <= 0){
Alert("stop loss <=0");
return INIT_PARAMETERS_INCORRECT;
}
if(InputTP <= 0){
Alert("Take profit <=0");
return INIT_PARAMETERS_INCORRECT;
}
//creat handles
fastHandle = iMA(_Symbol,PERIOD_CURRENT,FastMA_Period,0,MODE_SMA,PRICE_CLOSE);
if(fastHandle == INVALID_HANDLE){
Alert("Failed to create fast handle");
return INIT_FAILED;
}
slowHandle = iMA(_Symbol,PERIOD_CURRENT,SlowMA_Period,0,MODE_SMA,PRICE_CLOSE);
if(slowHandle == INVALID_HANDLE){
Alert("Failed to create slow handle");
return INIT_FAILED;
}
//create handle
handlersi = iRSI (_Symbol,PERIOD_CURRENT,RSI_Period, PRICE_CLOSE);
if (handlersi == INVALID_HANDLE){
Alert("Failed to create indictor handle");
return INIT_FAILED;
}
ArraySetAsSeries(fastMA,true);
ArraySetAsSeries(slowMA,true);
ArraySetAsSeries(rsi,true);
return(INIT_SUCCEEDED);
}
//
// Función de inicio
void OnTick()
{
if(!SymbolInfoTick(_Symbol,currentTick))
{
Print("Failed to get current tick"); return;}
// Copy the values of the moving averages into the arrays
int values1 = CopyBuffer(fastHandle, 0, 0, 2, fastMA);
int values2 = CopyBuffer(slowHandle, 0, 0, 2, slowMA);
int values3 = CopyBuffer(handlersi, 0, 0, 2, rsi);
// Check if the values were successfully copied
if (values1 != 2 || values2 != 2 || values3 != 2) {
printf("Failed to get indicator values");
return;
}
Comment("slowMA[0]:", slowMA[0],
"\nslowMA[1]:",slowMA[1],
"\nfastMA[0]:", fastMA[0],
"\nslowMA[1]:",fastMA[1],
"\nbufferrsi[0]:", rsi[0],
"\nbufferrsi[1]:",rsi[1]);
// Obtener los valores de las medias móviles y el RSI
if (values1 <= 0 || values2 <= 0 || values3 <= 0)
{
Print("Error al obtener los valores de los indicadores: ", GetLastError());
return;
}
// count opern position
int cntBuy, cntSell;
if(!CountOpenPositions(cntBuy,cntSell)){return;}
//check for buy position
if(cntBuy==0 && rsi[1]>=(100-RSI_Level) && rsi[0]<(100-RSI_Level) && openTimeBuy
!= iTime(_Symbol,PERIOD_CURRENT,0)){
openTimeBuy=iTime(_Symbol,PERIOD_CURRENT,0);
if(ImpCloseSignal){if(!ClosePositions(2)){return;}}
double sl = InputSL==0 ? 0 : currentTick.bid - InputSL * _Point;
double tp = InputTP==0 ? 0 : currentTick.bid + InputTP * _Point;
if(!NormalizeDouble(sl)){return;}
if(!NormalizeDouble(tp)){return;}
trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,LotSize,currentTick.ask,sl,tp, "RSI
EA");
//check for SELL position
if(cntSell==0 && rsi[1]<=RSI_Level && rsi[0]>RSI_Level && openTimeSell !=
iTime(_Symbol,PERIOD_CURRENT,0)){
openTimeSell=iTime(_Symbol,PERIOD_CURRENT,0);
if(ImpCloseSignal){if(!ClosePositions(1)){return;}}
double sl = InputSL==0 ? 0 : currentTick.ask + InputSL * _Point;
double tp = InputTP==0 ? 0 : currentTick.ask - InputTP * _Point;
if(!NormalizeDouble(sl)){return;}
if(!NormalizeDouble(tp)){return;}
trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,LotSize,currentTick.bid,sl,tp,
"RSI EA");
// funciones
// open positions
bool CountOpenPositions (int &cntBuy, int &cntSell){
cntBuy = 0;
cntSell = 0;
int total = PositionsTotal();
for(int i=total-1 ; i>=0 ; i--){
ulong ticket = PositionGetTicket(i);
if(ticket<=0){Print("Failed to open posistion ticket"); return false;}
if(!PositionSelectByTicket(ticket)){Print("Failed to select
position");}
long magic;
if(!PositionGetInteger(POSITION_MAGIC,magic)){Print("failed to get
psition magic number");return false;}
if(magic == InpMagicNumber){
long type;
if(!PositionGetInteger(POSITION_TYPE,type)){Print("Failed to get
position types");return false;}
if(type==POSITION_TYPE_BUY){cntBuy++;}
if(type==POSITION_TYPE_SELL){cntSell++;}
}
}
return true;
}
// nomalize price
bool NormalizeDouble(double &price){
double tickSize=0;
if(!SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE,tickSize)){
Print("Failed to get tick size");
return false;
}
price = NormalizeDouble(MathRound(price/tickSize)*tickSize,_Digits);
return true;
}
// close positions
bool ClosePositions (int all_buy_sell){
int total = PositionsTotal();
for(int i=total-1 ; i>=0 ; i--){
ulong ticket = PositionGetTicket(i);
if(ticket<=0){Print("Failed to open posistion ticket"); return false;}
if(!PositionSelectByTicket(ticket)){Print("Failed to select
position");}
long magic;
if(!PositionGetInteger(POSITION_MAGIC,magic)){Print("failed to get
psition magic number");return false;}
if(magic == InpMagicNumber){
long type;
if(!PositionGetInteger(POSITION_TYPE,type)){Print("Failed to get
position types");return false;}
if(all_buy_sell==1 && type== POSITION_TYPE_SELL){continue;}
if(all_buy_sell == 2 && type==POSITION_TYPE_BUY){continue;}
trade.PositionClose(ticket);
if(trade.ResultRetcode()!=TRADE_RETCODE_DONE){
Print("Failed to close position", (string)ticket, "result",
(string)trade.ResultRetcode(), ":", trade.CheckResultRetcodeDescription());
}
}
}
return true;
}