AntRobot/ea/RicoBot.mq5
super.admin 9174d587ba convert
2025-05-30 14:40:14 +02:00

439 lines
30 KiB
MQL5

//+------------------------------------------------------------------+
//| RicoBot.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include "..\\utils\\Utils.mqh"
CTrade trade;
Utils utils;
// good config 5m (openPositionAmplitudeInline)
//input double amplitudeUmbral = 1.9;
//input double wickUmbral = 0.4;
//input int loadBalanceBars = 2;
//double takeProfit = amplitudeUmbral / 2;
//double stopLoss = amplitudeUmbral * 2;
//input int barsFromLastOpenPositionUmbral = 5 o 10
//end
// good config 1h 0 10m(passed in fab) (openPositionAmplitudeInline)
//input double amplitudeUmbral = 3.5;
//input double wickUmbral = 0.8;
//input int loadBalanceBars = 2;
//double takeProfit = amplitudeUmbral / 2;
//double stopLoss = amplitudeUmbral * 2;
//input int barsFromLastOpenPositionUmbral = 5 o 10
//end
//input generals
input double expectedprofitUmbral = 0.5;
input int loadBalanceUmbral = 70000;
input int barsFromLastOpenPositionUmbral = 900000;
//input ICrossAverage
input double Lots=0.01;
input int FEMA = 13;
input int MEMA = 26;
input int SEMA = 34;
//input ProbableTarget
input double fuzzyFactor = 0.10;
input int reachedPeriodLength = 24;
input int maxPeriodLength = 24;
//input ITrendConfirmation
input int FMA=12;
input int SMA=26;
input int SIGNAL=9;
input double CONFIRMATION_UMBRAL=10;
//input amplitude
input double amplitudeUmbral = 1.9;
input double wickUmbral = 0.4;
input int loadBalanceBars = 2;
//vars
double maxAbsoluteReachedBuffer[];
double smaMaxAbsoluteReachedBuffer[];
double maxReachedInBothDirectionBuffer[];
double smaMaxReachedInBothDirectionBuffer[];
double maxReachedInBothDirectionFuzzyModeBuffer[];
double maxReachedInBothDirectionFuzzyModeOccurrencesBuffer[];
double signDiffInPercentBuffer[];
double maxReachedInBothDirectionFuzzyModeOccurrencesByBarBuffer[];
double targetProfitBuffer[];
double stopLosstBuffer[];
long LIMIT_FACTOR = 100000;
int indicatorTrendHandle=0;
int indicatorProbableProfitHandle=0;
int indicatorAmplitudeHandle=0;
int indicatorTradeConfirmHandler=0;
int barsFromLastOpenPosition = 0;
int currentSignal=0;
int currentConfirmedSignal=0;
bool isFirstSignal=true;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//---
ResetLastError();
string path = utils.GetRelativeProgramPath();
indicatorTrendHandle=iCustom(Symbol(),PERIOD_CURRENT,path + "\\..\\indicators\\ICrossAverage",FEMA,MEMA,SEMA);
indicatorTradeConfirmHandler=iCustom(Symbol(),PERIOD_CURRENT,path + "\\..\\indicators\\ITrendConfirmation",FMA,SMA,SIGNAL,CONFIRMATION_UMBRAL);
indicatorProbableProfitHandle=iCustom(Symbol(),PERIOD_CURRENT,path + "\\..\\indicators\\ProbableTarget",fuzzyFactor,reachedPeriodLength,maxPeriodLength);
indicatorAmplitudeHandle=iCustom(Symbol(),PERIOD_CURRENT,path + "\\..\\indicators\\Amplitude",amplitudeUmbral, wickUmbral, loadBalanceBars);
if(indicatorTrendHandle ==INVALID_HANDLE || indicatorProbableProfitHandle==INVALID_HANDLE || indicatorTradeConfirmHandler==INVALID_HANDLE || indicatorAmplitudeHandle == INVALID_HANDLE) {
Print("Probable profit error inicialization, Code = ",GetLastError());
return -1;
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
if(indicatorTrendHandle!=INVALID_HANDLE) {
IndicatorRelease(indicatorTrendHandle);
}
if(indicatorProbableProfitHandle!=INVALID_HANDLE) {
IndicatorRelease(indicatorProbableProfitHandle);
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
//---
if(!checkIfNewBar())
return;
// open positions
long positionsTotal=PositionsTotal();
// don't trade if it's a open trade
if(positionsTotal>=1) {
if(barsFromLastOpenPosition == barsFromLastOpenPositionUmbral) {
trade.PositionClose(Symbol(),10);
//TODO: check if was ejecuted really
barsFromLastOpenPosition = 0;
} else {
barsFromLastOpenPosition +=1;
return;
}
}
//int signal = openPositionAmplitude();
int signal = openPositionAmplitudeInline();
//int signal = openPositionTwoWickBig();
Print("signal = ",signal);
if(signal == 1) {
MakeTrade(true);
}
if(signal == -1) {
MakeTrade(false);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int openPositionTwoWickBig() {
ResetLastError();
double positionBuffer[2];
MqlRates rates[2];
if(CopyRates(Symbol(),Period(),1,2,rates)!=2) {
Print("CopyRates error de copia, Code = ",GetLastError());
return 0;
}
if(rates[0].close > rates[0].open) {
if((absDiffInPercent(rates[0].close, rates[0].high) + absDiffInPercent(rates[1].close, rates[1].high)) >= wickUmbral) {
return -1;
}
if((absDiffInPercent(rates[0].open, rates[0].low) + absDiffInPercent(rates[1].open, rates[1].low)) >= wickUmbral) {
return 1;
}
}
if(rates[0].close < rates[0].open) {
if((absDiffInPercent(rates[0].close, rates[0].low) + absDiffInPercent(rates[1].close, rates[1].low)) >= wickUmbral) {
return 1;
}
if((absDiffInPercent(rates[0].open, rates[0].high) + absDiffInPercent(rates[1].open, rates[1].high)) >= wickUmbral) {
return 1;
}
}
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int openPositionAmplitudeInline() {
ResetLastError();
double positionBuffer[1];
MqlRates rates[1];
if(CopyRates(Symbol(),Period(),1,1,rates)!=1) {
Print("CopyRates error de copia, Code = ",GetLastError());
return 0;
}
double close = rates[0].close;
double open = rates[0].open;
double high = rates[0].high;
double low = rates[0].low;
if(absDiffInPercent(close, open) < amplitudeUmbral)
return 0;
if(close > open) {
if(absDiffInPercent(close, high) >= wickUmbral) {
return -1;
} else {
return 1;
}
}
if(close < open) {
if(absDiffInPercent(close, low) >= wickUmbral) {
return 1;
} else {
return -1;
}
}
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int openPositionAmplitude() {
ResetLastError();
double positionBuffer[1];
if(CopyBuffer(indicatorAmplitudeHandle,6,1,1,positionBuffer)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
Print("positionBuffer = ",positionBuffer[0]);
return (int)positionBuffer[0];
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int openPositionFromITrendConfirmation() {
ResetLastError();
currentSignal=getTrendSignal();
currentConfirmedSignal=getTradeConfirmationSignal();
double takeProfit = getTargetInPercent();
if(takeProfit < expectedprofitUmbral)
return 0;
if(isFirstSignal) {
isFirstSignal=false;
}
if(checkBuySignal(currentSignal,currentConfirmedSignal)==1) {
return 1;
}
if(checkIfSellSignal(currentSignal,currentConfirmedSignal)==1) {
return -1;
}
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int openPositionFromICrossAverage() {
ResetLastError();
double positionBuffer[4];
if(CopyBuffer(indicatorAmplitudeHandle,0,0,1,positionBuffer)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
Print("positionBuffer = ",positionBuffer[1]);
double trendDirection[4];
ResetLastError();
if(CopyBuffer(indicatorTrendHandle,0,0,1,trendDirection)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
if(CopyBuffer(indicatorProbableProfitHandle,7,0,1,signDiffInPercentBuffer)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
if(CopyBuffer(indicatorProbableProfitHandle,4,0,1,maxReachedInBothDirectionBuffer)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
int signal = (int)trendDirection[0];
if(MathAbs(signDiffInPercentBuffer[0]) > loadBalanceUmbral)
return 0;
double takeProfit = getTargetInPercent();
if(takeProfit < expectedprofitUmbral)
return 0;
if(signal == 0 && signDiffInPercentBuffer[0] < 0)
return 1;
if(signal == 0 && signDiffInPercentBuffer[0] > 0)
return -1;
return signal;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MakeTrade(bool isLong) {
//double stopLoss = 0;
//double takeProfit = 0;
//double stopLoss = getStopLossPercent();
//double takeProfit = getTargetInPercent();
double takeProfit = amplitudeUmbral / 2;
double stopLoss = amplitudeUmbral * 2;
MqlRates rates[2];
ResetLastError();
if(CopyRates(Symbol(),Period(),1,2,rates)!=2) {
Print("CopyRates error de copia, Code = ",GetLastError());
return;
}
//takeProfit = absDiffInPercent(rates[0].close, rates[0].high);
//stopLoss = takeProfit * 2;
string comment = "sl: " + NormalizeDouble(stopLoss, 2) + " tp: " + NormalizeDouble(takeProfit, 2);
if(isLong) {
double ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
double takeProfitLevel = ask * ((100 + takeProfit)/100);
double stopLossLevel = ask * ((100 - stopLoss)/100);
//double takeProfitLevel = ask + takeProfit;
//double stopLossLevel = ask - stopLoss;
trade.Buy(Lots,_Symbol,ask,stopLossLevel,takeProfitLevel,comment);
} else {
double bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
double takeProfitLevel = bid * ((100 - takeProfit)/100);
double stopLossLevel = bid * ((100 + stopLoss)/100);
//double takeProfitLevel = bid - takeProfit;
//double stopLossLevel = bid + stopLoss;
trade.Sell(Lots,_Symbol,bid,stopLossLevel,takeProfitLevel,comment);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getTargetInPercent() {
int copy = CopyBuffer(indicatorProbableProfitHandle,0,0,1,targetProfitBuffer);
if(copy != 1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
return targetProfitBuffer[0];
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getStopLossPercent() {
int copy = CopyBuffer(indicatorProbableProfitHandle,1,0,1,stopLosstBuffer);
if(copy != 1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
return stopLosstBuffer[0];
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int checkIfNewBar() {
MqlRates rates[1];
ResetLastError();
if(CopyRates(Symbol(),Period(),0,1,rates)!=1) {
Print("CopyRates error de copia, Code = ",GetLastError());
return false;
}
if(rates[0].tick_volume>1) {
return false;
}
return true;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int getTrendSignal() {
double trendDirection[1];
ResetLastError();
if(CopyBuffer(indicatorTrendHandle,0,0,1,trendDirection)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
return((int)trendDirection[0]);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int getTradeConfirmationSignal() {
double tradeConfirm[1];
ResetLastError();
if(CopyBuffer(indicatorTradeConfirmHandler,2,0,1,tradeConfirm)!=1) {
Print("CopyBuffer error de copia, Code = ",GetLastError());
return 0;
}
return((int)tradeConfirm[0]);
}
//+------------------------------------------------------------------+
int checkIfSellSignal(int currSignal,int confirmedSignal) {
if(currSignal==-1 && confirmedSignal==-1) {
return 1;
}
return 0;
}
//+------------------------------------------------------------------+
int checkBuySignal(int currSignal,int confirmedSignal) {
if(currentSignal==1 && confirmedSignal==1) {
return(1);
}
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double absDiffInPercent(const double initExtreme, const double endExtreme) {
return MathAbs(((endExtreme - initExtreme) * 100) / initExtreme);
}
//+------------------------------------------------------------------+