#property copyright "Copyright 2023, M & Q Investment Group" #property link "https://www.mql5.com" #property version "1.00" #include CTrade trade; input int MinDistToLastSig = 5; int HandleZigZag; int HandleRSI; input double MaxCandleSizeinPoints = 100; input double MinCandleSizeinPoints = 10; input int TPtoSLRatio = 2; input double RiskPerc = 1; double Lostrades = 0; double Wintrades = 0; double AllWinRatio = 0; double accountbalancebeginning; double accountprofit; int OnInit(){ string NameZigZag = "Market\\ArrowZigZag.ex5"; HandleZigZag = iCustom(_Symbol,PERIOD_CURRENT,NameZigZag,5,5,5); HandleRSI = iRSI(_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE); accountbalancebeginning = AccountInfoDouble(ACCOUNT_BALANCE); //OrderinAction = false; return(INIT_SUCCEEDED); } void OnTick(){ double RSIValue[]; CopyBuffer(HandleRSI,0,0,1,RSIValue); //----SEARCHING THROUG THE ZIGZAGINDICATOR---- double LastHighnLows[6]; int SignalCounter = 0; double ZigZagindiRedTop[]; double ZigZagindiGreenBot[]; double ZigZagindiValue[]; int IndexCurrent = -1, IndexLast = -1; int SignalDirection = 0; int LastsignalI = -1; bool LastSignalReady = false; for(int i = 0; i < 1000; i++){ CopyBuffer(HandleZigZag,1,i,1,ZigZagindiRedTop); CopyBuffer(HandleZigZag,2,i,1,ZigZagindiGreenBot); CopyBuffer(HandleZigZag,0,i,1,ZigZagindiValue); if(ZigZagindiValue[0] > 0){ //IF REDTOP HAS A VALUE if(ZigZagindiRedTop[0] > 0 && SignalCounter < 6){ //INSERT THE VALUE IN GENERAL ARRAY LastHighnLows[SignalCounter] = ZigZagindiValue [0]; //SETTING INFO ABOUT LAST SIGNAL AND DIRECTION if(SignalCounter == 0 && i >= MinDistToLastSig){SignalDirection = -1; LastsignalI = i; LastSignalReady = true;} else if(SignalCounter == 0 && i < MinDistToLastSig){LastsignalI = i; LastSignalReady = false;} else if(SignalCounter == 1 && LastsignalI < MinDistToLastSig){SignalDirection = -1;} //FINISH SIGNAL DOCUMENTATION GOTO NEXT SIGNAL SignalCounter ++; } //IF GREENBOT HAS A VALUE if(ZigZagindiGreenBot[0] > 0 && SignalCounter < 6){ //INSERT THE VALUE IN GENERAL ARRAY LastHighnLows[SignalCounter] = ZigZagindiValue [0]; //SETTING INFO ABOUT LAST SIGNAL AND DIRECTION if(SignalCounter == 0 && i >= MinDistToLastSig){SignalDirection = 1; LastsignalI = i; LastSignalReady = true;} else if(SignalCounter == 0 && i < MinDistToLastSig){LastsignalI = i; LastSignalReady = false;} else if(SignalCounter == 1 && LastsignalI < MinDistToLastSig){SignalDirection = 1;} //FINISH SIGNAL DOCUMENTATION GOTO NEXT SIGNAL SignalCounter ++; } if(SignalCounter == 6){break;} }//END OF IF ZIGZAGARRAY HAS VALUE }//END OF FOR LOOP //----DETERMINE THE TREND---- int TrendUp1No0Down2 = 0; bool TradeInTrenddirection = false; //TREND SIGANAL READY if(LastSignalReady){ if(//DOWNTREND LastHighnLows[0] < LastHighnLows[2] && LastHighnLows[1] < LastHighnLows[3] //&& LastHighnLows[2] < LastHighnLows[4] ){ TrendUp1No0Down2 = 2; if(SignalDirection == -1 && TrendUp1No0Down2 == 2){ TradeInTrenddirection = true; //TRADE BEI 3 LINE STRIKE if(Check2LineStrikeDown() > 0 && RSIValue[0] < 50 && OrdersTotal() == 0 && PositionsTotal() == 0){ double Price = SymbolInfoDouble(_Symbol,SYMBOL_BID); double SL = LastHighnLows[0]; //double SL = Check2LineStrikeDown(); double TP = Price - MathAbs(SL - Price) * TPtoSLRatio; double Lots = CalcLots(RiskPerc,MathAbs(SL - Price)); if(SL != 0){trade.Sell(Lots,_Symbol,Price,SL,TP,"Trade Downtrend after 2LineStrike");} else{Print("--------------------------UNABLE TO TRADE SL IS 0 ----------------------------------");} Print("Check2LineStrikeDown Successful, Placing Trade... Last Candle is smaller than MaxCandleSize: ",MaxCandleSizeinPoints, "\nRSI values are below 50: ",RSIValue[0], "\nTrendUp1No0Down2: ",TrendUp1No0Down2, "\nPrice: ",Price); } } } else if(//UPTREND LastHighnLows[0] > LastHighnLows[2]&& LastHighnLows[1] > LastHighnLows[3] //&& LastHighnLows[2] > LastHighnLows[4] ){ TrendUp1No0Down2 = 1; if(SignalDirection == 1 && TrendUp1No0Down2 == 1){ TradeInTrenddirection = true; //TRADE BEI 3 LINE STRIKE if(Check2LineStrikeUp() > 0 && RSIValue[0] > 50 && OrdersTotal() == 0 && PositionsTotal() == 0){ double Price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); double SL = LastHighnLows[0]; //double SL = Check2LineStrikeUp(); double TP = Price + MathAbs(SL - Price) * TPtoSLRatio; double Lots = CalcLots(RiskPerc,MathAbs(SL - Price)); if(SL != 0){trade.Buy(Lots,_Symbol,Price,SL,TP,"Trade Uptrend after 2LineStrike");} else{Print("--------------------------UNABLE TO TRADE SL IS 0 ----------------------------------");} Print("Check2LineStrikeUP Successful, Placing Trade... Last Candle is smaller than MaxCandleSize: ",MaxCandleSizeinPoints, "\nRSI values are above 50: ",RSIValue[0], "\nTrendUp1No0Down2: ",TrendUp1No0Down2, "\nPrice: ",Price); } } } else{TrendUp1No0Down2 = 0;} }// END TREND SIGANAL READY //TREND SIGNAL NOT READY => LAST SIGNAL if(LastSignalReady == false){ if(//DOWNTREND LastHighnLows[1] < LastHighnLows[3]&& LastHighnLows[2] < LastHighnLows[4] //&& LastHighnLows[3] < LastHighnLows[5] ){TrendUp1No0Down2 = 2; if(SignalDirection == -1 && TrendUp1No0Down2 == 2){ TradeInTrenddirection = true; //TRADE BEI 3 LINE STRIKE if(Check2LineStrikeDown() > 0 && RSIValue[0] < 50 && OrdersTotal() == 0 && PositionsTotal() == 0){ double Price = SymbolInfoDouble(_Symbol,SYMBOL_BID); double SL = LastHighnLows[1]; //double SL = Check2LineStrikeDown(); double TP = Price - MathAbs(SL - Price) * TPtoSLRatio; double Lots = CalcLots(RiskPerc,MathAbs(SL - Price)); if(SL != 0){trade.Sell(Lots,_Symbol,Price,SL,TP,"Trade Downtrend after 2LineStrike");} else{Print("--------------------------UNABLE TO TRADE SL IS 0 ----------------------------------");} Print("Check2LineStrikeDown Successful, Placing Trade... Last Candle is smaller than MaxCandleSize: ",MaxCandleSizeinPoints, "\nRSI values are below 50: ",RSIValue[0], "\nTrendUp1No0Down2: ",TrendUp1No0Down2, "\nPrice: ",Price); } } } else if(//UPTREND LastHighnLows[1] > LastHighnLows[3]&& LastHighnLows[2] > LastHighnLows[4] //&& LastHighnLows[3] > LastHighnLows[5] ){TrendUp1No0Down2 = 1; if(SignalDirection == 1 && TrendUp1No0Down2 == 1){ TradeInTrenddirection = true; //TRADE BEI 3 LINE STRIKE if(Check2LineStrikeUp() > 0 && RSIValue[0] > 50 && OrdersTotal() == 0 && PositionsTotal() == 0){ double Price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); double SL = LastHighnLows[1]; //double SL = Check2LineStrikeUp(); double TP = Price + MathAbs(SL - Price) * TPtoSLRatio; double Lots = CalcLots(RiskPerc,MathAbs(SL - Price)); if(SL != 0){trade.Buy(Lots,_Symbol,Price,SL,TP,"Trade Uptrend after 2LineStrike");} else{Print("--------------------------UNABLE TO TRADE SL IS 0 ----------------------------------");} Print("Check2LineStrikeUP Successful, Placing Trade... Last Candle is smaller than MaxCandleSize: ",MaxCandleSizeinPoints, "\nRSI values are above 50: ",RSIValue[0], "\nTrendUp1No0Down2: ",TrendUp1No0Down2, "\nPrice: ",Price); } } } else{TrendUp1No0Down2 = 0;} }//END TREND SIGNAL NOT READY => LAST SIGNAL double accountequity = AccountInfoDouble(ACCOUNT_EQUITY); accountprofit = accountequity - accountbalancebeginning; accountprofit = NormalizeDouble(accountprofit,2); Comment("\nCurrenttime: ",TimeCurrent(), "\nProfit: ",accountprofit, "\nEquity: ",accountequity, "\nCurrent Trend, TrendUp1No0Down2: ",TrendUp1No0Down2, "\n Trade in Trenddirection: ",TradeInTrenddirection, "\nRSI Value: ",NormalizeDouble(RSIValue[0],2)); }//END ON TICK 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); } //CHECK FOR 2 LINE STRIKE DOWN double Check2LineStrikeDown(){ double Open1 = iOpen(_Symbol,PERIOD_CURRENT,1); double Close1 = iClose(_Symbol,PERIOD_CURRENT,1); double High1 = iHigh(_Symbol,PERIOD_CURRENT,1); double Open2 = iOpen(_Symbol,PERIOD_CURRENT,2); double Close2 = iClose(_Symbol,PERIOD_CURRENT,2); double High2 = iHigh(_Symbol,PERIOD_CURRENT,2); double Open3 = iOpen(_Symbol,PERIOD_CURRENT,3); double Close3 = iClose(_Symbol,PERIOD_CURRENT,3); if(Open3 < Close3 && Open2 < Close2 && Open1 > Close1 && Close1 < Open2 && MaxCandleSizeinPoints * _Point > MathAbs(Close1 - Open1) && MinCandleSizeinPoints * _Point < MathAbs(Close1 - Open1) && MathAbs(Open1 - Close2) < 5 * _Point){ if(High1 < High2){return High2;} else if(High1 > High2){return High1;} else{return High1;} }else{ return 0; } } //CHECK FOR 2 LINE STRIKE UP double Check2LineStrikeUp(){ double Open1 = iOpen(_Symbol,PERIOD_CURRENT,1); double Close1 = iClose(_Symbol,PERIOD_CURRENT,1); double Low1 = iLow(_Symbol,PERIOD_CURRENT,1); double Open2 = iOpen(_Symbol,PERIOD_CURRENT,2); double Close2 = iClose(_Symbol,PERIOD_CURRENT,2); double Low2 = iLow(_Symbol,PERIOD_CURRENT,2); double Open3 = iOpen(_Symbol,PERIOD_CURRENT,3); double Close3 = iClose(_Symbol,PERIOD_CURRENT,3); if(Open3 > Close3 && Open2 > Close2 && Open1 < Close1 && Close1 > Open2 && MaxCandleSizeinPoints * _Point > MathAbs(Close1 - Open1) && MinCandleSizeinPoints * _Point < MathAbs(Close1 - Open1) && MathAbs(Open1 - Close2) < 5 * _Point){ if(Low1 > Low2){return Low2;} else if(Low1 < Low2){return Low1;} else{return Low1;} }else{ return 0; } } //DYNAMIC LOT CALCULATION double CalcLots(double riskPercent, double SLDistance){ double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); double Lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); if(ticksize == 0 || tickvalue == 0 || Lotstep == 0){ Print(__FUNCTION__,"Lotsize cannot be calculated"); return 0;} double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent /100; double MoneyperLotstep = (SLDistance / ticksize) * tickvalue * Lotstep; if(MoneyperLotstep == 0){ Print(__FUNCTION__,"Lotsize cannot be calculated"); return 0;} double lots = MathFloor(riskMoney / MoneyperLotstep) * Lotstep; return lots; }