//+------------------------------------------------------------------+ //| 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 #include #include #include #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); } //+------------------------------------------------------------------+