352 linhas
12 KiB
MQL5
352 linhas
12 KiB
MQL5
// Include the necessary libraries
|
|
#include <Trade\Trade.mqh>
|
|
#include <Trade\PositionInfo.mqh>
|
|
|
|
// Input parameters
|
|
input double LotSize = 0.01;
|
|
input ENUM_TIMEFRAMES Timeframe = PERIOD_M3;
|
|
input int MALen = 100;
|
|
input double TakeProfit = 0;
|
|
input double StopLoss = 0;
|
|
input double FixedLot = 0;
|
|
input int PositionsThreshold = 1;
|
|
input string GMTstartTime = "11:30";
|
|
input string GMTendTime = "17:30";
|
|
|
|
int Grid = 100;
|
|
double StopLossBuy;
|
|
double StopLossSell;
|
|
bool upStruct = NULL;
|
|
|
|
|
|
double FractalsUp[], FractalsDown[], MA[], bid, ask;
|
|
int FractalsHandle, MAHandle;
|
|
// Create an instance of the Trade library
|
|
CTrade trade;
|
|
CPositionInfo PosInfo;
|
|
|
|
// Create instances of the required indicators
|
|
// Expert Advisor initialization function
|
|
int OnInit()
|
|
{
|
|
|
|
FractalsHandle = iFractals(_Symbol,Timeframe);
|
|
MAHandle = iMA(_Symbol,Timeframe,MALen,0,MODE_EMA,PRICE_MEDIAN);
|
|
ArraySetAsSeries(FractalsUp, true);
|
|
ArraySetAsSeries(FractalsDown, true);
|
|
ArraySetAsSeries(MA, true);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
// Expert Advisor start function
|
|
void OnTick()
|
|
{
|
|
MqlRates Bar1;
|
|
MqlDateTime dt;
|
|
datetime gmtTime = TimeGMT(dt);
|
|
|
|
bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
|
|
ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
|
|
|
|
CopyBuffer(FractalsHandle,0,0,10,FractalsUp);
|
|
CopyBuffer(FractalsHandle,1,0,10,FractalsDown);
|
|
CopyBuffer(MAHandle,0,0,10,MA);
|
|
|
|
//bool tradetime = (dt.hour == 8 || dt.hour == 14 || dt.hour == 0 || dt.hour == 1);
|
|
bool tradetime = ((StringToTime(GMTstartTime) < StringToTime(GMTendTime) && gmtTime >= StringToTime(GMTstartTime) && gmtTime <= StringToTime(GMTendTime)) || (StringToTime(GMTstartTime) > StringToTime(GMTendTime) && gmtTime <= StringToTime(GMTstartTime) && gmtTime >= StringToTime(GMTendTime)));
|
|
|
|
|
|
//Print("ArrayUp");
|
|
//ArrayPrint(FractalsUp);
|
|
//Print("ArrayDown");
|
|
//ArrayPrint(FractalsDown);
|
|
// Check if the current price is above or below the 26 EMA
|
|
bool isPriceAboveEMA = (bid > MA[1]);
|
|
|
|
// Check for up fractal to enter sell and close all buys
|
|
int bar = 0;
|
|
if(bar < iBars(_Symbol,Timeframe))
|
|
{
|
|
|
|
|
|
if (FractalsUp[2] < 10000 && FractalsUp[2] >= ask)
|
|
{
|
|
upStruct = false;
|
|
StopLossSell = FractalsUp[2];
|
|
StoplossUpdate("sell");
|
|
}
|
|
if(!upStruct && tradetime && !isPriceAboveEMA && SellPositionsCount() < PositionsThreshold)
|
|
//
|
|
{
|
|
trade.Sell(FixedLot,_Symbol, 0, FractalsUp[2], 0);
|
|
}
|
|
|
|
|
|
// Check for down fractal to enter buy and close all sells
|
|
if (FractalsDown[2] < 10000 && FractalsDown[2] <= bid)
|
|
{
|
|
upStruct = true;
|
|
StopLossBuy = FractalsDown[2];
|
|
StoplossUpdate("buy");
|
|
}
|
|
if(upStruct && tradetime && isPriceAboveEMA && BuyPositionsCount() < PositionsThreshold)
|
|
//
|
|
{
|
|
trade.Buy(FixedLot,_Symbol, 0, FractalsDown[2], 0);
|
|
}
|
|
|
|
bar = iBars(_Symbol,Timeframe);
|
|
}
|
|
}
|
|
// Expert Advisor deinitialization function
|
|
void OnDeinit(const int reason)
|
|
{
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseAllPositions()
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
|
|
if(PosInfo.SelectByIndex(i)) // select a position
|
|
{
|
|
trade.PositionClose(PosInfo.Ticket());
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseBuys()
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
|
|
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
|
|
{
|
|
double thebuy = PosInfo.PriceOpen();
|
|
int theBuyTicket = PosInfo.Ticket();
|
|
|
|
|
|
trade.PositionClose(theBuyTicket);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseSells()
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
|
|
if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL)
|
|
{
|
|
double thesell = PosInfo.PriceOpen();
|
|
int theSellTicket = PosInfo.Ticket();
|
|
|
|
|
|
trade.PositionClose(theSellTicket);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int BuyPositionsCount()
|
|
{
|
|
int Buys = 0;
|
|
for(int i = PositionsTotal()-1; i>=0; i--)
|
|
{
|
|
PositionGetTicket(i);
|
|
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
Buys = Buys+1;
|
|
}
|
|
}
|
|
return Buys;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int SellPositionsCount()
|
|
{
|
|
int Sells = 0;
|
|
for(int i = PositionsTotal()-1; i>=0; i--)
|
|
{
|
|
PositionGetTicket(i);
|
|
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
Sells = Sells+1;
|
|
}
|
|
}
|
|
return Sells;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseByWinning()
|
|
{
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
|
|
if(PosInfo.SelectByIndex(i))
|
|
{
|
|
if(PosInfo.PositionType() == POSITION_TYPE_BUY)
|
|
{
|
|
double thebuy = PosInfo.PriceOpen();
|
|
int theBuyTicket = PosInfo.Ticket();
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
if(PosInfo.SelectByIndex(i))
|
|
{
|
|
if(PosInfo.PositionType() == POSITION_TYPE_SELL)
|
|
{
|
|
double thesell = PosInfo.PriceOpen();
|
|
int theSellTicket = PosInfo.Ticket();
|
|
|
|
if(thesell - thebuy > 0)
|
|
{
|
|
trade.PositionCloseBy(theBuyTicket,theSellTicket);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CloseByLosing()
|
|
{
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
|
|
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
|
|
{
|
|
double thebuy = PosInfo.PriceOpen();
|
|
int theBuyTicket = PosInfo.Ticket();
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL)
|
|
{
|
|
double thesell = PosInfo.PriceOpen();
|
|
int theSellTicket = PosInfo.Ticket();
|
|
|
|
if(thesell - thebuy < -Grid*_Point)
|
|
{
|
|
trade.PositionCloseBy(theBuyTicket,theSellTicket);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void StoplossUpdate(string comment)
|
|
{
|
|
|
|
int buyCount = BuyPositionsCount();
|
|
int sellCount = SellPositionsCount();
|
|
double meanEntryBuy = meanEntryPrice("Buy");
|
|
double meanEntrySell = meanEntryPrice("Sell");
|
|
|
|
for(int i=PositionsTotal()-1; i>=0; i--)
|
|
{
|
|
ulong PositionTicket = PositionGetTicket(i);
|
|
long trade_type = PositionGetInteger(POSITION_TYPE);
|
|
if(trade_type == POSITION_TYPE_BUY && (comment == "buy" || comment == "both"))
|
|
{
|
|
double risk = PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_SL);
|
|
double newStopLoss = StopLossBuy;
|
|
double reward = ask - PositionGetDouble(POSITION_PRICE_OPEN);
|
|
if(reward > 2*risk && PositionGetDouble(POSITION_SL) < StopLossBuy)
|
|
newStopLoss = NormalizeDouble((ask + PositionGetDouble(POSITION_PRICE_OPEN))/2,_Digits);
|
|
if(PositionGetDouble(POSITION_SL) < newStopLoss)
|
|
trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP));
|
|
}
|
|
if(trade_type == POSITION_TYPE_SELL && (comment == "sell" || comment == "both"))
|
|
{
|
|
double risk = PositionGetDouble(POSITION_SL) - PositionGetDouble(POSITION_PRICE_OPEN);
|
|
double newStopLoss = StopLossSell;
|
|
double reward = PositionGetDouble(POSITION_PRICE_OPEN) - ask;
|
|
if(reward > 2*risk && PositionGetDouble(POSITION_SL) > StopLossSell)
|
|
newStopLoss = NormalizeDouble((ask + PositionGetDouble(POSITION_PRICE_OPEN))/2,_Digits);
|
|
if(PositionGetDouble(POSITION_SL) > newStopLoss || PosInfo.StopLoss() == 0)
|
|
trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP));
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double meanEntryPrice(string type)
|
|
{
|
|
|
|
double quantity = 0;
|
|
double volume = 0;
|
|
double entry = 0;
|
|
|
|
|
|
for(int i = PositionsTotal()-1; i>=0; i--)
|
|
{
|
|
PositionGetTicket(i);
|
|
|
|
//////////////////////////////////
|
|
|
|
if(type == "Buy" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
if(type == "Sell" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
if(type == "Total" && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
|
|
}
|
|
|
|
|
|
if(type == "BuysAbove" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
|
|
if(type == "BuysBelow" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
|
|
|
|
/////////////////////////////
|
|
|
|
|
|
|
|
if(type == "SellsAbove" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
if(type == "SellsBelow" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
|
|
|
|
{
|
|
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
|
|
volume = volume + PosInfo.Volume();
|
|
}
|
|
}
|
|
|
|
entry = quantity / volume;
|
|
return entry;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|