diff --git a/EMASlopeDistanceCocktailXAUUSD/main.mq5 b/EMASlopeDistanceCocktailXAUUSD/main.mq5 index e69de29..421c19d 100644 --- a/EMASlopeDistanceCocktailXAUUSD/main.mq5 +++ b/EMASlopeDistanceCocktailXAUUSD/main.mq5 @@ -0,0 +1,515 @@ +//+------------------------------------------------------------------+ +//| EMACrossOver.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 +//--- Eingabeparameter (Input Parameters) +input int EMA_Periode = 26; // EMA Periode +input double PreisSchwelle = 2050.0; // Preisbewegung Schwelle in Pips +input double SteigungSchwelle = 100.0; // EMA Steigung Schwelle in Pips +input int ÜberwachungTimeout = 750; // Überwachungszeit in Sekunden +input double TrailingStop = 400.0; // Gleitender Stop in Pips +input double LotGröße = 0.1; // Handelsvolumen +input int MagicNumber = 12350; // Magic Number für Trades +input bool UseSpreadAdjustment = true; // Spread-Anpassung verwenden +input ENUM_TIMEFRAMES Timeframe = PERIOD_H1; // Zeitraum für Analyse +input bool UseBarData = true; // Bar-Daten statt Tick-Daten verwenden +input int MaxTradesPerCrossover = 4; // Maximale Trades pro Crossover-Ereignis +input int ProfitCheckBars = 26; // Bars bis zur Profit-Prüfung +input bool CloseUnprofitableTrades = true; // Unprofitable Trades nach X Bars schließen + +//--- Globale Variablen (Global Variables) +int ema_handle; // EMA Indicator Handle +double ema_array[]; // Array für EMA +datetime letzte_überwachung_zeit; // Zeit der letzten Überwachung +bool überwachung_aktiv = false; // Überwachungsstatus +bool preis_trigger_aktiv = false; // Preis-Trigger Status +bool steigung_trigger_aktiv = false; // Steigungs-Trigger Status +int ticket = 0; // Trade Ticket +CTrade trade; // CTrade Objekt +int trades_in_current_crossover = 0; // Anzahl Trades im aktuellen Crossover +bool crossover_detected = false; // Crossover erkannt +datetime trade_open_time = 0; // Zeitpunkt des Trade-Öffnens + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { + //--- CTrade konfigurieren (Configure CTrade) + trade.SetExpertMagicNumber(MagicNumber); + trade.SetDeviationInPoints(10); + trade.SetTypeFilling(ORDER_FILLING_IOC); + + //--- EMA Indicator Handle erstellen (Create EMA indicator handle) + ema_handle = iMA(_Symbol, Timeframe, EMA_Periode, 0, MODE_EMA, PRICE_CLOSE); + + if(ema_handle == INVALID_HANDLE) + { + Print("Fehler beim Erstellen des EMA Indicators"); + return(INIT_FAILED); + } + + //--- Arrays initialisieren (Initialize arrays) + ArraySetAsSeries(ema_array, true); + + //--- Arrays mit aktuellen Werten füllen (Fill arrays with current values) + BerechneEMA(); + + Print("EMA EA initialisiert - Periode: ", EMA_Periode, " Timeframe: ", EnumToString(Timeframe), " Handle: ", ema_handle); + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + //--- Indicator Handle freigeben (Release indicator handle) + if(ema_handle != INVALID_HANDLE) + { + IndicatorRelease(ema_handle); + } + + Print("EA beendet - Grund: ", reason); +} + +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { + //--- Bar-Daten oder Tick-Daten verwenden (Use bar data or tick data) + if(UseBarData) + { + //--- Nur bei neuen Bars ausführen (Only execute on new bars) + static datetime last_bar_time = 0; + datetime current_bar_time = iTime(_Symbol, Timeframe, 0); + + if(current_bar_time == last_bar_time) + { + return; // Kein neuer Bar, nichts tun + } + + last_bar_time = current_bar_time; + } + + //--- EMA Werte berechnen (Calculate EMA values) + BerechneEMA(); + + //--- Debug: Aktuelle Werte ausgeben (Debug: Output current values) + if(ArraySize(ema_array) > 0) + { + double aktueller_close = iClose(_Symbol, Timeframe, 0); + double ema_aktuell = ema_array[0]; + double ema_vorher = ema_array[1]; + double preis_abstand = MathAbs(aktueller_close - ema_aktuell) / _Point; + double steigung = (ema_aktuell - ema_vorher) / _Point; + + if(UseBarData) + { + Print("=== DEBUG INFO (Neuer Bar) ==="); + Print("Bar Zeit: ", TimeToString(iTime(_Symbol, Timeframe, 0))); + } + else + { + Print("=== DEBUG INFO (Tick) ==="); + } + + Print("Aktueller Close: ", aktueller_close); + Print("EMA: ", ema_aktuell); + Print("Preis-Abstand: ", preis_abstand, " Pips"); + Print("EMA Steigung: ", steigung, " Pips"); + Print("Differenz Close-EMA: ", aktueller_close - ema_aktuell); + Print("Preis-Trigger: ", preis_trigger_aktiv, " Steigungs-Trigger: ", steigung_trigger_aktiv); + Print("Überwachung aktiv: ", überwachung_aktiv); + Print("Position offen: ", PositionSelect(_Symbol)); + Print("Trades im aktuellen Crossover: ", trades_in_current_crossover, "/", MaxTradesPerCrossover); + Print("=================="); + } + + //--- Überwachung prüfen (Check monitoring) + if(überwachung_aktiv) + { + if(UseBarData) + { + // Bar-basierte Überwachungszeit + int bars_since_monitoring = iBarShift(_Symbol, Timeframe, letzte_überwachung_zeit); + int timeout_bars = (int)(ÜberwachungTimeout / PeriodSeconds(Timeframe)); + + if(bars_since_monitoring > timeout_bars) + { + überwachung_aktiv = false; + preis_trigger_aktiv = false; + steigung_trigger_aktiv = false; + Print("Überwachung beendet - Bar-basierte Zeitüberschreitung (", bars_since_monitoring, " Bars)"); + } + } + else + { + // Tick-basierte Überwachungszeit + if(TimeCurrent() - letzte_überwachung_zeit > ÜberwachungTimeout) + { + überwachung_aktiv = false; + preis_trigger_aktiv = false; + steigung_trigger_aktiv = false; + Print("Überwachung beendet - Tick-basierte Zeitüberschreitung"); + } + } + } + + //--- Trigger-Bedingungen prüfen (Check trigger conditions) + PrüfeTrigger(); + + //--- Trade Management (Trade management) + VerwalteTrades(); +} + +//+------------------------------------------------------------------+ +//| EMA Berechnung (EMA Calculation) | +//+------------------------------------------------------------------+ +void BerechneEMA() +{ + //--- EMA Werte vom Indicator kopieren (Copy EMA values from indicator) + int copied = CopyBuffer(ema_handle, 0, 0, 3, ema_array); + + if(copied <= 0) + { + Print("TRACE: Fehler beim Kopieren der EMA Werte - Copied: ", copied); + return; + } + + Print("TRACE: EMA Werte kopiert: ", copied, " Bars"); + Print("TRACE: EMA [0]: ", ema_array[0], " [1]: ", ema_array[1], " [2]: ", ema_array[2]); +} + +//+------------------------------------------------------------------+ +//| Trigger-Bedingungen prüfen (Check trigger conditions) | +//+------------------------------------------------------------------+ +void PrüfeTrigger() +{ + if(ArraySize(ema_array) < 2) + { + Print("TRACE: Array zu klein - Größe: ", ArraySize(ema_array)); + return; + } + + //--- Aktuelle Werte (Current values) + double aktueller_preis = SymbolInfoDouble(_Symbol, SYMBOL_BID); + double aktueller_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); + double aktueller_close = iClose(_Symbol, Timeframe, 0); + double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; + + //--- EMA Werte in Variablen (EMA values in variables) + double ema_aktuell = ema_array[0]; + double ema_vorher = ema_array[1]; + + //--- EMA Crossover Erkennung (EMA Crossover Detection) + // Prüfe ob Preis die EMA kreuzt (Check if price crosses EMA) + static double last_close = 0; + static double last_ema = 0; + + if(last_close != 0 && last_ema != 0) + { + bool crossover_bullish = (last_close <= last_ema) && (aktueller_close > ema_aktuell); + bool crossover_bearish = (last_close >= last_ema) && (aktueller_close < ema_aktuell); + + //--- Neues Crossover-Ereignis erkannt (New crossover event detected) + if(crossover_bullish || crossover_bearish) + { + trades_in_current_crossover = 0; // Reset trade counter + Print("TRACE: EMA Crossover erkannt - ", (crossover_bullish ? "BULLISH" : "BEARISH"), " - Trade-Counter zurückgesetzt"); + Print("TRACE: Vorher: Close=", last_close, " EMA=", last_ema, " Jetzt: Close=", aktueller_close, " EMA=", ema_aktuell); + } + } + + //--- Aktuelle Werte für nächsten Vergleich speichern (Save current values for next comparison) + last_close = aktueller_close; + last_ema = ema_aktuell; + + //--- Preisbewegung zur EMA prüfen (Check price action to EMA) + double preis_abstand = MathAbs(aktueller_close - ema_aktuell) / _Point / pips_multiplier; + + Print("TRACE: Preis-Abstand: ", preis_abstand, " Pips (Schwelle: ", PreisSchwelle, ")"); + Print("TRACE: Close: ", aktueller_close, " EMA: ", ema_aktuell); + Print("TRACE: Trades im aktuellen Crossover: ", trades_in_current_crossover, "/", MaxTradesPerCrossover); + + if(preis_abstand > PreisSchwelle && !preis_trigger_aktiv) + { + preis_trigger_aktiv = true; + Print("TRACE: Preis-Trigger aktiviert: ", preis_abstand, " Pips"); + } + + //--- EMA Steigung prüfen (Check EMA slope) + double steigung = (ema_aktuell - ema_vorher) / _Point / pips_multiplier; + + Print("TRACE: EMA Steigung: ", steigung, " Pips (Schwelle: ", SteigungSchwelle, ")"); + + if(MathAbs(steigung) > SteigungSchwelle && !steigung_trigger_aktiv) + { + steigung_trigger_aktiv = true; + Print("TRACE: Steigungs-Trigger aktiviert: ", steigung, " Pips"); + } + + //--- Überwachung starten wenn beide Trigger aktiv sind (Start monitoring when both triggers are active) + if(preis_trigger_aktiv && steigung_trigger_aktiv && !überwachung_aktiv) + { + überwachung_aktiv = true; + + if(UseBarData) + { + letzte_überwachung_zeit = iTime(_Symbol, Timeframe, 0); // Aktuelle Bar-Zeit + Print("TRACE: Überwachung gestartet - Beide Trigger aktiv (Bar: ", TimeToString(letzte_überwachung_zeit), ")"); + } + else + { + letzte_überwachung_zeit = TimeCurrent(); // Aktuelle Tick-Zeit + Print("TRACE: Überwachung gestartet - Beide Trigger aktiv (Tick)"); + } + } + + //--- Trade platzieren wenn Überwachung aktiv und Preis über/unter EMA (Place trade when monitoring active and price above/below EMA) + if(überwachung_aktiv) + { + bool bullish_signal = aktueller_close > ema_aktuell; + bool bearish_signal = aktueller_close < ema_aktuell; + + Print("TRACE: Signal Check - Bullish: ", bullish_signal, " Bearish: ", bearish_signal); + Print("TRACE: Close: ", aktueller_close, " EMA: ", ema_aktuell); + Print("TRACE: Differenz: ", aktueller_close - ema_aktuell); + + //--- Trade-Limit prüfen (Check trade limit) + if(trades_in_current_crossover >= MaxTradesPerCrossover) + { + Print("TRACE: Trade-Limit erreicht (", MaxTradesPerCrossover, ") - Kein neuer Trade"); + return; + } + + if(bullish_signal && !PositionSelect(_Symbol)) + { + Print("TRACE: Versuche KAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")"); + if(PlatziereTrade(ORDER_TYPE_BUY)) + { + trades_in_current_crossover++; + } + } + else if(bearish_signal && !PositionSelect(_Symbol)) + { + Print("TRACE: Versuche VERKAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")"); + if(PlatziereTrade(ORDER_TYPE_SELL)) + { + trades_in_current_crossover++; + } + } + else if(PositionSelect(_Symbol)) + { + Print("TRACE: Position bereits offen - kein neuer Trade"); + } + } +} + +//+------------------------------------------------------------------+ +//| Trade platzieren (Place trade) | +//+------------------------------------------------------------------+ +bool PlatziereTrade(ENUM_ORDER_TYPE order_type) +{ + Print("TRACE: Versuche Trade zu platzieren - Typ: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF"); + Print("TRACE: Lot: ", LotGröße); + + bool success = false; + + if(order_type == ORDER_TYPE_BUY) + { + success = trade.Buy(LotGröße, _Symbol, 0, 0, 0, "EMA Crossover Trade"); + } + else + { + success = trade.Sell(LotGröße, _Symbol, 0, 0, 0, "EMA Crossover Trade"); + } + + if(success) + { + ticket = (int)trade.ResultOrder(); + Print("TRACE: Trade erfolgreich platziert: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF", " Ticket: ", ticket); + + //--- Trade-Öffnungszeit speichern (Save trade opening time) + trade_open_time = iTime(_Symbol, Timeframe, 0); + Print("TRACE: Trade-Öffnungszeit: ", TimeToString(trade_open_time)); + + //--- Überwachung zurücksetzen (Reset monitoring) + überwachung_aktiv = false; + preis_trigger_aktiv = false; + steigung_trigger_aktiv = false; + + return true; + } + else + { + Print("TRACE: Fehler beim Platzieren des Trades - Retcode: ", trade.ResultRetcode()); + Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); + + return false; + } +} + +//+------------------------------------------------------------------+ +//| Trades verwalten (Manage trades) | +//+------------------------------------------------------------------+ +void VerwalteTrades() +{ + if(!PositionSelect(_Symbol)) + return; + + double position_profit = PositionGetDouble(POSITION_PROFIT); + double position_open_price = PositionGetDouble(POSITION_PRICE_OPEN); + double current_price = PositionGetDouble(POSITION_PRICE_CURRENT); + ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; + double trailing_stop_pips = TrailingStop; + + //--- Gleitender Stop (Trailing Stop) - nur wenn Position im Profit ist + if(position_profit > 0) // Only apply trailing stop when in profit + { + if(position_type == POSITION_TYPE_BUY) + { + double new_stop_loss = current_price - (trailing_stop_pips * _Point * pips_multiplier); + double current_stop_loss = PositionGetDouble(POSITION_SL); + + // Only move stop loss if new stop is higher than current stop + if(new_stop_loss > current_stop_loss) + { + ÄndereStopLoss(new_stop_loss); + } + } + else if(position_type == POSITION_TYPE_SELL) + { + double new_stop_loss = current_price + (trailing_stop_pips * _Point * pips_multiplier); + double current_stop_loss = PositionGetDouble(POSITION_SL); + + // Only move stop loss if new stop is lower than current stop + if(new_stop_loss < current_stop_loss || current_stop_loss == 0) + { + ÄndereStopLoss(new_stop_loss); + } + } + } + + //--- Ausstieg bei Preis unter/über EMA (Exit when price below/above EMA) + if(ArraySize(ema_array) >= 1) + { + double aktueller_close = iClose(_Symbol, Timeframe, 0); + double ema_aktuell = ema_array[0]; + bool exit_bullish = (position_type == POSITION_TYPE_SELL && aktueller_close > ema_aktuell); + bool exit_bearish = (position_type == POSITION_TYPE_BUY && aktueller_close < ema_aktuell); + + if(exit_bullish || exit_bearish) + { + Print("TRACE: Ausstiegssignal - Close: ", aktueller_close, " EMA: ", ema_aktuell); + SchließePosition("EMA Crossover Exit"); + + Print("TRACE: Position geschlossen - Trade-Counter bleibt bei ", trades_in_current_crossover); + } + } + + //--- Profit-Prüfung nach X Bars (Profit check after X bars) + if(CloseUnprofitableTrades && trade_open_time != 0 && PositionSelect(_Symbol)) + { + Print("TRACE: Profit-Prüfung aktiviert - CloseUnprofitableTrades: ", CloseUnprofitableTrades); + PrüfeProfitNachBars(); + } + else if(!CloseUnprofitableTrades) + { + Print("TRACE: Profit-Prüfung deaktiviert - CloseUnprofitableTrades: ", CloseUnprofitableTrades); + } +} + +//+------------------------------------------------------------------+ +//| Profit-Prüfung nach X Bars (Profit check after X bars) | +//+------------------------------------------------------------------+ +void PrüfeProfitNachBars() +{ + if(!PositionSelect(_Symbol)) + { + return; // Keine Position offen + } + + datetime current_bar_time = iTime(_Symbol, Timeframe, 0); + int bars_since_trade_open = iBarShift(_Symbol, Timeframe, trade_open_time); + + Print("TRACE: Bars seit Trade-Öffnung: ", bars_since_trade_open, "/", ProfitCheckBars); + + //--- Prüfe ob genügend Bars vergangen sind (Check if enough bars have passed) + if(bars_since_trade_open >= ProfitCheckBars) + { + double position_profit = PositionGetDouble(POSITION_PROFIT); + double position_volume = PositionGetDouble(POSITION_VOLUME); + ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + Print("TRACE: Profit-Prüfung nach ", ProfitCheckBars, " Bars"); + Print("TRACE: Position Profit: ", position_profit, " USD"); + + //--- Schließe Position wenn nicht im Profit (Close position if not in profit) + if(position_profit <= 0) + { + Print("TRACE: Position nicht im Profit - Schließe Position"); + SchließePosition("Profit Check - Unprofitable"); + + //--- Trade-Öffnungszeit zurücksetzen (Reset trade opening time) + trade_open_time = 0; + Print("TRACE: Trade-Öffnungszeit zurückgesetzt"); + } + else + { + Print("TRACE: Position im Profit - Behalte Position"); + //--- Trade-Öffnungszeit zurücksetzen um weitere Prüfungen zu vermeiden (Reset to avoid further checks) + trade_open_time = 0; + } + } +} + +//+------------------------------------------------------------------+ +//| Stop Loss ändern (Modify Stop Loss) | +//+------------------------------------------------------------------+ +void ÄndereStopLoss(double new_stop_loss) +{ + Print("TRACE: Versuche Stop Loss zu ändern auf: ", new_stop_loss); + + bool success = trade.PositionModify(_Symbol, new_stop_loss, PositionGetDouble(POSITION_TP)); + + if(success) + { + Print("TRACE: Stop Loss erfolgreich geändert auf: ", new_stop_loss); + } + else + { + Print("TRACE: Fehler beim Ändern des Stop Loss - Retcode: ", trade.ResultRetcode()); + Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); + } +} + +//+------------------------------------------------------------------+ +//| Position schließen (Close position) | +//+------------------------------------------------------------------+ +void SchließePosition(string reason = "Unbekannt") +{ + Print("TRACE: Versuche Position zu schließen - Grund: ", reason); + + bool success = trade.PositionClose(_Symbol); + + if(success) + { + Print("TRACE: Position erfolgreich geschlossen - Grund: ", reason); + } + else + { + Print("TRACE: Fehler beim Schließen der Position - Retcode: ", trade.ResultRetcode()); + Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); + } +} + +//+------------------------------------------------------------------+ diff --git a/EMASlopeDistanceCocktailXAUUSD/test-balance.jpg b/EMASlopeDistanceCocktailXAUUSD/test-balance.jpg index 69cd846..0e93cab 100644 Binary files a/EMASlopeDistanceCocktailXAUUSD/test-balance.jpg and b/EMASlopeDistanceCocktailXAUUSD/test-balance.jpg differ diff --git a/RSIScalpingAPPL/main.mq5 b/RSIScalpingAPPL/main.mq5 new file mode 100644 index 0000000..bad9ead --- /dev/null +++ b/RSIScalpingAPPL/main.mq5 @@ -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 + +//--- Input parameters +input ENUM_TIMEFRAMES TimeFrame = PERIOD_H4; // 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 = 82; // RSI Overbought Level +input double RSI_Oversold = 55; // RSI Oversold Level +input double RSI_Target_Buy = 39; // RSI Target for Buy Exit +input double RSI_Target_Sell = 35; // RSI Target for Sell Exit +input int BarsToWait = 2; // Bars to wait when RSI goes against position +input double LotSize = 50; // 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; + } +} diff --git a/RSIScalpingMSFT/main.mq5 b/RSIScalpingMSFT/main.mq5 new file mode 100644 index 0000000..72711c3 --- /dev/null +++ b/RSIScalpingMSFT/main.mq5 @@ -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 + +//--- Input parameters +input ENUM_TIMEFRAMES TimeFrame = PERIOD_H3; // 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 = 19; // RSI Overbought Level +input double RSI_Oversold = 50; // RSI Oversold Level +input double RSI_Target_Buy = 71; // RSI Target for Buy Exit +input double RSI_Target_Sell = 70; // RSI Target for Sell Exit +input int BarsToWait = 1; // Bars to wait when RSI goes against position +input double LotSize = 50; // 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; + } +} diff --git a/RSIScalpingMSFT/test-balance.jpg b/RSIScalpingMSFT/test-balance.jpg new file mode 100644 index 0000000..2c8a679 Binary files /dev/null and b/RSIScalpingMSFT/test-balance.jpg differ diff --git a/RSIScalpingTSLA/main.mq5 b/RSIScalpingTSLA/main.mq5 new file mode 100644 index 0000000..8e2d137 --- /dev/null +++ b/RSIScalpingTSLA/main.mq5 @@ -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 + +//--- 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 = 54; // RSI Overbought Level +input double RSI_Oversold = 73; // RSI Oversold Level +input double RSI_Target_Buy = 87; // RSI Target for Buy Exit +input double RSI_Target_Sell = 33; // RSI Target for Sell Exit +input int BarsToWait = 1; // Bars to wait when RSI goes against position +input double LotSize = 50; // 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; + } +} diff --git a/RSIScalpingTSLA/test-balance.jpg b/RSIScalpingTSLA/test-balance.jpg new file mode 100644 index 0000000..6fcfe4d Binary files /dev/null and b/RSIScalpingTSLA/test-balance.jpg differ