152 lines
No EOL
4.5 KiB
MQL5
152 lines
No EOL
4.5 KiB
MQL5
#property strict
|
|
#property version "2.10"
|
|
|
|
#include <Trade/Trade.mqh>
|
|
CTrade Trade;
|
|
|
|
//================ INPUT PARAMETERS ==================//
|
|
input int MagicNumber = 456789;
|
|
input double Risk_Per_Trade = 1.0;
|
|
input int SR_Lookback_Bars = 50;
|
|
input int SR_Buffer_Points = 30;
|
|
|
|
input ENUM_TIMEFRAMES Trend_Timeframe = PERIOD_H1;
|
|
input int Fast_EMA = 50;
|
|
input int Slow_EMA = 200;
|
|
|
|
input int Initial_SL_Points = 150;
|
|
input int BreakEven_Points = 120;
|
|
input double Min_Profit_Lock_Percent = 2.0;
|
|
|
|
input int Trailing_Step_Points = 40;
|
|
input int Max_Open_Trades = 1;
|
|
|
|
//================ GLOBAL ==================//
|
|
ulong EA_PositionTicket = 0;
|
|
|
|
//================ LOT SIZE ==================//
|
|
double GetLotSize(int sl_points)
|
|
{
|
|
double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * Risk_Per_Trade / 100.0;
|
|
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
|
|
|
double lot = riskMoney / ((sl_points * _Point / tickSize) * tickValue);
|
|
return NormalizeDouble(lot, 2);
|
|
}
|
|
|
|
//================ TREND FILTER ==================//
|
|
bool GetTrend(bool &uptrend, bool &downtrend)
|
|
{
|
|
int fastHandle = iMA(_Symbol, Trend_Timeframe, Fast_EMA, 0, MODE_EMA, PRICE_CLOSE);
|
|
int slowHandle = iMA(_Symbol, Trend_Timeframe, Slow_EMA, 0, MODE_EMA, PRICE_CLOSE);
|
|
|
|
if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE)
|
|
return false;
|
|
|
|
double fastBuf[1], slowBuf[1];
|
|
|
|
if(CopyBuffer(fastHandle, 0, 0, 1, fastBuf) <= 0) return false;
|
|
if(CopyBuffer(slowHandle, 0, 0, 1, slowBuf) <= 0) return false;
|
|
|
|
uptrend = fastBuf[0] > slowBuf[0];
|
|
downtrend = fastBuf[0] < slowBuf[0];
|
|
|
|
IndicatorRelease(fastHandle);
|
|
IndicatorRelease(slowHandle);
|
|
return true;
|
|
}
|
|
|
|
//================ SUPPORT & RESISTANCE ==================//
|
|
double GetSupport()
|
|
{
|
|
double s = iLow(_Symbol, PERIOD_H1, 1);
|
|
for(int i=2;i<=SR_Lookback_Bars;i++)
|
|
s = MathMin(s, iLow(_Symbol, PERIOD_H1, i));
|
|
return s;
|
|
}
|
|
|
|
double GetResistance()
|
|
{
|
|
double r = iHigh(_Symbol, PERIOD_H1, 1);
|
|
for(int i=2;i<=SR_Lookback_Bars;i++)
|
|
r = MathMax(r, iHigh(_Symbol, PERIOD_H1, i));
|
|
return r;
|
|
}
|
|
|
|
//================ TRADE MANAGEMENT ==================//
|
|
void ManageTrade()
|
|
{
|
|
if(!PositionSelect(_Symbol)) return;
|
|
|
|
double entry = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
double sl = PositionGetDouble(POSITION_SL);
|
|
double price = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
|
? SymbolInfoDouble(_Symbol, SYMBOL_BID)
|
|
: SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
|
|
double profit = PositionGetDouble(POSITION_PROFIT);
|
|
long type = PositionGetInteger(POSITION_TYPE);
|
|
|
|
// Break-even
|
|
if(type == POSITION_TYPE_BUY && price - entry >= BreakEven_Points * _Point && sl < entry)
|
|
Trade.PositionModify(_Symbol, entry, 0);
|
|
|
|
if(type == POSITION_TYPE_SELL && entry - price >= BreakEven_Points * _Point && sl > entry)
|
|
Trade.PositionModify(_Symbol, entry, 0);
|
|
|
|
// Profit lock & trailing
|
|
double minProfit = AccountInfoDouble(ACCOUNT_BALANCE) * Min_Profit_Lock_Percent / 100.0;
|
|
|
|
if(profit >= minProfit)
|
|
{
|
|
double newSL;
|
|
if(type == POSITION_TYPE_BUY)
|
|
{
|
|
newSL = price - Trailing_Step_Points * _Point;
|
|
if(newSL > sl)
|
|
Trade.PositionModify(_Symbol, newSL, 0);
|
|
}
|
|
else
|
|
{
|
|
newSL = price + Trailing_Step_Points * _Point;
|
|
if(newSL < sl)
|
|
Trade.PositionModify(_Symbol, newSL, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//================ MAIN ==================//
|
|
void OnTick()
|
|
{
|
|
ManageTrade();
|
|
|
|
if(PositionsTotal() >= Max_Open_Trades) return;
|
|
|
|
bool uptrend=false, downtrend=false;
|
|
if(!GetTrend(uptrend, downtrend)) return;
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
|
|
double support = GetSupport();
|
|
double resistance = GetResistance();
|
|
|
|
double lot = GetLotSize(Initial_SL_Points);
|
|
|
|
Trade.SetExpertMagicNumber(MagicNumber);
|
|
|
|
// BUY
|
|
if(uptrend && MathAbs(bid - support) <= SR_Buffer_Points * _Point)
|
|
{
|
|
double sl = bid - Initial_SL_Points * _Point;
|
|
Trade.Buy(lot, _Symbol, ask, sl, 0);
|
|
}
|
|
|
|
// SELL
|
|
if(downtrend && MathAbs(ask - resistance) <= SR_Buffer_Points * _Point)
|
|
{
|
|
double sl = ask + Initial_SL_Points * _Point;
|
|
Trade.Sell(lot, _Symbol, bid, sl, 0);
|
|
}
|
|
} |