297 lines
27 KiB
MQL5
297 lines
27 KiB
MQL5
#property copyright "Copyright 2023, M & Q Investment Group"
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
#include <trade/trade.mqh>
|
|
CTrade trade;
|
|
|
|
input int MinDistToLastSig = 5;
|
|
input double MaxCandleSizeinPoints = 100;
|
|
input double MinCandleSizeinPoints = 10;
|
|
input int TPtoSLRatio = 2;
|
|
input double RiskPerc = 1;
|
|
input double MaxDistancetoIndforRejPoints = 10;
|
|
input int SLLasthighorlowRange = 10;
|
|
//input double MinimalRejWigSizePoints = 5;
|
|
|
|
int HandleZigZag;
|
|
int HandleRSI;
|
|
int HandleMA200;
|
|
int HandleMA50;
|
|
int HandleMA21;
|
|
int TrendUp1No0Down2 = 0;
|
|
|
|
double Lostrades = 0;
|
|
double Wintrades = 0;
|
|
double AllWinRatio = 0;
|
|
|
|
double accountbalancebeginning;
|
|
double accountprofit;
|
|
|
|
int OrderCooldownSec = 300;
|
|
datetime OrderCooldownTime = 0;
|
|
|
|
int OnInit(){
|
|
|
|
string NameZigZag = "Market\\ArrowZigZag.ex5";
|
|
HandleZigZag = iCustom(_Symbol,PERIOD_CURRENT,NameZigZag,7,5,6);
|
|
HandleRSI = iRSI(_Symbol,PERIOD_CURRENT,14,PRICE_CLOSE);
|
|
HandleMA200 = iMA(_Symbol,PERIOD_CURRENT,200,0,MODE_SMMA,PRICE_CLOSE);
|
|
HandleMA50 = iMA(_Symbol,PERIOD_CURRENT,50,0,MODE_SMMA,PRICE_CLOSE);
|
|
HandleMA21 = iMA(_Symbol,PERIOD_CURRENT,21,0,MODE_SMMA,PRICE_CLOSE);
|
|
accountbalancebeginning = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
//OrderinAction = false
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
|
|
void OnTick(){
|
|
datetime Currenttime = TimeCurrent();
|
|
//CHECKING FOR 3LINESTRIKE PATTERN TO REDUCE OVERALL CALCULATION TIME
|
|
if((Check2LineStrikeDown() || Check2LineStrikeUp()) && Currenttime > OrderCooldownTime){
|
|
|
|
//PREPARING BASIC INDICATORS
|
|
double RSIValue[];
|
|
CopyBuffer(HandleRSI,0,0,1,RSIValue);
|
|
double MA200Value[];
|
|
CopyBuffer(HandleMA200,0,0,1,MA200Value);
|
|
double MA50Value[];
|
|
CopyBuffer(HandleMA50,0,0,1,MA50Value);
|
|
double MA21Value[];
|
|
CopyBuffer(HandleMA21,0,0,1,MA21Value);
|
|
|
|
//CHECK FOR PRICE IN ZONE
|
|
if(CheckForREjection(MA21Value[0],MA50Value[0],MA200Value[0],MaxDistancetoIndforRejPoints)){
|
|
|
|
//PREPARING THE TRENDDETECTOR
|
|
int IndexCurrent = -1, IndexLast = -1;
|
|
int SignalDirection = 0;
|
|
int LastsignalI = -1;
|
|
bool LastSignalReady = false;
|
|
int SignalCounter = 0;
|
|
|
|
double ZigZagindiRedTop[];
|
|
double ZigZagindiGreenBot[];
|
|
double ZigZagindiValue[];
|
|
double LastHighnLows[6];
|
|
|
|
//----------------------------------------SEARCHING THROUG THE ZIGZAGINDICATOR----
|
|
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
|
|
//----------------------------------------END SEARCHING THROUG THE ZIGZAGINDICATOR----
|
|
|
|
//-----------------------------------------------DETERMINE THE TREND----
|
|
|
|
if(//----------------------------------------------DOWNTREND-----
|
|
LastHighnLows[0] < LastHighnLows[2] &&
|
|
LastHighnLows[1] < LastHighnLows[3]
|
|
//&& LastHighnLows[2] < LastHighnLows[4]
|
|
){
|
|
TrendUp1No0Down2 = 2;
|
|
//TRADE BEI 3 LINE STRIKE DOWNTREND
|
|
if(Check2LineStrikeDown() > 0 && OrdersTotal() == 0 && PositionsTotal() == 0){
|
|
|
|
double Price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
|
|
int SLSourceIndex = iHighest(_Symbol,PERIOD_CURRENT,MODE_HIGH,SLLasthighorlowRange,0);
|
|
double SL = iHigh(_Symbol,PERIOD_CURRENT,SLSourceIndex);
|
|
//double SL = NormalizeDouble(LastHighnLows[0],_Digits);
|
|
//double SL = Check2LineStrikeDown();
|
|
double TP = NormalizeDouble(Price - MathAbs(SL - Price) * TPtoSLRatio,_Digits);
|
|
double Lots = NormalizeDouble(CalcLots(RiskPerc,MathAbs(SL - Price)),2);
|
|
|
|
if(SL != 0){trade.Sell(Lots,_Symbol,Price,SL,TP,"Trade Downtrend after 2LineStrike");
|
|
OrderCooldownTime = Currenttime + OrderCooldownSec;}
|
|
|
|
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;
|
|
|
|
//TRADE BEI 3 LINE STRIKE
|
|
if(Check2LineStrikeUp() > 0 && OrdersTotal() == 0 && PositionsTotal() == 0){
|
|
|
|
double Price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
|
|
int SLSourceIndex = iLowest(_Symbol,PERIOD_CURRENT,MODE_HIGH,SLLasthighorlowRange,0);
|
|
double SL = iLow(_Symbol,PERIOD_CURRENT,SLSourceIndex);
|
|
//double SL = NormalizeDouble(LastHighnLows[0],_Digits);
|
|
//double SL = Check2LineStrikeUp();
|
|
double TP = NormalizeDouble(Price + MathAbs(SL - Price) * TPtoSLRatio,_Digits);
|
|
double Lots = NormalizeDouble(CalcLots(RiskPerc,MathAbs(SL - Price)),2);
|
|
|
|
if(SL != 0){trade.Buy(Lots,_Symbol,Price,SL,TP,"Trade Uptrend after 2LineStrike");
|
|
OrderCooldownTime = Currenttime + OrderCooldownSec;}
|
|
|
|
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 IF CHECK FOR PRICE IN MAs ZONE
|
|
}//------------------------------------------------------END IF THERE IS A STRIKE PATTERN
|
|
|
|
//GENERAL INFORMATION FOR THE CHART
|
|
double accountequity = AccountInfoDouble(ACCOUNT_EQUITY);
|
|
accountprofit = accountequity - accountbalancebeginning;
|
|
accountprofit = NormalizeDouble(accountprofit,2);
|
|
|
|
Comment("\nCurrenttime: ",TimeCurrent(),
|
|
"\nProfit: ",accountprofit,
|
|
"\nEquity: ",accountequity,
|
|
"\nCurrent Trend, TrendUp1No0Down2: ",TrendUp1No0Down2);
|
|
|
|
}//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;
|
|
}
|
|
|
|
//CHECK FOR REJECTION
|
|
bool CheckForREjection(double MA21Value, double MA50Value, double MA200Value, double MaxDistance/*, double MinimalRejWigSizePointz*/){
|
|
|
|
double Open1 = iOpen(_Symbol,PERIOD_CURRENT,1);
|
|
double Close1 = iClose(_Symbol,PERIOD_CURRENT,1);
|
|
double Low1 = iLow(_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 Low2 = iLow(_Symbol,PERIOD_CURRENT,2);
|
|
double High2 = iHigh(_Symbol,PERIOD_CURRENT,2);
|
|
double MA21ValueLow = MA21Value - MaxDistance * _Point;
|
|
double MA21ValueHigh = MA21Value + MaxDistance * _Point;
|
|
double MA50ValueLow = MA50Value - MaxDistance * _Point;
|
|
double MA50ValueHigh = MA50Value + MaxDistance * _Point;
|
|
double MA200ValueLow = MA200Value - MaxDistance * _Point;
|
|
double MA200ValueHigh = MA200Value + MaxDistance * _Point;
|
|
|
|
if((MA200ValueLow > Low1 && MA200ValueLow < High1) || (MA200ValueHigh > Low1 && MA200ValueHigh < High1)
|
|
|| (MA50ValueLow > Low1 && MA50ValueLow < High1) || (MA50ValueHigh > Low1 && MA50ValueHigh < High1)
|
|
|| (MA21ValueLow > Low1 && MA21ValueLow < High1) || (MA21ValueHigh > Low1 && MA21ValueHigh < High1)){
|
|
|
|
//MinimalRejWigSizePointz;
|
|
return true;
|
|
//bedingungen müssen noch so angepasst werden, dass falls muster auftritt und trend besteht getraded wird unabhängig wie weit letztes
|
|
//hoch entfernt ist oder welcher schenkel gerade der kurs ist
|
|
}else{return false;}
|
|
|
|
}
|