#property copyright "Copyright 2023, M & Q Investment Group" #property link "https://www.mql5.com" #property version "1.00" #include CTrade trade; input int GHighLowShift = 10; input double GMaximalSLPoints = 100; input double GMaximalTPPoints = 100; input double GTPtoOneSLRatio = 1; input double RiskPerc = 1; input double GTrigTSLRatioPricebeforeTP = 0.5; input int GMinTSLDistPoints = 50; input int GMaxPriceBufferrange = 30; input double GExtraOverEngulfingPoints = 20; input int TradecooldownMin = 30; int TradecooldownSec = TradecooldownMin * 60; datetime Tradecooldown; int HandleRSI; int HandleATR; int HandleMA200; int HandleMA50; int HandleMA21; double accountbalancebeginning; double accountprofit; double Lostrades = 0; double Wintrades = 0; double AllWinRatio = 0; int OnInit(){ HandleATR = iATR(_Symbol,PERIOD_CURRENT,14); accountbalancebeginning = AccountInfoDouble(ACCOUNT_BALANCE); return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ Lostrades = TesterStatistics(STAT_LOSS_TRADES); Wintrades = TesterStatistics(STAT_PROFIT_TRADES); if(Lostrades + Wintrades > 0){ AllWinRatio = NormalizeDouble(Wintrades / (Wintrades + Lostrades),2); }else{AllWinRatio = 0;} Print("Verlorene Trades: ",Lostrades, "\nGewonnenen Trades: ",Wintrades, "\nGewinnrate:________",AllWinRatio); } void OnTick(){ datetime GCurrenttime = TimeCurrent(); int CandleNumber = Bars(_Symbol,_Period); if(CheckfornewCandle(CandleNumber,GCurrenttime)){ int EngulfingValue = CheckEngulfingPatternUp1Net0Down2(GExtraOverEngulfingPoints,GMaxPriceBufferrange); if(EngulfingValue != 0){ Print("Engulfing Pattern ---",EngulfingValue, "Currenttime: ",GCurrenttime, "\nClose1: ",iClose(_Symbol,PERIOD_CURRENT,1), "\nAsk: ",SymbolInfoDouble(_Symbol,SYMBOL_ASK), "\nBid: ",SymbolInfoDouble(_Symbol,SYMBOL_BID)); } } } //CHECK FOR NEW CANDLE bool CheckfornewCandle (int CandleNumber, datetime Currenttime){ static int LastCandleNumber; bool IsNewCandle= false; if (CandleNumber>LastCandleNumber){ IsNewCandle = true; LastCandleNumber = CandleNumber; Print("------New Candle----- Time: ",Currenttime); } return IsNewCandle; } //CHECK FOR ENGULFING PATTERN int CheckEngulfingPatternUp1Net0Down2(double ExtraOverEngulfingPoints, int MaxPriceBufferrange){ int CheckEngulfingPatternUp1Net0Down2Value = 0; for(int i = 2; i < MaxPriceBufferrange; i++){ int iSize = i; double PriceCloseValues[]; CopyClose(_Symbol,PERIOD_CURRENT,0,i,PriceCloseValues); ArraySetAsSeries(PriceCloseValues,true); double PriceOpenValues[]; CopyOpen(_Symbol,PERIOD_CURRENT,0,i,PriceOpenValues); ArraySetAsSeries(PriceOpenValues,true); double PriceLowValues[]; CopyLow(_Symbol,PERIOD_CURRENT,0,i,PriceLowValues); ArraySetAsSeries(PriceLowValues,true); double PriceHighValues[]; CopyHigh(_Symbol,PERIOD_CURRENT,0,i,PriceHighValues); ArraySetAsSeries(PriceHighValues,true); int CandleUp1Neut0Down2[]; ArrayResize(CandleUp1Neut0Down2,iSize); for(int k = 0; k < iSize; k++){ if(PriceOpenValues[k] < PriceCloseValues[k]){CandleUp1Neut0Down2[k] = 1;} else if(PriceOpenValues[k] > PriceCloseValues[k]){CandleUp1Neut0Down2[k] = 2;} else if(PriceOpenValues[k] == PriceCloseValues[k]){CandleUp1Neut0Down2[k] = 0;} } //fängt bei Null an,da bei einstieg in kommendes if derStreak sozusagen 1 ist und Indextechnisch 0 sein muss //UPTREND int Streakcounter = 0; if(CandleUp1Neut0Down2[0] == 1){ int j = 1; int TrenEndIndex = 0; for(j; j < iSize; j++){ if(CandleUp1Neut0Down2[j] == 1){Streakcounter = Streakcounter + 1;} else if(CandleUp1Neut0Down2[j] == 2){TrenEndIndex = j; j = iSize;} else if(CandleUp1Neut0Down2[j] == 0){j = iSize;} }if(TrenEndIndex > 0){ if(PriceHighValues[TrenEndIndex] < SymbolInfoDouble(_Symbol,SYMBOL_ASK) + ExtraOverEngulfingPoints * _Point){ CheckEngulfingPatternUp1Net0Down2Value = 1; break; }else if(TrenEndIndex == 0){break;} } } //DOWNTREND Streakcounter = 0; if(CandleUp1Neut0Down2[0] == 2){ int j = 1; int TrenEndIndex = 0; for(j; j < iSize; j++){ if(CandleUp1Neut0Down2[j] == 2){Streakcounter = Streakcounter + 1;} else if(CandleUp1Neut0Down2[j] == 1){TrenEndIndex = j; j = iSize;} else if(CandleUp1Neut0Down2[j] == 0){j = iSize;} }if(TrenEndIndex > 0){ if(PriceHighValues[TrenEndIndex] < SymbolInfoDouble(_Symbol,SYMBOL_BID) + ExtraOverEngulfingPoints * _Point){ CheckEngulfingPatternUp1Net0Down2Value = 2; break; }else if(TrenEndIndex == 0){break;} } } } return CheckEngulfingPatternUp1Net0Down2Value; } //TRAILING SL void CheckTrailingstop(double TrigTSLRatioPricebeforeTP, int HighLowShift, double MinTSLDistPoints,int ATRHandle, double MaximalSLPoints){ for(int i = PositionsTotal()-1; i >= 0; i--){ string symbol = PositionGetSymbol(i); if(_Symbol == symbol){ ulong PositionTicket = PositionGetInteger(POSITION_TICKET); double PositionOpenprice = PositionGetDouble(POSITION_PRICE_OPEN); double CurrentSL = PositionGetDouble(POSITION_SL); double CurrentTP = PositionGetDouble(POSITION_TP); long PositionType = PositionGetInteger(POSITION_TYPE); string PositionComment = PositionGetString(POSITION_COMMENT); double Price = 0; double LatestHighLow = 0; double NewSL = 0; int LatestHighLowIndex = 0; double MinTSLDistValue = MinTSLDistPoints * _Point; double TPtoOpenpriceDif = MathAbs(PositionOpenprice - CurrentTP); if(PositionType == POSITION_TYPE_BUY && PositionComment == "TSL-Trade"){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); if((CurrentTP != 0 && Price > PositionOpenprice + TPtoOpenpriceDif * TrigTSLRatioPricebeforeTP) || (CurrentTP == 0 && Price > CurrentSL + MinTSLDistValue)){ NewSL = CalcSL(true,HighLowShift,ATRHandle,MaximalSLPoints);//--IMPORTANT NEW SL if(NewSL < CurrentSL || NewSL < PositionOpenprice){NewSL = 0;} } } else if(PositionType == POSITION_TYPE_SELL && PositionComment == "TSL-Trade"){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); if((CurrentTP != 0 && Price < PositionOpenprice - TPtoOpenpriceDif * TrigTSLRatioPricebeforeTP) || (CurrentTP == 0 && Price < CurrentSL - MinTSLDistValue)){ NewSL = CalcSL(false,HighLowShift,ATRHandle,MaximalSLPoints); //--IMPORTANT NEW SL if(NewSL > CurrentSL || NewSL > PositionOpenprice){NewSL = 0;} } } if(NewSL != 0){trade.PositionModify(PositionTicket,NewSL,0);} }//END IF CHECK SYMBOL }//END FOR LOOP } //CALC TP double CalcTP(bool BuyTrueSellFalse,double SL, double MaximalTPPoints, double TPtoOneSLRatio){ double TP = 0; double Price = 0; double MaximalTPDist = MaximalTPPoints * _Point; if(BuyTrueSellFalse == true){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double SLPriceDif = MathAbs(SL - Price); double TPPriceDif = SLPriceDif * TPtoOneSLRatio; if(TPPriceDif > MaximalTPDist) {TP = Price + MaximalTPDist;}//IMPORTANT TP else{TP = Price + TPPriceDif;}//IMPORTANT TP }if(BuyTrueSellFalse == false){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); double SLPriceDif = MathAbs(SL - Price); double TPPriceDif = SLPriceDif * TPtoOneSLRatio; if(TPPriceDif > MaximalTPDist) {TP = Price - MaximalTPDist;}//IMPORTANT TP else{TP = Price - TPPriceDif;}//IMPORTANT TP }return TP; } //CALC SL double CalcSL(bool BuyTrueSellFalse, int HighLowShift, int ATRHandle, double MaximalSLPoints){ double Price = 0; double SL = 0; double SLPriceDif = 0; double MaximalSLDist = MaximalSLPoints * _Point; double ATRValues[]; CopyBuffer(ATRHandle,0,0,1,ATRValues); double LatestHighLow = 0; int LatestHighLowIndex = 0; if(BuyTrueSellFalse == true){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); LatestHighLowIndex = iLowest(_Symbol,PERIOD_CURRENT,MODE_LOW,HighLowShift,0); LatestHighLow = iLow(_Symbol,PERIOD_CURRENT,LatestHighLowIndex); if(MathAbs(LatestHighLow - Price) > MaximalSLDist) {SL = Price - MaximalSLDist;}//--IMPORTANT SL else if(MathAbs(LatestHighLow - Price) < ATRValues[0]) {SL = Price - ATRValues[0];}//--IMPORTANT SL }else if(BuyTrueSellFalse == false){ Price = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); LatestHighLowIndex = iHighest(_Symbol,PERIOD_CURRENT,MODE_HIGH,HighLowShift,0); LatestHighLow = iHigh(_Symbol,PERIOD_CURRENT,LatestHighLowIndex); if(MathAbs(LatestHighLow - Price) > MaximalSLDist) {SL = Price + MaximalSLDist;}//--IMPORTANT SL else if(MathAbs(LatestHighLow - Price) < ATRValues[0]) {SL = Price + ATRValues[0];}//--IMPORTANT SL }return SL; }