@@ -27,13 +27,13 @@ input double InpLockProfitThreshold = 0.0; // Lock Profit Threshold (pips)
|
|||||||
input bool InpCloseOppositeTrades = false; // Close Opposite Trades When Profiting
|
input bool InpCloseOppositeTrades = false; // Close Opposite Trades When Profiting
|
||||||
|
|
||||||
input group "RSI Follow Strategy"
|
input group "RSI Follow Strategy"
|
||||||
input int InpRSIPeriod = 87; // RSI Period
|
input int InpRSIPeriod = 32; // RSI Period
|
||||||
input int InpRSIOverbought = 72; // RSI Overbought Level
|
input int InpRSIOverbought = 78; // RSI Overbought Level
|
||||||
input int InpRSIOversold = 50; // RSI Oversold Level
|
input int InpRSIOversold = 46; // RSI Oversold Level
|
||||||
input int InpRSIExitLevel = 40; // RSI Exit Level
|
input int InpRSIExitLevel = 44; // RSI Exit Level
|
||||||
input int InpRSIFollowStartHour = 0; // RSI Follow Start Hour (0-23)
|
input int InpRSIFollowStartHour = 23; // RSI Follow Start Hour (0-23)
|
||||||
input int InpRSIFollowEndHour = 7; // RSI Follow End Hour (0-23)
|
input int InpRSIFollowEndHour = 8; // RSI Follow End Hour (0-23)
|
||||||
input bool InpRSIFollowCloseOutsideHours = true; // Close trades outside trading hours
|
input bool InpRSIFollowCloseOutsideHours = false; // Close trades outside trading hours
|
||||||
|
|
||||||
input group "RSI Reverse Strategy"
|
input group "RSI Reverse Strategy"
|
||||||
input int InpRSIReversePeriod = 59; // RSI Period
|
input int InpRSIReversePeriod = 59; // RSI Period
|
||||||
@@ -72,6 +72,12 @@ int emaCrossSignalBar = 0;
|
|||||||
datetime lastBarTime = 0;
|
datetime lastBarTime = 0;
|
||||||
datetime rsiReverseLastCloseTime = 0;
|
datetime rsiReverseLastCloseTime = 0;
|
||||||
bool rsiReverseInCooldown = false;
|
bool rsiReverseInCooldown = false;
|
||||||
|
double lastBarRSI = 0; // Store last bar's RSI value
|
||||||
|
double lastBarRSIReverse = 0; // Store last bar's RSI Reverse value
|
||||||
|
double lastBarEMA = 0; // Store last bar's EMA value
|
||||||
|
double lastBarClose = 0; // Store last bar's close value
|
||||||
|
double lastBarEMAPrev = 0; // Store previous bar's EMA value
|
||||||
|
double lastBarClosePrev = 0; // Store previous bar's close value
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Expert initialization function |
|
//| Expert initialization function |
|
||||||
@@ -224,20 +230,14 @@ void CheckRSIFollowStrategy()
|
|||||||
if(InpEnableStrategyLock && HasProfitablePosition(InpMagicNumberRSIFollow))
|
if(InpEnableStrategyLock && HasProfitablePosition(InpMagicNumberRSIFollow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double rsi[];
|
// Use lastBarRSI instead of copying buffer
|
||||||
ArraySetAsSeries(rsi, true);
|
if(lastBarRSI > InpRSIOverbought)
|
||||||
CopyBuffer(rsiHandle, 0, 0, 3, rsi);
|
|
||||||
|
|
||||||
if(ArraySize(rsi) < 3) return;
|
|
||||||
|
|
||||||
// Check for overbought condition
|
|
||||||
if(rsi[1] > InpRSIOverbought)
|
|
||||||
rsiOverbought = true;
|
rsiOverbought = true;
|
||||||
else if(rsi[1] < InpRSIOversold)
|
else if(lastBarRSI < InpRSIOversold)
|
||||||
rsiOversold = true;
|
rsiOversold = true;
|
||||||
|
|
||||||
// Check for entry signals
|
// Check for entry signals
|
||||||
if(rsiOverbought && rsi[1] < rsi[0] && rsi[1] < InpRSIExitLevel)
|
if(rsiOverbought && lastBarRSI < InpRSIExitLevel)
|
||||||
{
|
{
|
||||||
// Sell signal
|
// Sell signal
|
||||||
if(!HasPosition(InpMagicNumberRSIFollow))
|
if(!HasPosition(InpMagicNumberRSIFollow))
|
||||||
@@ -247,7 +247,7 @@ void CheckRSIFollowStrategy()
|
|||||||
}
|
}
|
||||||
rsiOverbought = false;
|
rsiOverbought = false;
|
||||||
}
|
}
|
||||||
else if(rsiOversold && rsi[1] > rsi[0] && rsi[1] > InpRSIExitLevel)
|
else if(rsiOversold && lastBarRSI > InpRSIExitLevel)
|
||||||
{
|
{
|
||||||
// Buy signal
|
// Buy signal
|
||||||
if(!HasPosition(InpMagicNumberRSIFollow))
|
if(!HasPosition(InpMagicNumberRSIFollow))
|
||||||
@@ -312,20 +312,14 @@ void CheckRSIReverseStrategy()
|
|||||||
if(IsRSIReverseInCooldown())
|
if(IsRSIReverseInCooldown())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double rsi[];
|
// Use lastBarRSIReverse instead of copying buffer
|
||||||
ArraySetAsSeries(rsi, true);
|
if(lastBarRSIReverse > InpRSIReverseOverbought)
|
||||||
CopyBuffer(rsiReverseHandle, 0, 0, 3, rsi);
|
|
||||||
|
|
||||||
if(ArraySize(rsi) < 3) return;
|
|
||||||
|
|
||||||
// Check for overbought/oversold conditions
|
|
||||||
if(rsi[1] > InpRSIReverseOverbought)
|
|
||||||
rsiReverseOverbought = true;
|
rsiReverseOverbought = true;
|
||||||
else if(rsi[1] < InpRSIReverseOversold)
|
else if(lastBarRSIReverse < InpRSIReverseOversold)
|
||||||
rsiReverseOversold = true;
|
rsiReverseOversold = true;
|
||||||
|
|
||||||
// Check for entry signals
|
// Check for entry signals
|
||||||
if(rsiReverseOverbought && rsi[1] < InpRSIReverseCrossLevel)
|
if(rsiReverseOverbought && lastBarRSIReverse < InpRSIReverseCrossLevel)
|
||||||
{
|
{
|
||||||
// Sell signal
|
// Sell signal
|
||||||
if(!HasPosition(InpMagicNumberRSIReverse))
|
if(!HasPosition(InpMagicNumberRSIReverse))
|
||||||
@@ -335,7 +329,7 @@ void CheckRSIReverseStrategy()
|
|||||||
}
|
}
|
||||||
rsiReverseOverbought = false;
|
rsiReverseOverbought = false;
|
||||||
}
|
}
|
||||||
else if(rsiReverseOversold && rsi[1] > InpRSIReverseCrossLevel)
|
else if(rsiReverseOversold && lastBarRSIReverse > InpRSIReverseCrossLevel)
|
||||||
{
|
{
|
||||||
// Buy signal
|
// Buy signal
|
||||||
if(!HasPosition(InpMagicNumberRSIReverse))
|
if(!HasPosition(InpMagicNumberRSIReverse))
|
||||||
@@ -369,24 +363,15 @@ void CheckEMACrossStrategy()
|
|||||||
if(InpEnableStrategyLock && HasProfitablePosition(InpMagicNumberEMACross))
|
if(InpEnableStrategyLock && HasProfitablePosition(InpMagicNumberEMACross))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double ema[], close[];
|
// Check for cross signals using stored values
|
||||||
ArraySetAsSeries(ema, true);
|
if(lastBarEMAPrev < lastBarClosePrev && lastBarEMA > lastBarClose)
|
||||||
ArraySetAsSeries(close, true);
|
|
||||||
|
|
||||||
CopyBuffer(emaHandle, 0, 0, InpEMADistancePeriod + 2, ema);
|
|
||||||
CopyClose(_Symbol, InpTimeframe, 0, InpEMADistancePeriod + 2, close);
|
|
||||||
|
|
||||||
if(ArraySize(ema) < InpEMADistancePeriod + 2 || ArraySize(close) < InpEMADistancePeriod + 2) return;
|
|
||||||
|
|
||||||
// Check for cross signals
|
|
||||||
if(ema[1] < close[1] && ema[0] > close[0])
|
|
||||||
{
|
{
|
||||||
// Buy cross signal
|
// Buy cross signal
|
||||||
emaCrossBuySignal = true;
|
emaCrossBuySignal = true;
|
||||||
emaCrossSellSignal = false;
|
emaCrossSellSignal = false;
|
||||||
emaCrossSignalBar = 0;
|
emaCrossSignalBar = 0;
|
||||||
}
|
}
|
||||||
else if(ema[1] > close[1] && ema[0] < close[0])
|
else if(lastBarEMAPrev > lastBarClosePrev && lastBarEMA < lastBarClose)
|
||||||
{
|
{
|
||||||
// Sell cross signal
|
// Sell cross signal
|
||||||
emaCrossSellSignal = true;
|
emaCrossSellSignal = true;
|
||||||
@@ -401,49 +386,65 @@ void CheckEMACrossStrategy()
|
|||||||
{
|
{
|
||||||
// Check if price has moved above EMA by the required distance for the required period
|
// Check if price has moved above EMA by the required distance for the required period
|
||||||
bool distanceConditionMet = true;
|
bool distanceConditionMet = true;
|
||||||
for(int i = 0; i < InpEMADistancePeriod; i++)
|
double emaHistory[], closeHistory[];
|
||||||
{
|
ArraySetAsSeries(emaHistory, true);
|
||||||
double distance = (close[i] - ema[i]) / _Point;
|
ArraySetAsSeries(closeHistory, true);
|
||||||
if(distance < InpEMADistancePips)
|
|
||||||
{
|
|
||||||
distanceConditionMet = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(distanceConditionMet && !HasPosition(InpMagicNumberEMACross))
|
if(CopyBuffer(emaHandle, 0, 0, InpEMADistancePeriod, emaHistory) > 0 &&
|
||||||
|
CopyClose(_Symbol, InpTimeframe, 0, InpEMADistancePeriod, closeHistory) > 0)
|
||||||
{
|
{
|
||||||
trade.SetExpertMagicNumber(InpMagicNumberEMACross);
|
for(int i = 0; i < InpEMADistancePeriod; i++)
|
||||||
trade.Buy(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross Distance");
|
{
|
||||||
emaCrossBuySignal = false;
|
double distance = (closeHistory[i] - emaHistory[i]) / _Point;
|
||||||
|
if(distance < InpEMADistancePips)
|
||||||
|
{
|
||||||
|
distanceConditionMet = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(distanceConditionMet && !HasPosition(InpMagicNumberEMACross))
|
||||||
|
{
|
||||||
|
trade.SetExpertMagicNumber(InpMagicNumberEMACross);
|
||||||
|
trade.Buy(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross Distance");
|
||||||
|
emaCrossBuySignal = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(emaCrossSellSignal)
|
else if(emaCrossSellSignal)
|
||||||
{
|
{
|
||||||
// Check if price has moved below EMA by the required distance for the required period
|
// Check if price has moved below EMA by the required distance for the required period
|
||||||
bool distanceConditionMet = true;
|
bool distanceConditionMet = true;
|
||||||
for(int i = 0; i < InpEMADistancePeriod; i++)
|
double emaHistory[], closeHistory[];
|
||||||
{
|
ArraySetAsSeries(emaHistory, true);
|
||||||
double distance = (ema[i] - close[i]) / _Point;
|
ArraySetAsSeries(closeHistory, true);
|
||||||
if(distance < InpEMADistancePips)
|
|
||||||
{
|
|
||||||
distanceConditionMet = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(distanceConditionMet && !HasPosition(InpMagicNumberEMACross))
|
if(CopyBuffer(emaHandle, 0, 0, InpEMADistancePeriod, emaHistory) > 0 &&
|
||||||
|
CopyClose(_Symbol, InpTimeframe, 0, InpEMADistancePeriod, closeHistory) > 0)
|
||||||
{
|
{
|
||||||
trade.SetExpertMagicNumber(InpMagicNumberEMACross);
|
for(int i = 0; i < InpEMADistancePeriod; i++)
|
||||||
trade.Sell(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross Distance");
|
{
|
||||||
emaCrossSellSignal = false;
|
double distance = (emaHistory[i] - closeHistory[i]) / _Point;
|
||||||
|
if(distance < InpEMADistancePips)
|
||||||
|
{
|
||||||
|
distanceConditionMet = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(distanceConditionMet && !HasPosition(InpMagicNumberEMACross))
|
||||||
|
{
|
||||||
|
trade.SetExpertMagicNumber(InpMagicNumberEMACross);
|
||||||
|
trade.Sell(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross Distance");
|
||||||
|
emaCrossSellSignal = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Original cross entry logic
|
// Original cross entry logic using stored values
|
||||||
if(ema[1] < close[1] && ema[0] > close[0])
|
if(lastBarEMAPrev < lastBarClosePrev && lastBarEMA > lastBarClose)
|
||||||
{
|
{
|
||||||
// Buy signal
|
// Buy signal
|
||||||
if(!HasPosition(InpMagicNumberEMACross))
|
if(!HasPosition(InpMagicNumberEMACross))
|
||||||
@@ -452,7 +453,7 @@ void CheckEMACrossStrategy()
|
|||||||
trade.Buy(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross");
|
trade.Buy(InpLotSize, _Symbol, 0, 0, 0, "EMA Cross");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ema[1] > close[1] && ema[0] < close[0])
|
else if(lastBarEMAPrev > lastBarClosePrev && lastBarEMA < lastBarClose)
|
||||||
{
|
{
|
||||||
// Sell signal
|
// Sell signal
|
||||||
if(!HasPosition(InpMagicNumberEMACross))
|
if(!HasPosition(InpMagicNumberEMACross))
|
||||||
@@ -485,6 +486,30 @@ void OnTick()
|
|||||||
if(!IsNewBar())
|
if(!IsNewBar())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Get indicator values for the new bar
|
||||||
|
double rsi[], rsiReverse[], ema[], close[];
|
||||||
|
ArraySetAsSeries(rsi, true);
|
||||||
|
ArraySetAsSeries(rsiReverse, true);
|
||||||
|
ArraySetAsSeries(ema, true);
|
||||||
|
ArraySetAsSeries(close, true);
|
||||||
|
|
||||||
|
// Store previous values
|
||||||
|
lastBarEMAPrev = lastBarEMA;
|
||||||
|
lastBarClosePrev = lastBarClose;
|
||||||
|
|
||||||
|
// Get new values
|
||||||
|
if(CopyBuffer(rsiHandle, 0, 0, 1, rsi) > 0)
|
||||||
|
lastBarRSI = rsi[0];
|
||||||
|
|
||||||
|
if(CopyBuffer(rsiReverseHandle, 0, 0, 1, rsiReverse) > 0)
|
||||||
|
lastBarRSIReverse = rsiReverse[0];
|
||||||
|
|
||||||
|
if(CopyBuffer(emaHandle, 0, 0, 1, ema) > 0)
|
||||||
|
lastBarEMA = ema[0];
|
||||||
|
|
||||||
|
if(CopyClose(_Symbol, InpTimeframe, 0, 1, close) > 0)
|
||||||
|
lastBarClose = close[0];
|
||||||
|
|
||||||
// Check for new signals
|
// Check for new signals
|
||||||
if(InpEnableRSIFollow)
|
if(InpEnableRSIFollow)
|
||||||
CheckRSIFollowStrategy();
|
CheckRSIFollowStrategy();
|
||||||
@@ -502,20 +527,13 @@ void OnTick()
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void CheckExitConditions()
|
void CheckExitConditions()
|
||||||
{
|
{
|
||||||
double rsi[], rsiReverse[], ema[], close[];
|
|
||||||
ArraySetAsSeries(rsi, true);
|
|
||||||
ArraySetAsSeries(rsiReverse, true);
|
|
||||||
ArraySetAsSeries(ema, true);
|
|
||||||
ArraySetAsSeries(close, true);
|
|
||||||
|
|
||||||
if(InpEnableRSIFollow)
|
if(InpEnableRSIFollow)
|
||||||
{
|
{
|
||||||
CopyBuffer(rsiHandle, 0, 0, 1, rsi);
|
|
||||||
// Check RSI Follow exit conditions
|
// Check RSI Follow exit conditions
|
||||||
if(HasPosition(InpMagicNumberRSIFollow))
|
if(HasPosition(InpMagicNumberRSIFollow))
|
||||||
{
|
{
|
||||||
if((positionInfo.PositionType() == POSITION_TYPE_BUY && rsi[0] < InpRSIExitLevel) ||
|
if((positionInfo.PositionType() == POSITION_TYPE_BUY && lastBarRSI < InpRSIExitLevel) ||
|
||||||
(positionInfo.PositionType() == POSITION_TYPE_SELL && rsi[0] > InpRSIExitLevel))
|
(positionInfo.PositionType() == POSITION_TYPE_SELL && lastBarRSI > InpRSIExitLevel))
|
||||||
{
|
{
|
||||||
ClosePosition(InpMagicNumberRSIFollow);
|
ClosePosition(InpMagicNumberRSIFollow);
|
||||||
}
|
}
|
||||||
@@ -524,12 +542,11 @@ void CheckExitConditions()
|
|||||||
|
|
||||||
if(InpEnableRSIReverse)
|
if(InpEnableRSIReverse)
|
||||||
{
|
{
|
||||||
CopyBuffer(rsiReverseHandle, 0, 0, 1, rsiReverse);
|
|
||||||
// Check RSI Reverse exit conditions
|
// Check RSI Reverse exit conditions
|
||||||
if(HasPosition(InpMagicNumberRSIReverse))
|
if(HasPosition(InpMagicNumberRSIReverse))
|
||||||
{
|
{
|
||||||
if((positionInfo.PositionType() == POSITION_TYPE_BUY && rsiReverse[0] < InpRSIReverseExitLevel) ||
|
if((positionInfo.PositionType() == POSITION_TYPE_BUY && lastBarRSIReverse < InpRSIReverseExitLevel) ||
|
||||||
(positionInfo.PositionType() == POSITION_TYPE_SELL && rsiReverse[0] > InpRSIReverseExitLevel))
|
(positionInfo.PositionType() == POSITION_TYPE_SELL && lastBarRSIReverse > InpRSIReverseExitLevel))
|
||||||
{
|
{
|
||||||
ClosePosition(InpMagicNumberRSIReverse);
|
ClosePosition(InpMagicNumberRSIReverse);
|
||||||
}
|
}
|
||||||
@@ -538,13 +555,11 @@ void CheckExitConditions()
|
|||||||
|
|
||||||
if(InpEnableEMACross)
|
if(InpEnableEMACross)
|
||||||
{
|
{
|
||||||
CopyBuffer(emaHandle, 0, 0, 2, ema);
|
// Check EMA Cross exit conditions using stored values
|
||||||
CopyClose(_Symbol, InpTimeframe, 0, 2, close);
|
|
||||||
// Check EMA Cross exit conditions
|
|
||||||
if(HasPosition(InpMagicNumberEMACross))
|
if(HasPosition(InpMagicNumberEMACross))
|
||||||
{
|
{
|
||||||
if((positionInfo.PositionType() == POSITION_TYPE_BUY && ema[0] > close[0]) ||
|
if((positionInfo.PositionType() == POSITION_TYPE_BUY && lastBarEMA > lastBarClose) ||
|
||||||
(positionInfo.PositionType() == POSITION_TYPE_SELL && ema[0] < close[0]))
|
(positionInfo.PositionType() == POSITION_TYPE_SELL && lastBarEMA < lastBarClose))
|
||||||
{
|
{
|
||||||
ClosePosition(InpMagicNumberEMACross);
|
ClosePosition(InpMagicNumberEMACross);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,363 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| RSIScalping.mq5 |
|
||||||
|
//| Copyright 2025, MetaQuotes Ltd. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
|
||||||
|
#include <Trade\Trade.mqh>
|
||||||
|
|
||||||
|
//--- Input parameters
|
||||||
|
input ENUM_TIMEFRAMES TimeFrame = PERIOD_M30; // Timeframe for Analysis
|
||||||
|
input int RSI_Period = 14; // RSI Period
|
||||||
|
input ENUM_APPLIED_PRICE RSI_Applied_Price = PRICE_CLOSE; // RSI Applied Price
|
||||||
|
input double RSI_Overbought = 77; // RSI Overbought Level
|
||||||
|
input double RSI_Oversold = 10; // RSI Oversold Level
|
||||||
|
input double RSI_Target_Buy = 27; // RSI Target for Buy Exit
|
||||||
|
input double RSI_Target_Sell = 43; // RSI Target for Sell Exit
|
||||||
|
input int BarsToWait = 14; // Bars to wait when RSI goes against position
|
||||||
|
input double LotSize = 0.1; // Lot Size
|
||||||
|
input int MagicNumber = 12345; // Magic Number
|
||||||
|
input int Slippage = 3; // Slippage in points
|
||||||
|
|
||||||
|
//--- Global variables
|
||||||
|
CTrade trade;
|
||||||
|
int rsi_handle;
|
||||||
|
double rsi_buffer[];
|
||||||
|
double rsi_prev, rsi_current, rsi_two_bars_ago;
|
||||||
|
bool position_open = false;
|
||||||
|
int position_ticket = 0;
|
||||||
|
ENUM_POSITION_TYPE current_position_type = POSITION_TYPE_BUY;
|
||||||
|
datetime last_bar_time = 0;
|
||||||
|
bool rsi_against_position = false;
|
||||||
|
int bars_against_count = 0;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
// Initialize RSI indicator
|
||||||
|
rsi_handle = iRSI(_Symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
|
||||||
|
if(rsi_handle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
Print("Error creating RSI indicator");
|
||||||
|
return(INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize trade object
|
||||||
|
trade.SetExpertMagicNumber(MagicNumber);
|
||||||
|
trade.SetDeviationInPoints(Slippage);
|
||||||
|
trade.SetTypeFilling(ORDER_FILLING_FOK);
|
||||||
|
|
||||||
|
// Allocate arrays
|
||||||
|
ArraySetAsSeries(rsi_buffer, true);
|
||||||
|
|
||||||
|
Print("RSI Scalping EA initialized successfully on timeframe: ", EnumToString(TimeFrame));
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
if(rsi_handle != INVALID_HANDLE)
|
||||||
|
IndicatorRelease(rsi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
// Check if we have enough bars
|
||||||
|
if(Bars(_Symbol, TimeFrame) < RSI_Period + 2)
|
||||||
|
{
|
||||||
|
Print("TRACE: Not enough bars. Bars=", Bars(_Symbol, TimeFrame), " RSI_Period+2=", RSI_Period+2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is a new bar
|
||||||
|
datetime current_bar_time = iTime(_Symbol, TimeFrame, 0);
|
||||||
|
if(current_bar_time == last_bar_time)
|
||||||
|
{
|
||||||
|
Print("TRACE: Same bar, skipping. current_bar_time=", current_bar_time, " last_bar_time=", last_bar_time);
|
||||||
|
return; // Still the same bar, don't process
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("TRACE: New bar detected. current_bar_time=", current_bar_time, " last_bar_time=", last_bar_time);
|
||||||
|
last_bar_time = current_bar_time;
|
||||||
|
|
||||||
|
// Update RSI values
|
||||||
|
if(!UpdateRSI())
|
||||||
|
{
|
||||||
|
Print("TRACE: Failed to update RSI values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("TRACE: RSI values - Current=", rsi_current, " Previous=", rsi_prev);
|
||||||
|
|
||||||
|
// Check for existing position
|
||||||
|
CheckExistingPosition();
|
||||||
|
|
||||||
|
// Check for new entry signals
|
||||||
|
if(!position_open)
|
||||||
|
{
|
||||||
|
Print("TRACE: No position open, checking entry signals");
|
||||||
|
CheckEntrySignals();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Position already open, skipping entry signals");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Update RSI values |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool UpdateRSI()
|
||||||
|
{
|
||||||
|
Print("TRACE: Updating RSI values...");
|
||||||
|
|
||||||
|
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3)
|
||||||
|
{
|
||||||
|
Print("TRACE: Error copying RSI data. Copied=", CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsi_current = rsi_buffer[0]; // Current bar
|
||||||
|
rsi_prev = rsi_buffer[1]; // Previous bar
|
||||||
|
rsi_two_bars_ago = rsi_buffer[2]; // Two bars ago
|
||||||
|
|
||||||
|
Print("TRACE: RSI buffer values - [0]=", rsi_buffer[0], " [1]=", rsi_buffer[1], " [2]=", rsi_buffer[2]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check existing position for exit conditions |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckExistingPosition()
|
||||||
|
{
|
||||||
|
if(!position_open)
|
||||||
|
{
|
||||||
|
Print("TRACE: No position open, skipping position check");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("TRACE: Checking existing position. Ticket=", position_ticket, " Type=", (current_position_type == POSITION_TYPE_BUY ? "BUY" : "SELL"));
|
||||||
|
|
||||||
|
// Check if position still exists
|
||||||
|
if(!PositionSelectByTicket(position_ticket))
|
||||||
|
{
|
||||||
|
Print("TRACE: Position no longer exists, resetting state");
|
||||||
|
position_open = false;
|
||||||
|
position_ticket = 0;
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit conditions based on RSI target
|
||||||
|
if(current_position_type == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
Print("TRACE: Checking BUY position exit - rsi_current=", rsi_current, " RSI_Target_Buy=", RSI_Target_Buy, " RSI_Oversold=", RSI_Oversold);
|
||||||
|
|
||||||
|
// Check if RSI is against the position (below oversold)
|
||||||
|
if(rsi_current < RSI_Oversold)
|
||||||
|
{
|
||||||
|
if(!rsi_against_position)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI went against BUY position (below oversold), starting counter");
|
||||||
|
rsi_against_position = true;
|
||||||
|
bars_against_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bars_against_count++;
|
||||||
|
Print("TRACE: RSI still against BUY position. Bars against: ", bars_against_count, "/", BarsToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close position if RSI has been against for Y bars
|
||||||
|
if(bars_against_count >= BarsToWait)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI against BUY position for ", BarsToWait, " bars, closing position!");
|
||||||
|
ClosePosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RSI is no longer against the position, reset counter
|
||||||
|
if(rsi_against_position)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI no longer against BUY position, resetting counter");
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit long position when RSI reaches buy target
|
||||||
|
if(rsi_current >= RSI_Target_Buy)
|
||||||
|
{
|
||||||
|
Print("TRACE: BUY position target reached!");
|
||||||
|
ClosePosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: BUY position exit condition not met");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(current_position_type == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
Print("TRACE: Checking SELL position exit - rsi_current=", rsi_current, " RSI_Target_Sell=", RSI_Target_Sell, " RSI_Overbought=", RSI_Overbought);
|
||||||
|
|
||||||
|
// Check if RSI is against the position (above overbought)
|
||||||
|
if(rsi_current > RSI_Overbought)
|
||||||
|
{
|
||||||
|
if(!rsi_against_position)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI went against SELL position (above overbought), starting counter");
|
||||||
|
rsi_against_position = true;
|
||||||
|
bars_against_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bars_against_count++;
|
||||||
|
Print("TRACE: RSI still against SELL position. Bars against: ", bars_against_count, "/", BarsToWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close position if RSI has been against for Y bars
|
||||||
|
if(bars_against_count >= BarsToWait)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI against SELL position for ", BarsToWait, " bars, closing position!");
|
||||||
|
ClosePosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RSI is no longer against the position, reset counter
|
||||||
|
if(rsi_against_position)
|
||||||
|
{
|
||||||
|
Print("TRACE: RSI no longer against SELL position, resetting counter");
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit short position when RSI reaches sell target
|
||||||
|
if(rsi_current <= RSI_Target_Sell)
|
||||||
|
{
|
||||||
|
Print("TRACE: SELL position target reached!");
|
||||||
|
ClosePosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: SELL position exit condition not met");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check for entry signals |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckEntrySignals()
|
||||||
|
{
|
||||||
|
Print("TRACE: Checking entry signals...");
|
||||||
|
Print("TRACE: Buy condition - rsi_two_bars_ago <= RSI_Oversold && rsi_prev > RSI_Oversold");
|
||||||
|
Print("TRACE: Buy condition values - rsi_two_bars_ago=", rsi_two_bars_ago, " <= ", RSI_Oversold, " && rsi_prev=", rsi_prev, " > ", RSI_Oversold);
|
||||||
|
|
||||||
|
// Buy signal: RSI crosses from oversold to above oversold (checking the actual crossover)
|
||||||
|
if(rsi_two_bars_ago <= RSI_Oversold && rsi_prev > RSI_Oversold)
|
||||||
|
{
|
||||||
|
Print("TRACE: Buy signal detected!");
|
||||||
|
OpenBuyPosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Buy signal condition not met");
|
||||||
|
}
|
||||||
|
|
||||||
|
Print("TRACE: Sell condition - rsi_two_bars_ago >= RSI_Overbought && rsi_prev < RSI_Overbought");
|
||||||
|
Print("TRACE: Sell condition values - rsi_two_bars_ago=", rsi_two_bars_ago, " >= ", RSI_Overbought, " && rsi_prev=", rsi_prev, " < ", RSI_Overbought);
|
||||||
|
|
||||||
|
// Sell signal: RSI crosses from overbought to below overbought (checking the actual crossover)
|
||||||
|
if(rsi_two_bars_ago >= RSI_Overbought && rsi_prev < RSI_Overbought)
|
||||||
|
{
|
||||||
|
Print("TRACE: Sell signal detected!");
|
||||||
|
OpenSellPosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Sell signal condition not met");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open buy position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenBuyPosition()
|
||||||
|
{
|
||||||
|
Print("TRACE: Attempting to open buy position...");
|
||||||
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
Print("TRACE: Current ask price=", ask, " LotSize=", LotSize);
|
||||||
|
|
||||||
|
if(trade.Buy(LotSize, _Symbol, ask, 0, 0, "RSI Scalping Buy"))
|
||||||
|
{
|
||||||
|
position_ticket = trade.ResultOrder();
|
||||||
|
position_open = true;
|
||||||
|
current_position_type = POSITION_TYPE_BUY;
|
||||||
|
Print("TRACE: Buy position opened successfully! Ticket=", position_ticket, " Price=", ask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Error opening buy position. Retcode=", trade.ResultRetcode(), " Description=", trade.ResultRetcodeDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open sell position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenSellPosition()
|
||||||
|
{
|
||||||
|
Print("TRACE: Attempting to open sell position...");
|
||||||
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
Print("TRACE: Current bid price=", bid, " LotSize=", LotSize);
|
||||||
|
|
||||||
|
if(trade.Sell(LotSize, _Symbol, bid, 0, 0, "RSI Scalping Sell"))
|
||||||
|
{
|
||||||
|
position_ticket = trade.ResultOrder();
|
||||||
|
position_open = true;
|
||||||
|
current_position_type = POSITION_TYPE_SELL;
|
||||||
|
Print("TRACE: Sell position opened successfully! Ticket=", position_ticket, " Price=", bid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Error opening sell position. Retcode=", trade.ResultRetcode(), " Description=", trade.ResultRetcodeDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Close current position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void ClosePosition()
|
||||||
|
{
|
||||||
|
Print("TRACE: Attempting to close position. Ticket=", position_ticket);
|
||||||
|
|
||||||
|
if(trade.PositionClose(position_ticket))
|
||||||
|
{
|
||||||
|
Print("TRACE: Position closed successfully! Ticket=", position_ticket);
|
||||||
|
position_open = false;
|
||||||
|
position_ticket = 0;
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print("TRACE: Error closing position. Retcode=", trade.ResultRetcode(), " Description=", trade.ResultRetcodeDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 223 KiB |
@@ -0,0 +1,281 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| RSIScalping.mq5 |
|
||||||
|
//| Copyright 2025, MetaQuotes Ltd. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
|
||||||
|
#include <Trade\Trade.mqh>
|
||||||
|
|
||||||
|
//--- Input parameters
|
||||||
|
input ENUM_TIMEFRAMES TimeFrame = PERIOD_H1; // Timeframe for Analysis
|
||||||
|
input int RSI_Period = 14; // RSI Period
|
||||||
|
input ENUM_APPLIED_PRICE RSI_Applied_Price = PRICE_CLOSE; // RSI Applied Price
|
||||||
|
input double RSI_Overbought = 71; // RSI Overbought Level
|
||||||
|
input double RSI_Oversold = 57; // RSI Oversold Level
|
||||||
|
input double RSI_Target_Buy = 80; // RSI Target for Buy Exit
|
||||||
|
input double RSI_Target_Sell = 57; // RSI Target for Sell Exit
|
||||||
|
input int BarsToWait = 4; // Bars to wait when RSI goes against position
|
||||||
|
input double LotSize = 0.1; // Lot Size
|
||||||
|
input int MagicNumber = 12345; // Magic Number
|
||||||
|
input int Slippage = 3; // Slippage in points
|
||||||
|
|
||||||
|
//--- Global variables
|
||||||
|
CTrade trade;
|
||||||
|
int rsi_handle;
|
||||||
|
double rsi_buffer[];
|
||||||
|
double rsi_prev, rsi_current, rsi_two_bars_ago;
|
||||||
|
bool position_open = false;
|
||||||
|
int position_ticket = 0;
|
||||||
|
ENUM_POSITION_TYPE current_position_type = POSITION_TYPE_BUY;
|
||||||
|
datetime last_bar_time = 0;
|
||||||
|
bool rsi_against_position = false;
|
||||||
|
int bars_against_count = 0;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
// Initialize RSI indicator
|
||||||
|
rsi_handle = iRSI(_Symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
|
||||||
|
if(rsi_handle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
return(INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize trade object
|
||||||
|
trade.SetExpertMagicNumber(MagicNumber);
|
||||||
|
trade.SetDeviationInPoints(Slippage);
|
||||||
|
trade.SetTypeFilling(ORDER_FILLING_FOK);
|
||||||
|
|
||||||
|
// Allocate arrays
|
||||||
|
ArraySetAsSeries(rsi_buffer, true);
|
||||||
|
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
if(rsi_handle != INVALID_HANDLE)
|
||||||
|
IndicatorRelease(rsi_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
// Check if we have enough bars
|
||||||
|
if(Bars(_Symbol, TimeFrame) < RSI_Period + 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is a new bar
|
||||||
|
datetime current_bar_time = iTime(_Symbol, TimeFrame, 0);
|
||||||
|
if(current_bar_time == last_bar_time)
|
||||||
|
{
|
||||||
|
return; // Still the same bar, don't process
|
||||||
|
}
|
||||||
|
|
||||||
|
last_bar_time = current_bar_time;
|
||||||
|
|
||||||
|
// Update RSI values
|
||||||
|
if(!UpdateRSI())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for existing position
|
||||||
|
CheckExistingPosition();
|
||||||
|
|
||||||
|
// Check for new entry signals
|
||||||
|
if(!position_open)
|
||||||
|
{
|
||||||
|
CheckEntrySignals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Update RSI values |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool UpdateRSI()
|
||||||
|
{
|
||||||
|
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsi_current = rsi_buffer[0]; // Current bar
|
||||||
|
rsi_prev = rsi_buffer[1]; // Previous bar
|
||||||
|
rsi_two_bars_ago = rsi_buffer[2]; // Two bars ago
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check existing position for exit conditions |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckExistingPosition()
|
||||||
|
{
|
||||||
|
if(!position_open)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if position still exists
|
||||||
|
if(!PositionSelectByTicket(position_ticket))
|
||||||
|
{
|
||||||
|
position_open = false;
|
||||||
|
position_ticket = 0;
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit conditions based on RSI target
|
||||||
|
if(current_position_type == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
// Check if RSI is against the position (below oversold)
|
||||||
|
if(rsi_current < RSI_Oversold)
|
||||||
|
{
|
||||||
|
if(!rsi_against_position)
|
||||||
|
{
|
||||||
|
rsi_against_position = true;
|
||||||
|
bars_against_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bars_against_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close position if RSI has been against for Y bars
|
||||||
|
if(bars_against_count >= BarsToWait)
|
||||||
|
{
|
||||||
|
ClosePosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RSI is no longer against the position, reset counter
|
||||||
|
if(rsi_against_position)
|
||||||
|
{
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit long position when RSI reaches buy target
|
||||||
|
if(rsi_current >= RSI_Target_Buy)
|
||||||
|
{
|
||||||
|
ClosePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(current_position_type == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
// Check if RSI is against the position (above overbought)
|
||||||
|
if(rsi_current > RSI_Overbought)
|
||||||
|
{
|
||||||
|
if(!rsi_against_position)
|
||||||
|
{
|
||||||
|
rsi_against_position = true;
|
||||||
|
bars_against_count = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bars_against_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close position if RSI has been against for Y bars
|
||||||
|
if(bars_against_count >= BarsToWait)
|
||||||
|
{
|
||||||
|
ClosePosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RSI is no longer against the position, reset counter
|
||||||
|
if(rsi_against_position)
|
||||||
|
{
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit short position when RSI reaches sell target
|
||||||
|
if(rsi_current <= RSI_Target_Sell)
|
||||||
|
{
|
||||||
|
ClosePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check for entry signals |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckEntrySignals()
|
||||||
|
{
|
||||||
|
// Buy signal: RSI crosses from oversold to above oversold (checking the actual crossover)
|
||||||
|
if(rsi_two_bars_ago <= RSI_Oversold && rsi_prev > RSI_Oversold)
|
||||||
|
{
|
||||||
|
OpenBuyPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sell signal: RSI crosses from overbought to below overbought (checking the actual crossover)
|
||||||
|
if(rsi_two_bars_ago >= RSI_Overbought && rsi_prev < RSI_Overbought)
|
||||||
|
{
|
||||||
|
OpenSellPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open buy position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenBuyPosition()
|
||||||
|
{
|
||||||
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
|
||||||
|
if(trade.Buy(LotSize, _Symbol, ask, 0, 0, "RSI Scalping Buy"))
|
||||||
|
{
|
||||||
|
position_ticket = trade.ResultOrder();
|
||||||
|
position_open = true;
|
||||||
|
current_position_type = POSITION_TYPE_BUY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open sell position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenSellPosition()
|
||||||
|
{
|
||||||
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
|
||||||
|
if(trade.Sell(LotSize, _Symbol, bid, 0, 0, "RSI Scalping Sell"))
|
||||||
|
{
|
||||||
|
position_ticket = trade.ResultOrder();
|
||||||
|
position_open = true;
|
||||||
|
current_position_type = POSITION_TYPE_SELL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Close current position |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void ClosePosition()
|
||||||
|
{
|
||||||
|
if(trade.PositionClose(position_ticket))
|
||||||
|
{
|
||||||
|
position_open = false;
|
||||||
|
position_ticket = 0;
|
||||||
|
rsi_against_position = false;
|
||||||
|
bars_against_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 233 KiB |
Reference in New Issue
Block a user