This commit is contained in:
zhutoutoutousan
2025-08-17 11:05:03 +02:00
parent 9f5839e3d2
commit 54e91e0ce5
5 changed files with 258 additions and 120 deletions
+126 -55
View File
@@ -13,18 +13,18 @@
// Input parameters // Input parameters
input int RSIPeriod = 28; // RSI period input int RSIPeriod = 28; // RSI period
input double OverboughtLevel = 64; // Overbought level input double OverboughtLevel = 68; // Overbought level
input double OversoldLevel = 13; // Oversold level input double OversoldLevel = 30; // Oversold level
input int TakeProfitPips = 175; // Take profit in pips input int TakeProfitPips = 175; // Take profit in pips
input int StopLossPips = 5; // Stop loss in pips input int StopLossPips = 5; // Stop loss in pips
input double MaxLotSize = 0.1; // Maximum lot size input double MaxLotSize = 0.2; // Maximum lot size
input int MaxSpread = 1000; // Maximum allowed spread in pips input int MaxSpread = 1000; // Maximum allowed spread in pips
input int MaxDuration = 140; // Maximum trade duration in hours input int MaxDuration = 340; // Maximum trade duration in hours
input bool UseStopLoss = false; // Use stop loss input bool UseStopLoss = false; // Use stop loss
input bool UseTakeProfit = false; // Use take profit input bool UseTakeProfit = false; // Use take profit
input bool UseRSIExit = true; // Use RSI for exit input bool UseRSIExit = true; // Use RSI for exit
input double RSIExitLevel = 49; // RSI level to exit (50 = neutral) input double RSIExitLevel = 48; // RSI level to exit (50 = neutral)
input bool CloseOutsideSession = false; // Close trades outside Asian session input bool CloseOutsideSession = true; // Close trades outside Asian session
input color PanelBackground = clrBlack; // Panel background color input color PanelBackground = clrBlack; // Panel background color
input color PanelText = clrWhite; // Panel text color input color PanelText = clrWhite; // Panel text color
input int PanelX = 10; // Panel X position input int PanelX = 10; // Panel X position
@@ -39,6 +39,14 @@ datetime positionOpenTime = 0;
ENUM_POSITION_TYPE lastPositionType = POSITION_TYPE_BUY; ENUM_POSITION_TYPE lastPositionType = POSITION_TYPE_BUY;
bool sessionCloseAttempted = false; // Track if we've attempted to close positions for current session bool sessionCloseAttempted = false; // Track if we've attempted to close positions for current session
// RSI crossover variables
double rsiCurrent = 0;
double rsiPrevious = 0;
double rsiPrevious2 = 0;
bool rsiCrossedOverbought = false;
bool rsiCrossedOversold = false;
bool rsiCrossedExitLevel = false;
// Panel objects // Panel objects
string panelName = "RSIPanel"; string panelName = "RSIPanel";
int panelWidth = 200; int panelWidth = 200;
@@ -89,6 +97,7 @@ void CreatePanel()
CreateScoreLabel("Session", "Session: ", 3); CreateScoreLabel("Session", "Session: ", 3);
CreateScoreLabel("SL", "Stop Loss: ", 4); CreateScoreLabel("SL", "Stop Loss: ", 4);
CreateScoreLabel("TP", "Take Profit: ", 5); CreateScoreLabel("TP", "Take Profit: ", 5);
CreateScoreLabel("Cross", "Cross: ", 6);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -108,7 +117,7 @@ void CreateScoreLabel(string name, string text, int index)
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Update panel values | //| Update panel values |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void UpdatePanel(double rsi, string position, int spread, string session, double sl, double tp) void UpdatePanel(double rsi, string position, int spread, string session, double sl, double tp, string crossInfo)
{ {
ObjectSetString(0, panelName + "RSI", OBJPROP_TEXT, "RSI: " + DoubleToString(rsi, 2)); ObjectSetString(0, panelName + "RSI", OBJPROP_TEXT, "RSI: " + DoubleToString(rsi, 2));
ObjectSetString(0, panelName + "Position", OBJPROP_TEXT, "Position: " + position); ObjectSetString(0, panelName + "Position", OBJPROP_TEXT, "Position: " + position);
@@ -116,6 +125,7 @@ void UpdatePanel(double rsi, string position, int spread, string session, double
ObjectSetString(0, panelName + "Session", OBJPROP_TEXT, "Session: " + session); ObjectSetString(0, panelName + "Session", OBJPROP_TEXT, "Session: " + session);
ObjectSetString(0, panelName + "SL", OBJPROP_TEXT, "Stop Loss: " + IntegerToString(StopLossPips) + " pips"); ObjectSetString(0, panelName + "SL", OBJPROP_TEXT, "Stop Loss: " + IntegerToString(StopLossPips) + " pips");
ObjectSetString(0, panelName + "TP", OBJPROP_TEXT, "Take Profit: " + IntegerToString(TakeProfitPips) + " pips"); ObjectSetString(0, panelName + "TP", OBJPROP_TEXT, "Take Profit: " + IntegerToString(TakeProfitPips) + " pips");
ObjectSetString(0, panelName + "Cross", OBJPROP_TEXT, "Cross: " + crossInfo);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -157,20 +167,51 @@ bool IsTradingAllowed()
// Check if market is open // Check if market is open
if(!SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL) if(!SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL)
{ {
Print("Trading is not allowed for ", _Symbol);
return false; return false;
} }
// Check if we have enough money // Check if we have enough money
if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) <= 0) if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) <= 0)
{ {
Print("Not enough free margin");
return false; return false;
} }
return true; return true;
} }
//+------------------------------------------------------------------+
//| Check RSI crossover conditions |
//+------------------------------------------------------------------+
void CheckRSICrossover()
{
// Reset crossover flags
rsiCrossedOverbought = false;
rsiCrossedOversold = false;
rsiCrossedExitLevel = false;
// Check for overbought crossover (RSI crosses above overbought level)
if(rsiPrevious < OverboughtLevel && rsiCurrent >= OverboughtLevel)
{
rsiCrossedOverbought = true;
}
// Check for oversold crossover (RSI crosses below oversold level)
if(rsiPrevious > OversoldLevel && rsiCurrent <= OversoldLevel)
{
rsiCrossedOversold = true;
}
// Check for exit level crossover
if(rsiPrevious < RSIExitLevel && rsiCurrent >= RSIExitLevel)
{
rsiCrossedExitLevel = true;
}
else if(rsiPrevious > RSIExitLevel && rsiCurrent <= RSIExitLevel)
{
rsiCrossedExitLevel = true;
}
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Expert initialization function | //| Expert initialization function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -181,18 +222,47 @@ int OnInit()
if(rsiHandle == INVALID_HANDLE) if(rsiHandle == INVALID_HANDLE)
{ {
Print("Failed to create RSI indicator handle");
return(INIT_FAILED); return(INIT_FAILED);
} }
// Wait a bit for the indicator to be ready
Sleep(100);
// Initialize RSI values with retry logic
double rsi[];
ArraySetAsSeries(rsi, true);
int retryCount = 0;
bool rsiInitialized = false;
while(retryCount < 10 && !rsiInitialized)
{
int copied = CopyBuffer(rsiHandle, 0, 0, 3, rsi);
if(copied >= 3)
{
rsiCurrent = rsi[0];
rsiPrevious = rsi[1];
rsiPrevious2 = rsi[2];
rsiInitialized = true;
}
else
{
retryCount++;
Sleep(100);
}
}
if(!rsiInitialized)
{
// Don't fail initialization, just set default values
rsiCurrent = 50.0;
rsiPrevious = 50.0;
rsiPrevious2 = 50.0;
}
// Create panel // Create panel
CreatePanel(); CreatePanel();
Print("Expert Advisor initialized successfully");
Print("Trading symbol: ", _Symbol);
Print("Account balance: ", AccountInfoDouble(ACCOUNT_BALANCE));
Print("Account leverage: ", AccountInfoInteger(ACCOUNT_LEVERAGE));
return(INIT_SUCCEEDED); return(INIT_SUCCEEDED);
} }
@@ -218,8 +288,6 @@ bool CloseAllTrades(string reason = "")
if(totalPositions == 0) if(totalPositions == 0)
return true; return true;
Print("Attempting to close all positions", (reason != "" ? " - " + reason : ""));
// Check if there are any positions with our magic number // Check if there are any positions with our magic number
bool hasOurPositions = false; bool hasOurPositions = false;
@@ -244,14 +312,12 @@ bool CloseAllTrades(string reason = "")
{ {
if(trade.PositionClose(_Symbol)) if(trade.PositionClose(_Symbol))
{ {
Print("Position closed successfully");
isPositionOpen = false; isPositionOpen = false;
positionClosed = true; positionClosed = true;
} }
else else
{ {
int error = GetLastError(); int error = GetLastError();
Print("Failed to close position. Error: ", error, " Retry: ", retryCount + 1);
// If error is 4756 (Trade disabled), wait longer before retry // If error is 4756 (Trade disabled), wait longer before retry
if(error == 4756) if(error == 4756)
@@ -269,7 +335,6 @@ bool CloseAllTrades(string reason = "")
if(!positionClosed) if(!positionClosed)
{ {
Print("Failed to close position after all retries");
allClosed = false; allClosed = false;
} }
} }
@@ -286,15 +351,12 @@ void OnTick()
// Check if trading is allowed // Check if trading is allowed
if(!IsTradingAllowed()) if(!IsTradingAllowed())
{ {
Print("Trading is not allowed at the moment");
return; return;
} }
// Check if we're in Asian session // Check if we're in Asian session
if(!IsAsianSession()) if(!IsAsianSession())
{ {
Print("Not in Asian session");
// Close all positions if outside Asian session and CloseOutsideSession is true // Close all positions if outside Asian session and CloseOutsideSession is true
if(CloseOutsideSession && !sessionCloseAttempted) if(CloseOutsideSession && !sessionCloseAttempted)
{ {
@@ -316,17 +378,33 @@ void OnTick()
// Check if spread is too high // Check if spread is too high
if(spreadInPips > MaxSpread) if(spreadInPips > MaxSpread)
{ {
Print("Spread too high: ", spreadInPips, " pips");
return; return;
} }
// Get RSI value // Get RSI values from bar data
double rsi[]; double rsi[];
ArraySetAsSeries(rsi, true); ArraySetAsSeries(rsi, true);
if(CopyBuffer(rsiHandle, 0, 0, 1, rsi) != 1) int copied = CopyBuffer(rsiHandle, 0, 0, 3, rsi);
if(copied < 3)
{
return; return;
}
// Update RSI values
rsiPrevious2 = rsiPrevious;
rsiPrevious = rsiCurrent;
rsiCurrent = rsi[0];
// Validate RSI values
if(rsiCurrent == 0 || rsiPrevious == 0)
{
return;
}
// Check for RSI crossovers
CheckRSICrossover();
// Get current prices // Get current prices
double currentBid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double currentBid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
@@ -347,8 +425,14 @@ void OnTick()
double sl = 0; double sl = 0;
double tp = 0; double tp = 0;
// Prepare crossover info for panel
string crossInfo = "None";
if(rsiCrossedOverbought) crossInfo = "Overbought";
else if(rsiCrossedOversold) crossInfo = "Oversold";
else if(rsiCrossedExitLevel) crossInfo = "Exit";
// Update panel // Update panel
UpdatePanel(rsi[0], positionStatus, spreadInPips, GetCurrentSession(), sl, tp); UpdatePanel(rsiCurrent, positionStatus, spreadInPips, GetCurrentSession(), sl, tp, crossInfo);
// Check for open position // Check for open position
bool hasOpenPosition = false; bool hasOpenPosition = false;
@@ -365,26 +449,24 @@ void OnTick()
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// Check for RSI exit if enabled // Check for RSI exit if enabled
if(UseRSIExit) if(UseRSIExit && rsiCrossedExitLevel)
{ {
bool shouldExit = false; bool shouldExit = false;
// For long positions, exit when RSI reaches or exceeds exit level // For long positions, exit when RSI crosses above exit level
if(posType == POSITION_TYPE_BUY && rsi[0] >= RSIExitLevel) if(posType == POSITION_TYPE_BUY && rsiCurrent >= RSIExitLevel && rsiPrevious < RSIExitLevel)
{ {
Print("Closing long position due to RSI exit. RSI: ", rsi[0], " Exit Level: ", RSIExitLevel);
shouldExit = true; shouldExit = true;
} }
// For short positions, exit when RSI reaches or falls below exit level // For short positions, exit when RSI crosses below exit level
else if(posType == POSITION_TYPE_SELL && rsi[0] <= RSIExitLevel) else if(posType == POSITION_TYPE_SELL && rsiCurrent <= RSIExitLevel && rsiPrevious > RSIExitLevel)
{ {
Print("Closing short position due to RSI exit. RSI: ", rsi[0], " Exit Level: ", RSIExitLevel);
shouldExit = true; shouldExit = true;
} }
if(shouldExit) if(shouldExit)
{ {
CloseAllTrades("RSI Exit"); CloseAllTrades("RSI Exit Crossover");
return; return;
} }
} }
@@ -392,7 +474,6 @@ void OnTick()
// Check for timeout // Check for timeout
if(TimeCurrent() - positionOpenTime > MaxDuration * 3600) if(TimeCurrent() - positionOpenTime > MaxDuration * 3600)
{ {
Print("Closing position due to timeout");
CloseAllTrades("Timeout"); CloseAllTrades("Timeout");
return; return;
} }
@@ -401,11 +482,11 @@ void OnTick()
} }
} }
// If no position is open, look for entry signals // If no position is open, look for entry signals based on RSI crossover
if(!hasOpenPosition) if(!hasOpenPosition)
{ {
// Place buy order if RSI is oversold // Place buy order if RSI crosses below oversold level (oversold crossover)
if(rsi[0] <= OversoldLevel) if(rsiCrossedOversold)
{ {
double sl = UseStopLoss ? currentBid - StopLossPips * _Point : 0; double sl = UseStopLoss ? currentBid - StopLossPips * _Point : 0;
double tp = UseTakeProfit ? currentBid + TakeProfitPips * _Point : 0; double tp = UseTakeProfit ? currentBid + TakeProfitPips * _Point : 0;
@@ -421,21 +502,16 @@ void OnTick()
trade.SetExpertMagicNumber(123456); trade.SetExpertMagicNumber(123456);
// Place buy order using CTrade // Place buy order using CTrade
if(!trade.Buy(MaxLotSize, _Symbol, currentAsk, sl, tp, "RSI Buy")) if(trade.Buy(MaxLotSize, _Symbol, currentAsk, sl, tp, "RSI Oversold Crossover Buy"))
{ {
Print("Buy order failed. Error code: ", GetLastError());
}
else
{
Print("Buy order placed. RSI: ", rsi[0]);
isPositionOpen = true; isPositionOpen = true;
positionOpenPrice = currentAsk; positionOpenPrice = currentAsk;
positionOpenTime = TimeCurrent(); positionOpenTime = TimeCurrent();
lastPositionType = POSITION_TYPE_BUY; lastPositionType = POSITION_TYPE_BUY;
} }
} }
// Place sell order if RSI is overbought // Place sell order if RSI crosses above overbought level (overbought crossover)
else if(rsi[0] >= OverboughtLevel) else if(rsiCrossedOverbought)
{ {
double sl = UseStopLoss ? currentAsk + StopLossPips * _Point : 0; double sl = UseStopLoss ? currentAsk + StopLossPips * _Point : 0;
double tp = UseTakeProfit ? currentAsk - TakeProfitPips * _Point : 0; double tp = UseTakeProfit ? currentAsk - TakeProfitPips * _Point : 0;
@@ -451,13 +527,8 @@ void OnTick()
trade.SetExpertMagicNumber(123456); trade.SetExpertMagicNumber(123456);
// Place sell order using CTrade // Place sell order using CTrade
if(!trade.Sell(MaxLotSize, _Symbol, currentBid, sl, tp, "RSI Sell")) if(trade.Sell(MaxLotSize, _Symbol, currentBid, sl, tp, "RSI Overbought Crossover Sell"))
{ {
Print("Sell order failed. Error code: ", GetLastError());
}
else
{
Print("Sell order placed. RSI: ", rsi[0]);
isPositionOpen = true; isPositionOpen = true;
positionOpenPrice = currentBid; positionOpenPrice = currentBid;
positionOpenTime = TimeCurrent(); positionOpenTime = TimeCurrent();
@@ -465,4 +536,4 @@ void OnTick()
} }
} }
} }
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

+132 -65
View File
@@ -12,18 +12,18 @@
#include <Trade\Trade.mqh> #include <Trade\Trade.mqh>
// Input parameters // Input parameters
input int RSIPeriod = 14; // RSI period input int RSIPeriod = 28; // RSI period
input double OverboughtLevel = 78; // Overbought level input double OverboughtLevel = 60; // Overbought level
input double OversoldLevel = 20; // Oversold level input double OversoldLevel = 8; // Oversold level
input int TakeProfitPips = 635; // Take profit in pips input int TakeProfitPips = 175; // Take profit in pips
input int StopLossPips = 290; // Stop loss in pips input int StopLossPips = 5; // Stop loss in pips
input double MaxLotSize = 0.1; // Maximum lot size input double MaxLotSize = 0.1; // Maximum lot size
input int MaxSpread = 1000; // Maximum allowed spread in pips input int MaxSpread = 1000; // Maximum allowed spread in pips
input int MaxDuration = 22; // Maximum trade duration in hours input int MaxDuration = 270; // Maximum trade duration in hours
input bool UseStopLoss = true; // Use stop loss input bool UseStopLoss = false; // Use stop loss
input bool UseTakeProfit = false; // Use take profit input bool UseTakeProfit = false; // Use take profit
input bool UseRSIExit = true; // Use RSI for exit input bool UseRSIExit = true; // Use RSI for exit
input double RSIExitLevel = 57; // RSI level to exit (50 = neutral) input double RSIExitLevel = 55; // RSI level to exit (50 = neutral)
input bool CloseOutsideSession = false; // Close trades outside Asian session input bool CloseOutsideSession = false; // Close trades outside Asian session
input color PanelBackground = clrBlack; // Panel background color input color PanelBackground = clrBlack; // Panel background color
input color PanelText = clrWhite; // Panel text color input color PanelText = clrWhite; // Panel text color
@@ -39,6 +39,14 @@ datetime positionOpenTime = 0;
ENUM_POSITION_TYPE lastPositionType = POSITION_TYPE_BUY; ENUM_POSITION_TYPE lastPositionType = POSITION_TYPE_BUY;
bool sessionCloseAttempted = false; // Track if we've attempted to close positions for current session bool sessionCloseAttempted = false; // Track if we've attempted to close positions for current session
// RSI crossover variables
double rsiCurrent = 0;
double rsiPrevious = 0;
double rsiPrevious2 = 0;
bool rsiCrossedOverbought = false;
bool rsiCrossedOversold = false;
bool rsiCrossedExitLevel = false;
// Panel objects // Panel objects
string panelName = "RSIPanel"; string panelName = "RSIPanel";
int panelWidth = 200; int panelWidth = 200;
@@ -89,6 +97,7 @@ void CreatePanel()
CreateScoreLabel("Session", "Session: ", 3); CreateScoreLabel("Session", "Session: ", 3);
CreateScoreLabel("SL", "Stop Loss: ", 4); CreateScoreLabel("SL", "Stop Loss: ", 4);
CreateScoreLabel("TP", "Take Profit: ", 5); CreateScoreLabel("TP", "Take Profit: ", 5);
CreateScoreLabel("Cross", "Cross: ", 6);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -108,7 +117,7 @@ void CreateScoreLabel(string name, string text, int index)
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Update panel values | //| Update panel values |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void UpdatePanel(double rsi, string position, int spread, string session, double sl, double tp) void UpdatePanel(double rsi, string position, int spread, string session, double sl, double tp, string crossInfo)
{ {
ObjectSetString(0, panelName + "RSI", OBJPROP_TEXT, "RSI: " + DoubleToString(rsi, 2)); ObjectSetString(0, panelName + "RSI", OBJPROP_TEXT, "RSI: " + DoubleToString(rsi, 2));
ObjectSetString(0, panelName + "Position", OBJPROP_TEXT, "Position: " + position); ObjectSetString(0, panelName + "Position", OBJPROP_TEXT, "Position: " + position);
@@ -116,6 +125,7 @@ void UpdatePanel(double rsi, string position, int spread, string session, double
ObjectSetString(0, panelName + "Session", OBJPROP_TEXT, "Session: " + session); ObjectSetString(0, panelName + "Session", OBJPROP_TEXT, "Session: " + session);
ObjectSetString(0, panelName + "SL", OBJPROP_TEXT, "Stop Loss: " + IntegerToString(StopLossPips) + " pips"); ObjectSetString(0, panelName + "SL", OBJPROP_TEXT, "Stop Loss: " + IntegerToString(StopLossPips) + " pips");
ObjectSetString(0, panelName + "TP", OBJPROP_TEXT, "Take Profit: " + IntegerToString(TakeProfitPips) + " pips"); ObjectSetString(0, panelName + "TP", OBJPROP_TEXT, "Take Profit: " + IntegerToString(TakeProfitPips) + " pips");
ObjectSetString(0, panelName + "Cross", OBJPROP_TEXT, "Cross: " + crossInfo);
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -157,20 +167,51 @@ bool IsTradingAllowed()
// Check if market is open // Check if market is open
if(!SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL) if(!SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL)
{ {
Print("Trading is not allowed for ", _Symbol);
return false; return false;
} }
// Check if we have enough money // Check if we have enough money
if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) <= 0) if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) <= 0)
{ {
Print("Not enough free margin");
return false; return false;
} }
return true; return true;
} }
//+------------------------------------------------------------------+
//| Check RSI crossover conditions |
//+------------------------------------------------------------------+
void CheckRSICrossover()
{
// Reset crossover flags
rsiCrossedOverbought = false;
rsiCrossedOversold = false;
rsiCrossedExitLevel = false;
// Check for overbought crossover (RSI crosses above overbought level)
if(rsiPrevious < OverboughtLevel && rsiCurrent >= OverboughtLevel)
{
rsiCrossedOverbought = true;
}
// Check for oversold crossover (RSI crosses below oversold level)
if(rsiPrevious > OversoldLevel && rsiCurrent <= OversoldLevel)
{
rsiCrossedOversold = true;
}
// Check for exit level crossover
if(rsiPrevious < RSIExitLevel && rsiCurrent >= RSIExitLevel)
{
rsiCrossedExitLevel = true;
}
else if(rsiPrevious > RSIExitLevel && rsiCurrent <= RSIExitLevel)
{
rsiCrossedExitLevel = true;
}
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Expert initialization function | //| Expert initialization function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -181,18 +222,47 @@ int OnInit()
if(rsiHandle == INVALID_HANDLE) if(rsiHandle == INVALID_HANDLE)
{ {
Print("Failed to create RSI indicator handle");
return(INIT_FAILED); return(INIT_FAILED);
} }
// Wait a bit for the indicator to be ready
Sleep(100);
// Initialize RSI values with retry logic
double rsi[];
ArraySetAsSeries(rsi, true);
int retryCount = 0;
bool rsiInitialized = false;
while(retryCount < 10 && !rsiInitialized)
{
int copied = CopyBuffer(rsiHandle, 0, 0, 3, rsi);
if(copied >= 3)
{
rsiCurrent = rsi[0];
rsiPrevious = rsi[1];
rsiPrevious2 = rsi[2];
rsiInitialized = true;
}
else
{
retryCount++;
Sleep(100);
}
}
if(!rsiInitialized)
{
// Don't fail initialization, just set default values
rsiCurrent = 50.0;
rsiPrevious = 50.0;
rsiPrevious2 = 50.0;
}
// Create panel // Create panel
CreatePanel(); CreatePanel();
Print("Expert Advisor initialized successfully");
Print("Trading symbol: ", _Symbol);
Print("Account balance: ", AccountInfoDouble(ACCOUNT_BALANCE));
Print("Account leverage: ", AccountInfoInteger(ACCOUNT_LEVERAGE));
return(INIT_SUCCEEDED); return(INIT_SUCCEEDED);
} }
@@ -218,24 +288,18 @@ bool CloseAllTrades(string reason = "")
if(totalPositions == 0) if(totalPositions == 0)
return true; return true;
// Check if there are any positions with our magic number // Check if there are any positions with our magic number
bool hasOurPositions = false; bool hasOurPositions = false;
for(int i = 0; i < totalPositions; i++) for(int i = 0; i < totalPositions; i++)
{ {
if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == 123457) if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == 123456)
{ {
hasOurPositions = true; hasOurPositions = true;
break; break;
} }
} }
// Return if no positions with our magic number
if(!hasOurPositions)
return true;
Print("Attempting to close all positions", (reason != "" ? " - " + reason : ""));
for(int i = totalPositions - 1; i >= 0; i--) for(int i = totalPositions - 1; i >= 0; i--)
{ {
if(PositionGetSymbol(i) == _Symbol) if(PositionGetSymbol(i) == _Symbol)
@@ -248,14 +312,12 @@ bool CloseAllTrades(string reason = "")
{ {
if(trade.PositionClose(_Symbol)) if(trade.PositionClose(_Symbol))
{ {
Print("Position closed successfully");
isPositionOpen = false; isPositionOpen = false;
positionClosed = true; positionClosed = true;
} }
else else
{ {
int error = GetLastError(); int error = GetLastError();
Print("Failed to close position. Error: ", error, " Retry: ", retryCount + 1);
// If error is 4756 (Trade disabled), wait longer before retry // If error is 4756 (Trade disabled), wait longer before retry
if(error == 4756) if(error == 4756)
@@ -273,7 +335,6 @@ bool CloseAllTrades(string reason = "")
if(!positionClosed) if(!positionClosed)
{ {
Print("Failed to close position after all retries");
allClosed = false; allClosed = false;
} }
} }
@@ -290,15 +351,12 @@ void OnTick()
// Check if trading is allowed // Check if trading is allowed
if(!IsTradingAllowed()) if(!IsTradingAllowed())
{ {
Print("Trading is not allowed at the moment");
return; return;
} }
// Check if we're in Asian session // Check if we're in Asian session
if(!IsAsianSession()) if(!IsAsianSession())
{ {
Print("Not in Asian session");
// Close all positions if outside Asian session and CloseOutsideSession is true // Close all positions if outside Asian session and CloseOutsideSession is true
if(CloseOutsideSession && !sessionCloseAttempted) if(CloseOutsideSession && !sessionCloseAttempted)
{ {
@@ -320,17 +378,33 @@ void OnTick()
// Check if spread is too high // Check if spread is too high
if(spreadInPips > MaxSpread) if(spreadInPips > MaxSpread)
{ {
Print("Spread too high: ", spreadInPips, " pips");
return; return;
} }
// Get RSI value // Get RSI values from bar data
double rsi[]; double rsi[];
ArraySetAsSeries(rsi, true); ArraySetAsSeries(rsi, true);
if(CopyBuffer(rsiHandle, 0, 0, 1, rsi) != 1) int copied = CopyBuffer(rsiHandle, 0, 0, 3, rsi);
if(copied < 3)
{
return; return;
}
// Update RSI values
rsiPrevious2 = rsiPrevious;
rsiPrevious = rsiCurrent;
rsiCurrent = rsi[0];
// Validate RSI values
if(rsiCurrent == 0 || rsiPrevious == 0)
{
return;
}
// Check for RSI crossovers
CheckRSICrossover();
// Get current prices // Get current prices
double currentBid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double currentBid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
@@ -351,8 +425,14 @@ void OnTick()
double sl = 0; double sl = 0;
double tp = 0; double tp = 0;
// Prepare crossover info for panel
string crossInfo = "None";
if(rsiCrossedOverbought) crossInfo = "Overbought";
else if(rsiCrossedOversold) crossInfo = "Oversold";
else if(rsiCrossedExitLevel) crossInfo = "Exit";
// Update panel // Update panel
UpdatePanel(rsi[0], positionStatus, spreadInPips, GetCurrentSession(), sl, tp); UpdatePanel(rsiCurrent, positionStatus, spreadInPips, GetCurrentSession(), sl, tp, crossInfo);
// Check for open position // Check for open position
bool hasOpenPosition = false; bool hasOpenPosition = false;
@@ -369,26 +449,24 @@ void OnTick()
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
// Check for RSI exit if enabled // Check for RSI exit if enabled
if(UseRSIExit) if(UseRSIExit && rsiCrossedExitLevel)
{ {
bool shouldExit = false; bool shouldExit = false;
// For long positions, exit when RSI reaches or exceeds exit level // For long positions, exit when RSI crosses above exit level
if(posType == POSITION_TYPE_BUY && rsi[0] >= RSIExitLevel) if(posType == POSITION_TYPE_BUY && rsiCurrent >= RSIExitLevel && rsiPrevious < RSIExitLevel)
{ {
Print("Closing long position due to RSI exit. RSI: ", rsi[0], " Exit Level: ", RSIExitLevel);
shouldExit = true; shouldExit = true;
} }
// For short positions, exit when RSI reaches or falls below exit level // For short positions, exit when RSI crosses below exit level
else if(posType == POSITION_TYPE_SELL && rsi[0] <= RSIExitLevel) else if(posType == POSITION_TYPE_SELL && rsiCurrent <= RSIExitLevel && rsiPrevious > RSIExitLevel)
{ {
Print("Closing short position due to RSI exit. RSI: ", rsi[0], " Exit Level: ", RSIExitLevel);
shouldExit = true; shouldExit = true;
} }
if(shouldExit) if(shouldExit)
{ {
CloseAllTrades("RSI Exit"); CloseAllTrades("RSI Exit Crossover");
return; return;
} }
} }
@@ -396,7 +474,6 @@ void OnTick()
// Check for timeout // Check for timeout
if(TimeCurrent() - positionOpenTime > MaxDuration * 3600) if(TimeCurrent() - positionOpenTime > MaxDuration * 3600)
{ {
Print("Closing position due to timeout");
CloseAllTrades("Timeout"); CloseAllTrades("Timeout");
return; return;
} }
@@ -405,11 +482,11 @@ void OnTick()
} }
} }
// If no position is open, look for entry signals // If no position is open, look for entry signals based on RSI crossover
if(!hasOpenPosition) if(!hasOpenPosition)
{ {
// Place buy order if RSI is oversold // Place buy order if RSI crosses below oversold level (oversold crossover)
if(rsi[0] <= OversoldLevel) if(rsiCrossedOversold)
{ {
double sl = UseStopLoss ? currentBid - StopLossPips * _Point : 0; double sl = UseStopLoss ? currentBid - StopLossPips * _Point : 0;
double tp = UseTakeProfit ? currentBid + TakeProfitPips * _Point : 0; double tp = UseTakeProfit ? currentBid + TakeProfitPips * _Point : 0;
@@ -422,24 +499,19 @@ void OnTick()
// Set trade parameters // Set trade parameters
trade.SetDeviationInPoints(3); trade.SetDeviationInPoints(3);
trade.SetTypeFilling(ORDER_FILLING_IOC); trade.SetTypeFilling(ORDER_FILLING_IOC);
trade.SetExpertMagicNumber(123457); trade.SetExpertMagicNumber(123456);
// Place buy order using CTrade // Place buy order using CTrade
if(!trade.Buy(MaxLotSize, _Symbol, currentAsk, sl, tp, "RSI Buy")) if(trade.Buy(MaxLotSize, _Symbol, currentAsk, sl, tp, "RSI Oversold Crossover Buy"))
{ {
Print("Buy order failed. Error code: ", GetLastError());
}
else
{
Print("Buy order placed. RSI: ", rsi[0]);
isPositionOpen = true; isPositionOpen = true;
positionOpenPrice = currentAsk; positionOpenPrice = currentAsk;
positionOpenTime = TimeCurrent(); positionOpenTime = TimeCurrent();
lastPositionType = POSITION_TYPE_BUY; lastPositionType = POSITION_TYPE_BUY;
} }
} }
// Place sell order if RSI is overbought // Place sell order if RSI crosses above overbought level (overbought crossover)
else if(rsi[0] >= OverboughtLevel) else if(rsiCrossedOverbought)
{ {
double sl = UseStopLoss ? currentAsk + StopLossPips * _Point : 0; double sl = UseStopLoss ? currentAsk + StopLossPips * _Point : 0;
double tp = UseTakeProfit ? currentAsk - TakeProfitPips * _Point : 0; double tp = UseTakeProfit ? currentAsk - TakeProfitPips * _Point : 0;
@@ -452,16 +524,11 @@ void OnTick()
// Set trade parameters // Set trade parameters
trade.SetDeviationInPoints(3); trade.SetDeviationInPoints(3);
trade.SetTypeFilling(ORDER_FILLING_IOC); trade.SetTypeFilling(ORDER_FILLING_IOC);
trade.SetExpertMagicNumber(123457); trade.SetExpertMagicNumber(123456);
// Place sell order using CTrade // Place sell order using CTrade
if(!trade.Sell(MaxLotSize, _Symbol, currentBid, sl, tp, "RSI Sell")) if(trade.Sell(MaxLotSize, _Symbol, currentBid, sl, tp, "RSI Overbought Crossover Sell"))
{ {
Print("Sell order failed. Error code: ", GetLastError());
}
else
{
Print("Sell order placed. RSI: ", rsi[0]);
isPositionOpen = true; isPositionOpen = true;
positionOpenPrice = currentBid; positionOpenPrice = currentBid;
positionOpenTime = TimeCurrent(); positionOpenTime = TimeCurrent();
@@ -469,4 +536,4 @@ void OnTick()
} }
} }
} }
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

After

Width:  |  Height:  |  Size: 250 KiB