diff --git a/README.md b/README.md index 42b0b6e..deaf705 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [5. RSI Reversal Asian AUDUSD](#5-rsi-reversal-asian-audusd) - [6. RSI Reversal Asian EURUSD](#6-rsi-reversal-asian-eurusd) - [7. EMA Crossover BTC](#7-ema-crossover-btc) + - [8. Smart RSI BTC](#8-smart-rsi-btc) - [Technical Details](#technical-details) - [Requirements](#requirements) - [Installation](#installation) @@ -506,6 +507,73 @@ A strategy specifically designed for Bitcoin (BTCUSD) using EMA crossovers with **Balance Sheet (2021-2025):** ![EMA Crossover BTC Balance Sheet](EMACrossOverBTC/test-balance.jpg) + +### 8. Smart RSI BTC + +A strategy that implements a smart RSI-based trading system specifically optimized for Bitcoin trading. + +**Key Features:** +- Advanced RSI-based entry and exit signals +- Dynamic position sizing +- Risk management through stop loss and take profit levels +- Optimized for Bitcoin market conditions + +**Strategy Settings:** +- Symbol: BTCUSD +- Period: H1 +- RSI Period: 14 +- RSI Overbought: 70 +- RSI Oversold: 30 +- Base Lot Size: 0.01 +- Max Spread: 50 +- Max Risk Percent: 2% +- Max Drawdown Percent: 10% +- Max Consecutive Losses: 3 +- Max Lot Size: 0.1 + +**Performance Metrics:** +| Metric | Value | +|--------|-------| +| Total Net Profit | $1,344.74 | +| Gross Profit | $4,410.51 | +| Gross Loss | -$3,065.77 | +| Profit Factor | 1.44 | +| Recovery Factor | 4.91 | +| Expected Payoff | $4.87 | +| Sharpe Ratio | 1.69 | +| AHPR | 1.0033 (0.33%) | +| GHPR | 1.0031 (0.31%) | + +**Trade Statistics:** +| Statistic | Value | +|-----------|-------| +| Total Trades | 276 | +| Total Deals | 552 | +| Profit Trades | 81 (29.35%) | +| Loss Trades | 195 (70.65%) | +| Short Trades Won | 26.28% | +| Long Trades Won | 32.37% | +| Largest Profit Trade | $144.46 | +| Largest Loss Trade | -$46.66 | +| Average Profit Trade | $54.45 | +| Average Loss Trade | -$15.72 | +| Max Consecutive Wins | 3 ($179.71) | +| Max Consecutive Losses | 15 (-$159.89) | + +**Drawdown Analysis:** +| Metric | Value | +|--------|-------| +| Balance Drawdown Absolute | $18.62 | +| Equity Drawdown Absolute | $19.45 | +| Balance Drawdown Maximal | $231.79 (10.21%) | +| Equity Drawdown Maximal | $273.75 (11.93%) | +| Balance Drawdown Relative | 13.47% ($210.14) | +| Equity Drawdown Relative | 15.85% ($250.78) | + +**Balance Sheet:** +![Smart RSI BTC Balance Sheet](SmartRSIBTC/test-balance.jpg) + + ## Technical Details Each EA is implemented in MQL5 and includes: - Custom strategy implementation diff --git a/RSIReversalAsianEURUSD/main.mq5 b/RSIReversalAsianEURUSD/main.mq5 index c3ed4a6..414a69b 100644 --- a/RSIReversalAsianEURUSD/main.mq5 +++ b/RSIReversalAsianEURUSD/main.mq5 @@ -17,7 +17,7 @@ input double OverboughtLevel = 77; // Overbought level input double OversoldLevel = 10; // Oversold level input int TakeProfitPips = 116; // Take profit in pips input int StopLossPips = 247; // Stop loss in pips -input double MaxLotSize = 0.1; // Maximum lot size +input double MaxLotSize = 0.05; // Maximum lot size input int MaxSpread = 1000; // Maximum allowed spread in pips input int MaxDuration = 67; // Maximum trade duration in hours input bool UseStopLoss = true; // Use stop loss diff --git a/RSIReversalAsianEURUSD/test-balance-2016.jpg b/RSIReversalAsianEURUSD/test-balance-2016.jpg new file mode 100644 index 0000000..7de4e56 Binary files /dev/null and b/RSIReversalAsianEURUSD/test-balance-2016.jpg differ diff --git a/SmartRSIBTC/main.mq5 b/SmartRSIBTC/main.mq5 new file mode 100644 index 0000000..78f739b --- /dev/null +++ b/SmartRSIBTC/main.mq5 @@ -0,0 +1,325 @@ +//+------------------------------------------------------------------+ +//| SmartRSI.mq5 | +//| Copyright 2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2024, MetaQuotes Ltd." +#property link "https://www.mql5.com" +#property version "1.00" + +#include + +// Input parameters for RSI +input group "RSI Settings" +input int RSI_Period = 89; // RSI Period +input ENUM_APPLIED_PRICE RSI_Price = PRICE_TYPICAL; // RSI Applied Price + +// Strategy Selection +input group "Strategy Selection" +input bool UseTrendFollowing = true; // Use Trend Following Strategy +input bool UseReversal = false; // Use Reversal Strategy + +// Enum for RSI conditions +enum ENUM_RSI_CONDITION +{ + RSI_BELOW_OVERSOLD, // RSI below oversold level + RSI_ABOVE_OVERBOUGHT, // RSI above overbought level + RSI_BELOW_MIDPOINT, // RSI below midpoint + RSI_ABOVE_MIDPOINT, // RSI above midpoint + RSI_CROSS_OVERSOLD, // RSI crosses below oversold + RSI_CROSS_OVERBOUGHT // RSI crosses above overbought +}; + +// Entry/Exit Conditions +input group "Entry/Exit Conditions" +input ENUM_RSI_CONDITION Trend_Entry_Condition = RSI_BELOW_OVERSOLD; // Trend Entry Condition +input ENUM_RSI_CONDITION Trend_Exit_Condition = RSI_ABOVE_MIDPOINT; // Trend Exit Condition +input ENUM_RSI_CONDITION Rev_Entry_Condition = RSI_BELOW_OVERSOLD; // Reversal Entry Condition +input ENUM_RSI_CONDITION Rev_Exit_Condition = RSI_ABOVE_MIDPOINT; // Reversal Exit Condition + +// Trend Following Strategy Parameters +input group "Trend Following Strategy" +input double Trend_Overbought = 51; // Overbought level for trend following +input double Trend_Oversold = 30; // Oversold level for trend following +input double Trend_Exit_Long = 50; // Exit level for long positions +input double Trend_Exit_Short = 50; // Exit level for short positions +input double Trend_LotSize = 0.1; // Lot size for trend following +input int Trend_Magic = 12345; // Magic number for trend following +input bool Trend_CloseOpposite = true; // Close opposite trades on profit +input double Trend_ProfitToClose = 15; // Profit in points to close opposite trades +input int Trend_TimeToClose = 9; // Bars to wait before closing opposite trades + +// Reversal Strategy Parameters +input group "Reversal Strategy" +input double Rev_Overbought = 70; // Overbought level for reversal +input double Rev_Oversold = 30; // Oversold level for reversal +input double Rev_Exit_Long = 50; // Exit level for long positions +input double Rev_Exit_Short = 50; // Exit level for short positions +input double Rev_LotSize = 0.1; // Lot size for reversal +input int Rev_Magic = 54321; // Magic number for reversal +input bool Rev_CloseOpposite = true; // Close opposite trades on profit +input double Rev_ProfitToClose = 50; // Profit in points to close opposite trades +input int Rev_TimeToClose = 5; // Bars to wait before closing opposite trades + + + +// Indicator buffers +double rsi_buffer[]; +int rsi_handle; +CTrade trade; +datetime last_bar_time; +datetime trend_long_entry_time = 0; +datetime trend_short_entry_time = 0; +datetime rev_long_entry_time = 0; +datetime rev_short_entry_time = 0; + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() +{ + // Initialize RSI indicator + rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, RSI_Price); + if(rsi_handle == INVALID_HANDLE) + { + Print("Failed to create RSI indicator"); + return INIT_FAILED; + } + + // Set buffer size and series + ArraySetAsSeries(rsi_buffer, true); + + // Initialize trade object + trade.SetExpertMagicNumber(Trend_Magic); + trade.SetMarginMode(); + trade.SetTypeFillingBySymbol(_Symbol); + trade.SetDeviationInPoints(10); + + // Initialize last bar time + last_bar_time = 0; + + return(INIT_SUCCEEDED); +} + +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) +{ + if(rsi_handle != INVALID_HANDLE) + IndicatorRelease(rsi_handle); +} + +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() +{ + datetime current_time = iTime(_Symbol, PERIOD_CURRENT, 0); + + // Check if new bar has formed + if(current_time != last_bar_time) + { + last_bar_time = current_time; + + // Update RSI values + if(CopyBuffer(rsi_handle, 0, 0, 2, rsi_buffer) <= 0) + { + Print("Failed to copy RSI buffer"); + return; + } + + // Run strategies if enabled + if(UseTrendFollowing) + CheckTrendFollowing(); + + if(UseReversal) + CheckReversal(); + } +} + +//+------------------------------------------------------------------+ +//| Check RSI Condition | +//+------------------------------------------------------------------+ +bool CheckRSICondition(ENUM_RSI_CONDITION condition, double level) +{ + switch(condition) + { + case RSI_BELOW_OVERSOLD: + return rsi_buffer[0] < level; + case RSI_ABOVE_OVERBOUGHT: + return rsi_buffer[0] > level; + case RSI_BELOW_MIDPOINT: + return rsi_buffer[0] < 50; + case RSI_ABOVE_MIDPOINT: + return rsi_buffer[0] > 50; + case RSI_CROSS_OVERSOLD: + return rsi_buffer[0] < level && rsi_buffer[1] >= level; + case RSI_CROSS_OVERBOUGHT: + return rsi_buffer[0] > level && rsi_buffer[1] <= level; + } + return false; +} + +//+------------------------------------------------------------------+ +//| Check Trend Following Strategy | +//+------------------------------------------------------------------+ +void CheckTrendFollowing() +{ + // Check for existing positions + bool hasLong = PositionSelectByMagic(Trend_Magic, POSITION_TYPE_BUY); + bool hasShort = PositionSelectByMagic(Trend_Magic, POSITION_TYPE_SELL); + + // Entry logic + if(!hasLong && !hasShort) + { + if(CheckRSICondition(Trend_Entry_Condition, Trend_Oversold)) + { + // Open short position + trade.SetExpertMagicNumber(Trend_Magic); + trade.Sell(Trend_LotSize, _Symbol, 0, 0, 0, "SmartRSI Trend"); + trend_short_entry_time = TimeCurrent(); + } + else if(CheckRSICondition(Trend_Entry_Condition, Trend_Overbought)) + { + // Open long position + trade.SetExpertMagicNumber(Trend_Magic); + trade.Buy(Trend_LotSize, _Symbol, 0, 0, 0, "SmartRSI Trend"); + trend_long_entry_time = TimeCurrent(); + } + } + + // Exit logic + if(hasLong && CheckRSICondition(Trend_Exit_Condition, Trend_Exit_Long)) + { + trade.SetExpertMagicNumber(Trend_Magic); + trade.PositionClose(_Symbol); + } + else if(hasShort && CheckRSICondition(Trend_Exit_Condition, Trend_Exit_Short)) + { + trade.SetExpertMagicNumber(Trend_Magic); + trade.PositionClose(_Symbol); + } + + // Check for opposite trade closing + if(Trend_CloseOpposite) + { + if(hasLong && (TimeCurrent() - trend_long_entry_time) >= Trend_TimeToClose * PeriodSeconds(PERIOD_CURRENT)) + { + double profit = PositionGetDouble(POSITION_PROFIT); + if(profit >= Trend_ProfitToClose * _Point) + { + // Close short position if exists + if(PositionSelectByMagic(Trend_Magic, POSITION_TYPE_SELL)) + { + trade.SetExpertMagicNumber(Trend_Magic); + trade.PositionClose(_Symbol); + } + } + } + else if(hasShort && (TimeCurrent() - trend_short_entry_time) >= Trend_TimeToClose * PeriodSeconds(PERIOD_CURRENT)) + { + double profit = PositionGetDouble(POSITION_PROFIT); + if(profit >= Trend_ProfitToClose * _Point) + { + // Close long position if exists + if(PositionSelectByMagic(Trend_Magic, POSITION_TYPE_BUY)) + { + trade.SetExpertMagicNumber(Trend_Magic); + trade.PositionClose(_Symbol); + } + } + } + } +} + +//+------------------------------------------------------------------+ +//| Check Reversal Strategy | +//+------------------------------------------------------------------+ +void CheckReversal() +{ + // Check for existing positions + bool hasLong = PositionSelectByMagic(Rev_Magic, POSITION_TYPE_BUY); + bool hasShort = PositionSelectByMagic(Rev_Magic, POSITION_TYPE_SELL); + + // Entry logic + if(!hasLong && !hasShort) + { + if(CheckRSICondition(Rev_Entry_Condition, Rev_Oversold)) + { + // Open long position + trade.SetExpertMagicNumber(Rev_Magic); + trade.Buy(Rev_LotSize, _Symbol, 0, 0, 0, "SmartRSI Reversal"); + rev_long_entry_time = TimeCurrent(); + } + else if(CheckRSICondition(Rev_Entry_Condition, Rev_Overbought)) + { + // Open short position + trade.SetExpertMagicNumber(Rev_Magic); + trade.Sell(Rev_LotSize, _Symbol, 0, 0, 0, "SmartRSI Reversal"); + rev_short_entry_time = TimeCurrent(); + } + } + + // Exit logic + if(hasLong && CheckRSICondition(Rev_Exit_Condition, Rev_Exit_Long)) + { + trade.SetExpertMagicNumber(Rev_Magic); + trade.PositionClose(_Symbol); + } + else if(hasShort && CheckRSICondition(Rev_Exit_Condition, Rev_Exit_Short)) + { + trade.SetExpertMagicNumber(Rev_Magic); + trade.PositionClose(_Symbol); + } + + // Check for opposite trade closing + if(Rev_CloseOpposite) + { + if(hasLong && (TimeCurrent() - rev_long_entry_time) >= Rev_TimeToClose * PeriodSeconds(PERIOD_CURRENT)) + { + double profit = PositionGetDouble(POSITION_PROFIT); + if(profit >= Rev_ProfitToClose * _Point) + { + // Close short position if exists + if(PositionSelectByMagic(Rev_Magic, POSITION_TYPE_SELL)) + { + trade.SetExpertMagicNumber(Rev_Magic); + trade.PositionClose(_Symbol); + } + } + } + else if(hasShort && (TimeCurrent() - rev_short_entry_time) >= Rev_TimeToClose * PeriodSeconds(PERIOD_CURRENT)) + { + double profit = PositionGetDouble(POSITION_PROFIT); + if(profit >= Rev_ProfitToClose * _Point) + { + // Close long position if exists + if(PositionSelectByMagic(Rev_Magic, POSITION_TYPE_BUY)) + { + trade.SetExpertMagicNumber(Rev_Magic); + trade.PositionClose(_Symbol); + } + } + } + } +} + +//+------------------------------------------------------------------+ +//| Position Select By Magic | +//+------------------------------------------------------------------+ +bool PositionSelectByMagic(int magic, ENUM_POSITION_TYPE posType) +{ + for(int i = PositionsTotal() - 1; i >= 0; i--) + { + if(PositionGetTicket(i)) + { + if(PositionGetInteger(POSITION_MAGIC) == magic && + PositionGetInteger(POSITION_TYPE) == posType) + { + return true; + } + } + } + return false; +} diff --git a/SmartRSIBTC/test-balance.jpg b/SmartRSIBTC/test-balance.jpg new file mode 100644 index 0000000..e459c64 Binary files /dev/null and b/SmartRSIBTC/test-balance.jpg differ