Files
2026-06-08 10:36:15 +02:00

410 lines
12 KiB
Plaintext

//+------------------------------------------------------------------+
//| ThreeBarPlay.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| trading mechanics is the same as BUYSTOCK/SELLSTOCK scripts |
//+------------------------------------------------------------------+
int numOfTrades=0;
int takeprofit=100;
int stoploss=100;
void trade(bool buy, int sl)
{
numOfTrades++;
if(buy)
{
int pips=sl;
double risk=AccountBalance()*0.02/1.3;
double shares = (int)(risk / pips * 100);
double maxShares = (int)(AccountFreeMargin()/1.3 * 14.8 / (Ask));
if((MarketInfo(_Symbol,17))<0.01)//if forex
{
maxShares/=100;
shares/=100;
}
if(shares>(MarketInfo(_Symbol,MODE_MAXLOT)))
{
shares=MarketInfo(_Symbol,MODE_MAXLOT);
}
if(maxShares < shares)
{
shares = maxShares;
pips=(int)(risk/shares*100);
}
Alert("Buy ",shares," shares of ", _Symbol);
double x=Ask;
double y=shares*0.67;
double z=shares*0.33;
int pipstostoploss=pips;
int takeprofit2= pips;
int takeprofit1= (int)(pips/2);
int order0=OrderSend(
_Symbol,//currencyPair
OP_BUY,//buy
y,//howmuch*SYMBOL_VOLUME_MIN
x,//price
3,//tolerance
x-pipstostoploss*_Point, //stoploss
x+takeprofit1*_Point,//takeprofit
NULL,//comment
0,//magic number
0,//expiration
CLR_NONE//color of arrow
);
int order1=OrderSend(
_Symbol,//currencyPair
OP_BUY,//buy
z,//howmuch*SYMBOL_VOLUME_MIN
x,//price
3,//tolerance
x-pipstostoploss*_Point, //stoploss
x+takeprofit2*_Point,//takeprofit
NULL,//comment
0,//magic number
0,//expiration
CLR_NONE//color of arrow
);
}
else
if(!buy)
{
int pips=sl;
double risk=AccountBalance()*0.02/1.3;
double shares = (int)(risk / pips * 100);
double maxShares = (int)(AccountFreeMargin()/1.3 * 14.8 / (Bid));
if((MarketInfo(_Symbol,17))<0.01)//if forex
{
maxShares/=100;
shares/=100;
}
if(shares>(MarketInfo(_Symbol,MODE_MAXLOT)))
{
shares=MarketInfo(_Symbol,MODE_MAXLOT);
}
if(maxShares < shares)
{
shares = maxShares;
pips=(int)(risk/shares*100);
}
Alert("Sell ",shares," shares of ", _Symbol);
double x=Bid;
double y=shares*0.67;
double z=shares*0.33;
int pipstostoploss=pips;
int takeprofit2= pips;
int takeprofit1= (int)(pips/2);
int order0=OrderSend(
_Symbol,//currencyPair
OP_SELL,//sell
y,//howmuch*SYMBOL_VOLUME_MIN
x,//price
3,//tolerance
x+pipstostoploss*_Point, //stoploss
x-takeprofit1*_Point,//takeprofit
NULL,//comment
0,//magic number
0,//expiration
CLR_NONE//color of arrow
);
int order1=OrderSend(
_Symbol,//currencyPair
OP_SELL,//sell
z,//howmuch*SYMBOL_VOLUME_MIN
x,//price
3,//tolerance
x+pipstostoploss*_Point, //stoploss
x-takeprofit2*_Point,//takeprofit
NULL,//comment
0,//magic number
0,//expiration
CLR_NONE//color of arrow
);
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
double height;
bool traded=false;
void OnTick()
{
//find average size of candlesticks
int numOfCandles=200;
double total=0;
for(int i=0; i<numOfCandles; i++)
{
total+=(MathAbs(Open[i]-Close[i]));
}
double average=(int)((total/numOfCandles)/_Point);
//average volume
double totalVol=0;
for(int i=0; i<50; i++)
{
totalVol+=Volume[i];
}
double averageVol=(totalVol/(50));
//delete all trades with second candle doji
bool doji=false;
bool hammer =false;
bool star=false;
double high=High[1];
double low=Low[1];
double open=Open[1];
double close=Close[1];
double body=open-close;
double top=0;
double bot=0;
double topratio,botratio;
if(body>0)
{
top=high-close;
bot=open-low;
}
else
if(body<0)
{
top=high-open;
bot=close-low;
}
if(body!=0)
{
topratio=top/(MathAbs(body));
botratio=bot/(MathAbs(body));
}
else
{
//if body is 0
topratio=0;
botratio=0;
}
double dojiratio=1;
if((botratio>=dojiratio)&&(topratio>=dojiratio)&&(botratio>=(dojiratio+2))&&(topratio>=(dojiratio+2)))
{
doji=true;
if((botratio/topratio)>=2)
{
doji=false;
hammer=true;
}
else
if((topratio/botratio)>=2)
{
doji=false;
star=true;
}
}
else
if((botratio>=dojiratio)&&(botratio>=(dojiratio+2)))
{
hammer=true;
}
else
if((topratio>=(dojiratio+2))&&(topratio>=dojiratio))
{
star=true;
}
/*
calculations:
if spread<=16, then look for plays
ignition is any bar [a certain number] times or more than spread
correction is if second bar is less than 1 quarter ignition in op direction
enter trade when bid passes the ignition close
stoploss will be at ignition's open+spread
*/
//init variables
double MFI=iMFI(_Symbol,_Period,14,0);
int spread=SYMBOL_SPREAD;
double goldenNum=0.8;
double goldenMax=10;
double goldenNum2=2.5;
bool bull=false;
bool bear=false;
bool ignition=false;
bool correction=false;
bool confirmation=false;
bool rejection=false;
int height2=(int)((Close[2]-Open[2])/_Point);
int height1=(int)((Close[1]-Open[1])/_Point);
//one trade per 3barcombo
if(height!=Close[1])
{
traded=false;
}
//ignition : any bar [a certain number] times or more than average candle
if((height2>=(goldenNum*average))&&(height2<=(goldenMax*average)))
{
ignition=true;
//bull
bull=true;
bear=false;
}
if((height2<=(goldenNum*-1*average))&&(height2>=(goldenMax*-1*average)))
{
ignition=true;
bear=true;
bull=false;
height2*=-1;
}
//correction : second bar is less than [a second certain number] times of ignition in op direction
if(bull && (height1<-2) && (height1>=((-1)*height2/goldenNum2)))
{
if(!doji && !star)
{
correction=true;
}
}
else
if((bear &&(height1>2) && (height1<=(height2/goldenNum2))))
{
if(!doji && !hammer)
{
correction=true;
}
}
//confirmation : when the price passes the ignition close
if(((bull)&&(Ask>=(Close[2]+(spread*_Point))))||((bear)&&(Bid<=(Close[2]-(spread*_Point)))))
{
if(correction)
{
confirmation=true;
}
}
else
{
if(((bull)&&(Bid<=(Close[1]-(1.5*spread*_Point))))||((bear)&&(Ask>=(Close[1]+(1.5*spread*_Point)))))
{
if((bull==true)&&(bear==false)&&(star||doji))
{
rejection=true;
bear=true;
bull=false;
}
else
if((bear==true)&&(bull==false)&&(hammer||doji))
{
rejection=true;
bull=true;
bear=false;
}
}
}
//make trade if all true
//only trade with higher than average relative volume
bool withVol=false;
withVol=((Volume[1]/averageVol)>=1);
//trading format "trade(bool buy,int pipstostoploss));"
if(ignition && correction && confirmation && bull && !traded && withVol)
{
//buy after confirmation
stoploss=height2+(2*spread);
takeprofit=stoploss/2;
trade(true,stoploss);
traded=true;
}
else
if(ignition && correction && confirmation && bear && !traded && withVol)
{
//sell after confirmation
stoploss=height2+(2*spread);
takeprofit=stoploss/2;
trade(false,stoploss);
traded=true;
}
else
if(!traded && ignition && bull && rejection && withVol)
{
//buy after rejection
stoploss=height2+spread;
takeprofit=stoploss/2;
trade(true,stoploss);
traded=true;
}
else
if(!traded && ignition && bear && rejection && withVol)
{
//sell after rejection
stoploss=height2+spread;
takeprofit=stoploss/2;
trade(false,stoploss);
traded=true;
}
Comment(
"balance : ",AccountBalance(),"\n",
"ignition : ",ignition,"\n",
"correction : ",correction,"\n",
"confirmation: ",confirmation,"\n",
"doji: ",doji,"\n",
"hammer: ",hammer,"\n",
"star: ",star,"\n",
numOfTrades," trades "
);
height=Close[1];
//if there is a trade open, make a trailing stop while profitable by 20+ pips
if(OrdersTotal()>0)
{
for(int i=OrdersTotal(); i>=0; i--)
{
int pips=(int)(takeprofit);
//select an order
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
//make sure its the right currency pair
if(OrderSymbol()==_Symbol)
{
//check if buy or sell
if(OrderType()==OP_BUY)
{
if((Bid>(OrderOpenPrice()+pips*_Point))&&(OrderStopLoss()<OrderOpenPrice()) && (OrderStopLoss()<(Ask-pips*_Point)))
{
bool evenbuy=OrderModify(OrderTicket(),OrderOpenPrice(),Ask-pips*_Point,OrderTakeProfit(),0);
}
}
else
if(OrderType()==OP_SELL)
{
if((Ask<(OrderOpenPrice()-pips*_Point))&&(OrderStopLoss()>OrderOpenPrice()) && (OrderStopLoss()>(Bid+pips*_Point)))
{
bool evensell=OrderModify(OrderTicket(),OrderOpenPrice(),Bid+pips*_Point,OrderTakeProfit(),0);
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+