Merge pull request #30 from zhutoutoutousan/develop

Update
This commit is contained in:
zhutoutoutousan
2026-04-24 14:14:30 +02:00
committed by GitHub
130 changed files with 10016 additions and 4439 deletions
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

-82
View File
@@ -1,82 +0,0 @@
# MQL5 EA Improvements - Magic Number Isolation
## Problem
When multiple EAs run together on the same symbol, they interfere with each other because magic numbers are not properly checked in all position-related functions.
## Solution
1. Created `MagicNumberHelpers.mqh` with magic-aware helper functions
2. Updated EAs to use these helper functions
3. Created `_united/main.mq5` - a unified EA that runs multiple strategies together
## Fixed Functions
### Helper Functions (MagicNumberHelpers.mqh)
- `PositionSelectByMagic()` - Select position by symbol AND magic number
- `PositionSelectByTicketAndMagic()` - Verify ticket has correct magic number
- `PositionExistsByMagic()` - Check if position exists with magic number
- `GetPositionTicketByMagic()` - Get ticket by symbol and magic number
- `ClosePositionByMagic()` - Close position with magic number verification
- `ModifyPositionByMagic()` - Modify position with magic number verification
- `GetPositionProfitByMagic()` - Get profit with magic number check
- `GetPositionTypeByMagic()` - Get position type with magic number check
- `CountPositionsByMagic()` - Count positions with specific magic number
## Fixed EAs
### RSIScalpingXAUUSD
- ✅ Fixed `CheckExistingPosition()` to use `PositionSelectByTicketAndMagic()`
- ✅ Fixed `ClosePosition()` to verify magic number before closing
- ✅ Fixed entry signal check to use `PositionExistsByMagic()`
### MeanReversionXAUUSD
- ✅ Fixed all `PositionSelect(_Symbol)` calls to use `PositionSelectByMagic()`
- ✅ Fixed `SchließePosition()` to use `ClosePositionByMagic()`
- ✅ Fixed `ÄndereStopLoss()` to use `ModifyPositionByMagic()`
- ✅ Fixed all position existence checks to use `PositionExistsByMagic()`
## United EA
The `_united/main.mq5` EA allows running multiple strategies together:
- Each strategy has its own unique magic number
- Strategies operate independently without interference
- Can enable/disable individual strategies via input parameters
- Currently implements:
- RSI Scalping Strategy
- Mean Reversion Strategy
- Framework for additional strategies (DarvasBox, RSICrossOver, RSIMidPoint)
## Usage
### For Individual EAs
Simply include the helper file:
```mql5
#include "../_united/MagicNumberHelpers.mqh"
```
Then replace:
- `PositionSelect(_Symbol)``PositionSelectByMagic(_Symbol, MagicNumber)`
- `PositionSelectByTicket(ticket)``PositionSelectByTicketAndMagic(ticket, MagicNumber)`
- `trade.PositionClose(_Symbol)``ClosePositionByMagic(trade, _Symbol, MagicNumber)`
- `trade.PositionModify(_Symbol, ...)``ModifyPositionByMagic(trade, _Symbol, MagicNumber, ...)`
### For United EA
1. Set unique magic numbers for each strategy
2. Enable/disable strategies via input parameters
3. Configure strategy-specific parameters
4. Run on chart - all enabled strategies will operate independently
## Remaining EAs to Fix
The following EAs should be updated similarly:
- DarvasBoxXAUUSD
- RSICrossOverReversalXAUUSD
- RSIMidPointHijackXAUUSD
- EMASlopeDistanceCocktailXAUUSD
- All RSIScalping variants (APPL, BTCUSD, MSFT, NVDA, TSLA)
## Best Practices
1. **Always use magic-aware functions** when checking/modifying positions
2. **Set unique magic numbers** for each EA instance
3. **Verify magic number** before any position operation
4. **Use United EA** when running multiple strategies on same symbol
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

@@ -1,346 +0,0 @@
//+------------------------------------------------------------------+
//| DeepMarkovRegimeModel.mqh |
//| Hierarchical latent Markov stack + online regime-conditioned |
//| RSI parameter blending and self-tuning from trade feedback. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property strict
#define DMR_NUM_STATES 4
void DMR_NormalizePi(double &p[])
{
double s = 0.0;
for(int i = 0; i < DMR_NUM_STATES; i++)
s += p[i];
if(s <= 0.0)
{
for(int j = 0; j < DMR_NUM_STATES; j++)
p[j] = 1.0 / DMR_NUM_STATES;
return;
}
for(int k = 0; k < DMR_NUM_STATES; k++)
p[k] /= s;
}
//+------------------------------------------------------------------+
//| Two-level "deep" Markov: macro volatility x micro RSI momentum |
//| Combined state s in {0..3} = macro*2 + micro. |
//| Belief filtered each bar; transitions learned online. |
//+------------------------------------------------------------------+
class CDeepMarkovRegimeModel
{
private:
int m_seed;
double m_learning_trans; // transition matrix EMA
double m_learning_emit; // emission center EMA
double m_learning_param; // per-state param nudge on wins
double m_penalty_param; // nudge on losses
// Forward belief pi(s), row-stochastic T[s_prev][s_next]
double m_pi[DMR_NUM_STATES];
double m_T[DMR_NUM_STATES][DMR_NUM_STATES];
// Gaussian emission centers in feature space (3D): RSI/100, dRSI norm, ATR ratio
double m_center[DMR_NUM_STATES][3];
double m_emit_sigma; // shared diagonal sigma^2 for simplicity
// Per-state RSI strategy parameters (learned offsets around base inputs)
double m_d_overbought[DMR_NUM_STATES];
double m_d_oversold[DMR_NUM_STATES];
double m_d_target_buy[DMR_NUM_STATES];
double m_d_target_sell[DMR_NUM_STATES];
double m_d_bars_scale[DMR_NUM_STATES]; // multiplicative around base BarsToWait
double m_base_overbought;
double m_base_oversold;
double m_base_target_buy;
double m_base_target_sell;
int m_base_bars_wait;
void NormalizePi()
{
DMR_NormalizePi(m_pi);
}
void RowNormalizeT()
{
for(int i = 0; i < DMR_NUM_STATES; i++)
{
double row = 0.0;
for(int j = 0; j < DMR_NUM_STATES; j++)
row += m_T[i][j];
if(row <= 0.0)
{
for(int j = 0; j < DMR_NUM_STATES; j++)
m_T[i][j] = 1.0 / DMR_NUM_STATES;
}
else
{
for(int j = 0; j < DMR_NUM_STATES; j++)
m_T[i][j] /= row;
}
}
}
double FeatureDist2(const double f0, const double f1, const double f2, const int state) const
{
double d0 = f0 - m_center[state][0];
double d1 = f1 - m_center[state][1];
double d2 = f2 - m_center[state][2];
return d0 * d0 + d1 * d1 + d2 * d2;
}
static double Clamp(const double x, const double lo, const double hi)
{
if(x < lo) return lo;
if(x > hi) return hi;
return x;
}
public:
CDeepMarkovRegimeModel()
{
m_seed = 0;
m_learning_trans = 0.05;
m_learning_emit = 0.02;
m_learning_param = 0.03;
m_penalty_param = 0.015;
m_emit_sigma = 0.35;
for(int i = 0; i < DMR_NUM_STATES; i++)
{
m_pi[i] = 1.0 / DMR_NUM_STATES;
for(int j = 0; j < DMR_NUM_STATES; j++)
m_T[i][j] = (i == j) ? 0.55 : 0.15;
m_d_overbought[i] = 0.0;
m_d_oversold[i] = 0.0;
m_d_target_buy[i] = 0.0;
m_d_target_sell[i] = 0.0;
m_d_bars_scale[i] = 1.0;
// Spread default emission prototypes across feature cube corners
m_center[i][0] = ((i & 1) != 0) ? 0.75 : 0.35;
m_center[i][1] = ((i & 2) != 0) ? 0.6 : 0.25;
m_center[i][2] = (double)(i % 3) * 0.25 + 0.2;
}
RowNormalizeT();
}
void SetLearningRates(const double lr_trans, const double lr_emit, const double lr_win, const double lr_loss)
{
m_learning_trans = lr_trans;
m_learning_emit = lr_emit;
m_learning_param = lr_win;
m_penalty_param = lr_loss;
}
void SetBaseThresholds(const double ob, const double os, const double tb, const double ts, const int bars_wait)
{
m_base_overbought = ob;
m_base_oversold = os;
m_base_target_buy = tb;
m_base_target_sell = ts;
m_base_bars_wait = bars_wait;
}
void SetSeed(const int seed) { m_seed = seed; }
// f0: RSI/100, f1: tanh-like scaled delta RSI, f2: ATR short/long ratio capped
void Update(const double f0, const double f1, const double f2)
{
double emit[DMR_NUM_STATES];
double max_ll = -1.0e100;
for(int s = 0; s < DMR_NUM_STATES; s++)
{
double d2 = FeatureDist2(f0, f1, f2, s);
emit[s] = MathExp(-0.5 * d2 / (m_emit_sigma * m_emit_sigma + 1.0e-12));
if(emit[s] > max_ll) max_ll = emit[s];
}
// numerical safety
for(int s2 = 0; s2 < DMR_NUM_STATES; s2++)
if(emit[s2] != emit[s2] || emit[s2] < 1.0e-12)
emit[s2] = 1.0e-12;
double pi_new[DMR_NUM_STATES];
for(int j = 0; j < DMR_NUM_STATES; j++)
{
double sum = 0.0;
for(int i = 0; i < DMR_NUM_STATES; i++)
sum += m_pi[i] * m_T[i][j];
pi_new[j] = sum * emit[j];
}
DMR_NormalizePi(pi_new);
int imax_prev = ArgMaxPi();
int imax_new = 0;
double best = pi_new[0];
for(int j = 1; j < DMR_NUM_STATES; j++)
if(pi_new[j] > best)
{
best = pi_new[j];
imax_new = j;
}
// Online transition nudge toward observed edge imax_prev -> imax_new
for(int j = 0; j < DMR_NUM_STATES; j++)
m_T[imax_prev][j] *= (1.0 - m_learning_trans);
m_T[imax_prev][imax_new] += m_learning_trans;
RowNormalizeT();
// Pull emission center of dominant new state toward observation
for(int d = 0; d < 3; d++)
{
double obs[3] = {f0, f1, f2};
m_center[imax_new][d] = (1.0 - m_learning_emit) * m_center[imax_new][d] + m_learning_emit * obs[d];
}
for(int k = 0; k < DMR_NUM_STATES; k++)
m_pi[k] = pi_new[k];
NormalizePi();
}
int ArgMaxPi() const
{
int idx = 0;
double best = m_pi[0];
for(int i = 1; i < DMR_NUM_STATES; i++)
if(m_pi[i] > best)
{
best = m_pi[i];
idx = i;
}
return idx;
}
double Belief(const int s) const
{
if(s < 0 || s >= DMR_NUM_STATES) return 0.0;
return m_pi[s];
}
// Blended effective thresholds (self-optimized offsets)
double EffectiveOverbought() const
{
double v = 0.0;
for(int s = 0; s < DMR_NUM_STATES; s++)
v += m_pi[s] * (m_base_overbought + m_d_overbought[s]);
return Clamp(v, 50.0, 95.0);
}
double EffectiveOversold() const
{
double v = 0.0;
for(int s = 0; s < DMR_NUM_STATES; s++)
v += m_pi[s] * (m_base_oversold + m_d_oversold[s]);
return Clamp(v, 5.0, 50.0);
}
double EffectiveTargetBuy() const
{
double v = 0.0;
for(int s = 0; s < DMR_NUM_STATES; s++)
v += m_pi[s] * (m_base_target_buy + m_d_target_buy[s]);
return Clamp(v, 55.0, 99.0);
}
double EffectiveTargetSell() const
{
double v = 0.0;
for(int s = 0; s < DMR_NUM_STATES; s++)
v += m_pi[s] * (m_base_target_sell + m_d_target_sell[s]);
return Clamp(v, 1.0, 50.0);
}
int EffectiveBarsToWait() const
{
double acc = 0.0;
for(int s = 0; s < DMR_NUM_STATES; s++)
acc += m_pi[s] * m_d_bars_scale[s];
acc = Clamp(acc, 0.5, 2.0);
int b = (int)MathRound((double)m_base_bars_wait * acc);
return (int)Clamp((double)b, 1.0, 20.0);
}
// Reinforce or soften parameters for the regime active at entry
void OnTradeClosed(const int dominant_state_at_entry, const double profit_money)
{
if(dominant_state_at_entry < 0 || dominant_state_at_entry >= DMR_NUM_STATES)
return;
const int s = dominant_state_at_entry;
const double mag = MathMin(1.0, MathAbs(profit_money) / 100.0 + 0.2);
if(profit_money > 0.0)
{
// Slightly widen capture: push targets outward in favorable direction
m_d_target_buy[s] += m_learning_param * mag * 0.5;
m_d_target_sell[s] -= m_learning_param * mag * 0.5;
m_d_overbought[s] += m_learning_param * mag * 0.25;
m_d_oversold[s] -= m_learning_param * mag * 0.25;
m_d_bars_scale[s] += m_learning_param * 0.05 * mag;
}
else if(profit_money < 0.0)
{
// Tighten: mean-revert offsets toward 0 and shorten patience
m_d_target_buy[s] *= (1.0 - m_penalty_param * mag);
m_d_target_sell[s] *= (1.0 - m_penalty_param * mag);
m_d_overbought[s] *= (1.0 - m_penalty_param * mag);
m_d_oversold[s] *= (1.0 - m_penalty_param * mag);
m_d_bars_scale[s] -= m_penalty_param * 0.05 * mag;
}
for(int i = 0; i < DMR_NUM_STATES; i++)
{
m_d_overbought[i] = Clamp(m_d_overbought[i], -15.0, 15.0);
m_d_oversold[i] = Clamp(m_d_oversold[i], -15.0, 15.0);
m_d_target_buy[i] = Clamp(m_d_target_buy[i], -20.0, 20.0);
m_d_target_sell[i] = Clamp(m_d_target_sell[i], -20.0, 20.0);
m_d_bars_scale[i] = Clamp(m_d_bars_scale[i], 0.5, 2.0);
}
}
string DebugStateLine() const
{
string t = StringFormat("DMR pi=[%.2f,%.2f,%.2f,%.2f] OB=%.1f OS=%.1f TB=%.1f TS=%.1f BW=%d",
m_pi[0], m_pi[1], m_pi[2], m_pi[3],
EffectiveOverbought(), EffectiveOversold(),
EffectiveTargetBuy(), EffectiveTargetSell(),
EffectiveBarsToWait());
return t;
}
bool SaveToGlobals(const string prefix) const
{
string p = prefix + IntegerToString(m_seed) + "_";
GlobalVariableSet(p + "pi0", m_pi[0]);
GlobalVariableSet(p + "pi1", m_pi[1]);
GlobalVariableSet(p + "pi2", m_pi[2]);
GlobalVariableSet(p + "pi3", m_pi[3]);
for(int i = 0; i < DMR_NUM_STATES; i++)
{
GlobalVariableSet(p + "dob" + IntegerToString(i), m_d_overbought[i]);
GlobalVariableSet(p + "dos" + IntegerToString(i), m_d_oversold[i]);
GlobalVariableSet(p + "dtb" + IntegerToString(i), m_d_target_buy[i]);
GlobalVariableSet(p + "dts" + IntegerToString(i), m_d_target_sell[i]);
GlobalVariableSet(p + "dbs" + IntegerToString(i), m_d_bars_scale[i]);
}
return true;
}
bool LoadFromGlobals(const string prefix)
{
string p = prefix + IntegerToString(m_seed) + "_";
if(!GlobalVariableCheck(p + "pi0"))
return false;
m_pi[0] = GlobalVariableGet(p + "pi0");
m_pi[1] = GlobalVariableGet(p + "pi1");
m_pi[2] = GlobalVariableGet(p + "pi2");
m_pi[3] = GlobalVariableGet(p + "pi3");
for(int i = 0; i < DMR_NUM_STATES; i++)
{
m_d_overbought[i] = GlobalVariableGet(p + "dob" + IntegerToString(i));
m_d_oversold[i] = GlobalVariableGet(p + "dos" + IntegerToString(i));
m_d_target_buy[i] = GlobalVariableGet(p + "dtb" + IntegerToString(i));
m_d_target_sell[i] = GlobalVariableGet(p + "dts" + IntegerToString(i));
m_d_bars_scale[i] = GlobalVariableGet(p + "dbs" + IntegerToString(i));
}
NormalizePi();
return true;
}
};
@@ -1,350 +0,0 @@
//+------------------------------------------------------------------+
//| RSIScalpingXAUUSD_DeepMarkov.mq5 |
//| RSI scalping with online deep Markov regime filter + self-tune. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link "https://www.mql5.com"
#property version "1.00"
#include "MagicNumberHelpers.mqh"
#include "DeepMarkovRegimeModel.mqh"
//--- Input parameters
input group "=== Chart / RSI ==="
input ENUM_TIMEFRAMES TimeFrame = PERIOD_H1;
input int RSI_Period = 14;
input ENUM_APPLIED_PRICE RSI_Applied_Price = PRICE_CLOSE;
input group "=== Base RSI levels (Markov blends & learns offsets) ==="
input double RSI_Overbought = 71;
input double RSI_Oversold = 57;
input double RSI_Target_Buy = 80;
input double RSI_Target_Sell = 57;
input int BarsToWait = 4;
input group "=== Execution ==="
input double LotSize = 0.1;
input int MagicNumber = 129102316;
input int Slippage = 3;
input group "=== Deep Markov self-optimization ==="
input double DMR_LearnTransition = 0.05;
input double DMR_LearnEmission = 0.02;
input double DMR_LearnWin = 0.03;
input double DMR_LearnLoss = 0.015;
input bool DMR_PersistGlobals = true;
input string DMR_GlobalPrefix = "DMR_XAU_";
input bool DMR_LogEachBar = false;
//--- Global variables
CTrade trade;
CDeepMarkovRegimeModel g_dm;
int rsi_handle;
int atr_fast_handle;
int atr_slow_handle;
double rsi_buffer[];
double rsi_prev, rsi_current, rsi_two_bars_ago;
double atr_fast, atr_slow;
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;
int entry_regime = 0;
//+------------------------------------------------------------------+
int OnInit()
{
rsi_handle = iRSI(_Symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
if(rsi_handle == INVALID_HANDLE)
return(INIT_FAILED);
atr_fast_handle = iATR(_Symbol, TimeFrame, 8);
atr_slow_handle = iATR(_Symbol, TimeFrame, 34);
if(atr_fast_handle == INVALID_HANDLE || atr_slow_handle == INVALID_HANDLE)
return(INIT_FAILED);
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
ArraySetAsSeries(rsi_buffer, true);
g_dm.SetSeed(MagicNumber);
g_dm.SetLearningRates(DMR_LearnTransition, DMR_LearnEmission, DMR_LearnWin, DMR_LearnLoss);
g_dm.SetBaseThresholds(RSI_Overbought, RSI_Oversold, RSI_Target_Buy, RSI_Target_Sell, BarsToWait);
if(DMR_PersistGlobals)
{
if(g_dm.LoadFromGlobals(DMR_GlobalPrefix))
Print("RSIScalpingXAUUSD_DeepMarkov: loaded persisted Markov state from globals.");
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(DMR_PersistGlobals)
g_dm.SaveToGlobals(DMR_GlobalPrefix);
if(rsi_handle != INVALID_HANDLE)
IndicatorRelease(rsi_handle);
if(atr_fast_handle != INVALID_HANDLE)
IndicatorRelease(atr_fast_handle);
if(atr_slow_handle != INVALID_HANDLE)
IndicatorRelease(atr_slow_handle);
}
//+------------------------------------------------------------------+
void OnTick()
{
if(Bars(_Symbol, TimeFrame) < RSI_Period + 5)
return;
datetime current_bar_time = iTime(_Symbol, TimeFrame, 0);
if(current_bar_time == last_bar_time)
return;
last_bar_time = current_bar_time;
if(!UpdateRSI())
return;
if(!UpdateATR())
return;
const double f0 = rsi_current / 100.0;
const double dr = rsi_current - rsi_prev;
const double f1 = MathTanh(dr / 10.0) * 0.5 + 0.5;
double ratio = 1.0;
if(atr_slow > 1.0e-12)
ratio = atr_fast / atr_slow;
if(ratio < 0.15)
ratio = 0.15;
if(ratio > 2.5)
ratio = 2.5;
const double f2 = ratio / 2.5;
g_dm.Update(f0, f1, f2);
if(DMR_LogEachBar)
Print(g_dm.DebugStateLine());
ResyncPositionFromMarket();
CheckExistingPosition();
if(!position_open && !PositionExistsByMagic(_Symbol, (ulong)MagicNumber))
CheckEntrySignals();
}
//+------------------------------------------------------------------+
bool UpdateRSI()
{
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3)
return false;
rsi_current = rsi_buffer[0];
rsi_prev = rsi_buffer[1];
rsi_two_bars_ago = rsi_buffer[2];
return true;
}
//+------------------------------------------------------------------+
bool UpdateATR()
{
double af[], as[];
ArrayResize(af, 1);
ArrayResize(as, 1);
ArraySetAsSeries(af, true);
ArraySetAsSeries(as, true);
if(CopyBuffer(atr_fast_handle, 0, 0, 1, af) < 1)
return false;
if(CopyBuffer(atr_slow_handle, 0, 0, 1, as) < 1)
return false;
atr_fast = af[0];
atr_slow = as[0];
return true;
}
//+------------------------------------------------------------------+
void ResyncPositionFromMarket()
{
if(position_open)
return;
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
if(t == 0 || !PositionSelectByTicket(t))
return;
position_ticket = (int)t;
position_open = true;
current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
entry_regime = g_dm.ArgMaxPi();
}
//+------------------------------------------------------------------+
double EffectiveOverbought() { return g_dm.EffectiveOverbought(); }
double EffectiveOversold() { return g_dm.EffectiveOversold(); }
double EffectiveTargetBuy() { return g_dm.EffectiveTargetBuy(); }
double EffectiveTargetSell() { return g_dm.EffectiveTargetSell(); }
int EffectiveBarsToWait() { return g_dm.EffectiveBarsToWait(); }
//+------------------------------------------------------------------+
void CheckExistingPosition()
{
if(!position_open)
return;
if(!PositionSelectByTicketAndMagic((ulong)position_ticket, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
const double ob = EffectiveOverbought();
const double os = EffectiveOversold();
const double tb = EffectiveTargetBuy();
const double ts = EffectiveTargetSell();
const int bw = EffectiveBarsToWait();
if(current_position_type == POSITION_TYPE_BUY)
{
if(rsi_current < os)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
bars_against_count++;
if(bars_against_count >= bw)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current >= tb)
ClosePosition();
}
}
else if(current_position_type == POSITION_TYPE_SELL)
{
if(rsi_current > ob)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
bars_against_count++;
if(bars_against_count >= bw)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current <= ts)
ClosePosition();
}
}
}
//+------------------------------------------------------------------+
void CheckEntrySignals()
{
const double os = EffectiveOversold();
const double ob = EffectiveOverbought();
if(rsi_two_bars_ago <= os && rsi_prev > os)
OpenBuyPosition();
if(rsi_two_bars_ago >= ob && rsi_prev < ob)
OpenSellPosition();
}
//+------------------------------------------------------------------+
void OpenBuyPosition()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
entry_regime = g_dm.ArgMaxPi();
if(trade.Buy(LotSize, _Symbol, ask, 0, 0, "RSI DM Buy"))
{
ulong pt = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
position_ticket = (int)pt;
position_open = true;
current_position_type = POSITION_TYPE_BUY;
}
}
//+------------------------------------------------------------------+
void OpenSellPosition()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
entry_regime = g_dm.ArgMaxPi();
if(trade.Sell(LotSize, _Symbol, bid, 0, 0, "RSI DM Sell"))
{
ulong pt = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
position_ticket = (int)pt;
position_open = true;
current_position_type = POSITION_TYPE_SELL;
}
}
//+------------------------------------------------------------------+
void ClosePosition()
{
double profit = 0.0;
if(PositionSelectByTicket(position_ticket))
profit = PositionGetDouble(POSITION_PROFIT);
const int regime = entry_regime;
if(ClosePositionByMagic(trade, _Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
g_dm.OnTradeClosed(regime, profit);
return;
}
if(!PositionExistsByMagic(_Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
g_dm.OnTradeClosed(regime, profit);
return;
}
Print("RSIScalpingXAUUSD_DeepMarkov: close failed (will retry). retcode=",
trade.ResultRetcode(), " lastError=", GetLastError());
}
@@ -1,307 +0,0 @@
//+------------------------------------------------------------------+
//| RSIScalpingXAUUSD_PlusHours.mq5 |
//| Same logic as RSIScalpingXAUUSD + trading session filter |
//| (server time), day-of-week filter, and optional close-all when |
//| outside allowed hours/days |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include "../_united/MagicNumberHelpers.mqh"
input group "=== RSI (same as RSIScalpingXAUUSD) ==="
input ENUM_TIMEFRAMES TimeFrame = PERIOD_H1;
input int RSI_Period = 14;
input ENUM_APPLIED_PRICE RSI_Applied_Price = PRICE_CLOSE;
input double RSI_Overbought = 71;
input double RSI_Oversold = 57;
input double RSI_Target_Buy = 80;
input double RSI_Target_Sell = 57;
input int BarsToWait = 4;
input double LotSize = 0.1;
input int MagicNumber = 129102317;
input int Slippage = 3;
input group "=== Trading hours (broker server time) ==="
input bool InpUseTradingHours = true;
input int InpTradeHourStart = 8;
input int InpTradeHourEnd = 22;
input bool InpCloseOutsideTradingHours = true;
input group "=== Trading days (broker server time) ==="
input bool InpUseTradingDays = true;
input bool InpTradeMonday = true;
input bool InpTradeTuesday = true;
input bool InpTradeWednesday = true;
input bool InpTradeThursday = true;
input bool InpTradeFriday = true;
input bool InpTradeSaturday = true;
input bool InpTradeSunday = true;
input bool InpCloseOutsideTradingDays = true;
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;
bool IsWithinTradingHours()
{
if(!InpUseTradingHours)
return true;
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
const int h = dt.hour;
const int hs = MathMax(0, MathMin(23, InpTradeHourStart));
const int he = MathMax(0, MathMin(23, InpTradeHourEnd));
if(hs == he)
return true;
if(hs < he)
return (h >= hs && h < he);
return (h >= hs || h < he);
}
bool IsTradingDayAllowed()
{
if(!InpUseTradingDays)
return true;
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
switch(dt.day_of_week)
{
case 0: return InpTradeSunday;
case 1: return InpTradeMonday;
case 2: return InpTradeTuesday;
case 3: return InpTradeWednesday;
case 4: return InpTradeThursday;
case 5: return InpTradeFriday;
case 6: return InpTradeSaturday;
}
return false;
}
int OnInit()
{
rsi_handle = iRSI(_Symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
if(rsi_handle == INVALID_HANDLE)
return(INIT_FAILED);
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
ArraySetAsSeries(rsi_buffer, true);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
if(rsi_handle != INVALID_HANDLE)
IndicatorRelease(rsi_handle);
}
void OnTick()
{
if(Bars(_Symbol, TimeFrame) < RSI_Period + 2)
return;
datetime current_bar_time = iTime(_Symbol, TimeFrame, 0);
if(current_bar_time == last_bar_time)
return;
last_bar_time = current_bar_time;
if(!UpdateRSI())
return;
ResyncPositionFromMarket();
const bool inHours = IsWithinTradingHours();
const bool inDays = IsTradingDayAllowed();
const bool inSession = inHours && inDays;
if(position_open && !inSession &&
((InpUseTradingHours && InpCloseOutsideTradingHours && !inHours) ||
(InpUseTradingDays && InpCloseOutsideTradingDays && !inDays)))
{
ClosePosition();
return;
}
CheckExistingPosition();
if(!position_open && !PositionExistsByMagic(_Symbol, (ulong)MagicNumber) && inSession)
CheckEntrySignals();
}
bool UpdateRSI()
{
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3)
return false;
rsi_current = rsi_buffer[0];
rsi_prev = rsi_buffer[1];
rsi_two_bars_ago = rsi_buffer[2];
return true;
}
void ResyncPositionFromMarket()
{
if(position_open)
return;
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
if(t == 0 || !PositionSelectByTicket(t))
return;
position_ticket = (int)t;
position_open = true;
current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
void CheckExistingPosition()
{
if(!position_open)
return;
if(!PositionSelectByTicketAndMagic(position_ticket, MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
if(current_position_type == POSITION_TYPE_BUY)
{
if(rsi_current < RSI_Oversold)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
bars_against_count++;
if(bars_against_count >= BarsToWait)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current >= RSI_Target_Buy)
ClosePosition();
}
}
else if(current_position_type == POSITION_TYPE_SELL)
{
if(rsi_current > RSI_Overbought)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
bars_against_count++;
if(bars_against_count >= BarsToWait)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current <= RSI_Target_Sell)
ClosePosition();
}
}
}
void CheckEntrySignals()
{
if(rsi_two_bars_ago <= RSI_Oversold && rsi_prev > RSI_Oversold)
OpenBuyPosition();
if(rsi_two_bars_ago >= RSI_Overbought && rsi_prev < RSI_Overbought)
OpenSellPosition();
}
void OpenBuyPosition()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
trade.SetExpertMagicNumber(MagicNumber);
if(trade.Buy(LotSize, _Symbol, ask, 0, 0, "RSI Scalping Hours Buy"))
{
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
position_ticket = (int)t;
position_open = (position_ticket != 0);
current_position_type = POSITION_TYPE_BUY;
rsi_against_position = false;
bars_against_count = 0;
}
}
void OpenSellPosition()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
trade.SetExpertMagicNumber(MagicNumber);
if(trade.Sell(LotSize, _Symbol, bid, 0, 0, "RSI Scalping Hours Sell"))
{
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
position_ticket = (int)t;
position_open = (position_ticket != 0);
current_position_type = POSITION_TYPE_SELL;
rsi_against_position = false;
bars_against_count = 0;
}
}
void ClosePosition()
{
if(ClosePositionByMagic(trade, _Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
if(!PositionExistsByMagic(_Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
Print("RSIScalpingXAUUSD_PlusHours: close failed (will retry). retcode=",
trade.ResultRetcode(), " lastError=", GetLastError());
}
@@ -1,367 +0,0 @@
//+------------------------------------------------------------------+
//| RSIScalpingXAUUSD_Trailing.mq5 |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.06"
#include <Trade\Trade.mqh>
#include "../_united/MagicNumberHelpers.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 bool UseRSI_StopLoss = true; // Close on RSI stop (separate timeframe below)
input ENUM_TIMEFRAMES RSI_StopLoss_TimeFrame = PERIOD_H1; // RSI timeframe for stop-loss only
input double RSI_StopLoss_BuyBelow = 30; // Close buy when stop-timeframe RSI drops below this
input double RSI_StopLoss_SellAbove = 70; // Close sell when stop-timeframe RSI rises above this
input double LotSize = 0.1; // Lot Size
input int MagicNumber = 129102316; // Magic Number (distinct from non-trailing EA)
input int Slippage = 3; // Slippage in points
//--- Global variables
CTrade trade;
int rsi_handle;
int rsi_stoploss_handle = INVALID_HANDLE;
double rsi_buffer[];
double rsi_stoploss_buffer[];
double rsi_prev, rsi_current, rsi_two_bars_ago;
double rsi_stoploss_current = 0.0;
MqlTick rsi_stoploss_last_tick;
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()
{
rsi_handle = iRSI(_Symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
if(rsi_handle == INVALID_HANDLE)
{
return(INIT_FAILED);
}
rsi_stoploss_handle = iRSI(_Symbol, RSI_StopLoss_TimeFrame, RSI_Period, RSI_Applied_Price);
if(rsi_stoploss_handle == INVALID_HANDLE)
{
IndicatorRelease(rsi_handle);
return(INIT_FAILED);
}
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
ArraySetAsSeries(rsi_buffer, true);
ArraySetAsSeries(rsi_stoploss_buffer, true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(rsi_handle != INVALID_HANDLE)
IndicatorRelease(rsi_handle);
if(rsi_stoploss_handle != INVALID_HANDLE)
IndicatorRelease(rsi_stoploss_handle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
ResyncPositionFromMarket();
const int min_bars = RSI_Period + 2;
if(position_open)
{
if(UseRSI_StopLoss && Bars(_Symbol, RSI_StopLoss_TimeFrame) >= min_bars)
{
if(UpdateRSI_StopLoss())
CheckRSIStopLossClose();
}
}
if(Bars(_Symbol, TimeFrame) < min_bars)
{
return;
}
datetime current_bar_time = iTime(_Symbol, TimeFrame, 0);
if(current_bar_time == last_bar_time)
{
return;
}
last_bar_time = current_bar_time;
if(!UpdateRSI())
{
return;
}
ResyncPositionFromMarket();
CheckExistingPosition();
if(!position_open && !PositionExistsByMagic(_Symbol, MagicNumber))
{
CheckEntrySignals();
}
}
//+------------------------------------------------------------------+
//| Update RSI values |
//+------------------------------------------------------------------+
bool UpdateRSI()
{
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3)
{
return false;
}
rsi_current = rsi_buffer[0];
rsi_prev = rsi_buffer[1];
rsi_two_bars_ago = rsi_buffer[2];
return true;
}
//+------------------------------------------------------------------+
//| Stop-loss RSI (RSI_StopLoss_TimeFrame) |
//| Uses latest MqlTick before CopyBuffer so RSI matches current quote. |
//+------------------------------------------------------------------+
bool UpdateRSI_StopLoss()
{
if(rsi_stoploss_handle == INVALID_HANDLE)
return false;
if(!SymbolInfoTick(_Symbol, rsi_stoploss_last_tick))
return false;
int calc = BarsCalculated(rsi_stoploss_handle);
if(calc <= 0)
return false;
if(CopyBuffer(rsi_stoploss_handle, 0, 0, 1, rsi_stoploss_buffer) < 1)
return false;
rsi_stoploss_current = rsi_stoploss_buffer[0];
return true;
}
void ResyncPositionFromMarket()
{
if(position_open)
return;
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
if(t == 0 || !PositionSelectByTicket(t))
return;
position_ticket = (int)t;
position_open = true;
current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
//+------------------------------------------------------------------+
//| RSI-based stop: RSI_StopLoss_TimeFrame series (independent of TimeFrame) |
//+------------------------------------------------------------------+
void CheckRSIStopLossClose()
{
if(!UseRSI_StopLoss || !position_open)
return;
if(!PositionSelectByTicketAndMagic(position_ticket, MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
if(current_position_type == POSITION_TYPE_BUY)
{
if(rsi_stoploss_current < RSI_StopLoss_BuyBelow)
ClosePosition();
}
else if(current_position_type == POSITION_TYPE_SELL)
{
if(rsi_stoploss_current > RSI_StopLoss_SellAbove)
ClosePosition();
}
}
//+------------------------------------------------------------------+
//| Check existing position for exit conditions |
//+------------------------------------------------------------------+
void CheckExistingPosition()
{
if(!position_open)
{
return;
}
if(!PositionSelectByTicketAndMagic(position_ticket, MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
if(current_position_type == POSITION_TYPE_BUY)
{
if(rsi_current < RSI_Oversold)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
{
bars_against_count++;
}
if(bars_against_count >= BarsToWait)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current >= RSI_Target_Buy)
{
ClosePosition();
}
}
}
else if(current_position_type == POSITION_TYPE_SELL)
{
if(rsi_current > RSI_Overbought)
{
if(!rsi_against_position)
{
rsi_against_position = true;
bars_against_count = 1;
}
else
{
bars_against_count++;
}
if(bars_against_count >= BarsToWait)
{
ClosePosition();
return;
}
}
else
{
if(rsi_against_position)
{
rsi_against_position = false;
bars_against_count = 0;
}
if(rsi_current <= RSI_Target_Sell)
{
ClosePosition();
}
}
}
}
//+------------------------------------------------------------------+
//| Check for entry signals |
//+------------------------------------------------------------------+
void CheckEntrySignals()
{
if(rsi_two_bars_ago <= RSI_Oversold && rsi_prev > RSI_Oversold)
OpenBuyPosition();
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"))
{
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
if(t != 0)
position_ticket = (int)t;
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"))
{
ulong t = GetPositionTicketByMagic(_Symbol, (ulong)MagicNumber);
if(t != 0)
position_ticket = (int)t;
position_open = true;
current_position_type = POSITION_TYPE_SELL;
}
}
//+------------------------------------------------------------------+
//| Close current position |
//+------------------------------------------------------------------+
void ClosePosition()
{
if(ClosePositionByMagic(trade, _Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
if(!PositionExistsByMagic(_Symbol, (ulong)MagicNumber))
{
position_open = false;
position_ticket = 0;
rsi_against_position = false;
bars_against_count = 0;
return;
}
Print("RSIScalpingXAUUSD: close failed (will retry on next bar). retcode=",
trade.ResultRetcode(), " lastError=", GetLastError());
}
@@ -1,75 +0,0 @@
# Pepperstone US - Symbol Setup Guide
## Finding Correct Symbol Names in MetaTrader 5
### Step-by-Step Instructions:
1. **Open Market Watch Window**
- Press `Ctrl+M` or go to `View > Market Watch`
2. **Show All Symbols**
- Right-click in the Market Watch window
- Select `Show All` or `Symbols`
- This shows all available symbols from your broker
3. **Search for Your Symbols**
- Use the search box in the Market Watch window
- Search for: "AAPL", "MSFT", "NVDA", "TSLA", "BTCUSD", "XAUUSD"
4. **Note the Exact Symbol Name**
- The symbol name shown in Market Watch is what you need to use
- Common formats for Pepperstone US:
- Stocks: `AAPL.US`, `MSFT.US`, `NVDA.US`, `TSLA.US`
- Or: `NASDAQ:AAPL`, `NASDAQ:MSFT`, etc.
- Or: Just `AAPL`, `MSFT`, etc. (if available)
5. **Add to Market Watch**
- Double-click the symbol to add it to your Market Watch
- Or right-click and select `Show`
6. **Update EA Inputs**
- Open the EA inputs in MetaTrader 5
- Update each symbol parameter with the exact name from Market Watch
## Common Pepperstone US Symbol Formats
### US Stocks:
- **Apple**: `AAPL.US` or `NASDAQ:AAPL` or `AAPL`
- **Microsoft**: `MSFT.US` or `NASDAQ:MSFT` or `MSFT`
- **NVIDIA**: `NVDA.US` or `NASDAQ:NVDA` or `NVDA`
- **Tesla**: `TSLA.US` or `NASDAQ:TSLA` or `TSLA`
### Cryptocurrencies:
- **Bitcoin**: `BTCUSD` or `BTC/USD` or `BTCUSD.c`
### Precious Metals:
- **Gold**: `XAUUSD` or `GOLD` or `XAU/USD`
## Important Notes:
1. **Symbol Names are Case-Sensitive**: Use exact capitalization
2. **Add Symbols to Market Watch**: Symbols must be in Market Watch for the EA to access them
3. **Check Trading Hours**: US stocks trade during US market hours (9:30 AM - 4:00 PM ET)
4. **CFD vs Stock**: Pepperstone offers CFDs on stocks, not actual stocks
5. **Spread**: Check the spread for each symbol - some may have wider spreads
## Troubleshooting:
### If Symbol Not Found:
1. Check if you're connected to Pepperstone US server
2. Verify your account type supports the symbol
3. Contact Pepperstone support for symbol availability
4. Check if symbol requires special account permissions
### If EA Shows "Symbol Not Available":
1. Make sure symbol is added to Market Watch
2. Verify symbol name matches exactly (including dots, colons, etc.)
3. Check broker connection status
4. Try different symbol format variations
## Testing Symbols:
You can test if a symbol works by:
1. Opening a chart with that symbol
2. If chart opens successfully, the symbol name is correct
3. Use that exact symbol name in the EA inputs
@@ -1,639 +0,0 @@
//+------------------------------------------------------------------+
//| AdaptiveMonthlyRegime.mqh |
//| Streak unit (input): closed calendar MONTHS or closed DAYS |
//| (server time). Losing streak -> optional CANARY (next full month |
//| or next full day at InpAdaptiveCanaryLotMult). Canary P/L > 0 -> |
//| full size; else HARD PAUSE. CanaryLotMult==0 -> hard pause, no |
//| canary. Per-strat DD lot cap still uses last closed *month* P/L. |
//| Include after all `input` blocks. |
//+------------------------------------------------------------------+
#ifndef ADAPTIVE_MONTHLY_REGIME_MQH
#define ADAPTIVE_MONTHLY_REGIME_MQH
#define UNITED_ADAPTIVE_N 13
#define UNITED_AD_MAX_DAY_BUCKETS 400
#define UNITED_AD_DARVAS 0
#define UNITED_AD_ES 1
#define UNITED_AD_RC 2
#define UNITED_AD_RM 3
#define UNITED_AD_RS_APPL 4
#define UNITED_AD_RS_BTC 5
#define UNITED_AD_RS_NVDA 6
#define UNITED_AD_RS_TSLA 7
#define UNITED_AD_RS_XAU 8
#define UNITED_AD_RRA_EUR 9
#define UNITED_AD_RRA_AUD 10
#define UNITED_AD_RSS 11
#define UNITED_AD_SUPEREMA 12
bool g_adHardPaused[UNITED_ADAPTIVE_N];
bool g_adCanaryWaiting[UNITED_ADAPTIVE_N];
bool g_adCanaryActive[UNITED_ADAPTIVE_N];
datetime g_adCanaryMonthStart[UNITED_ADAPTIVE_N];
datetime g_adCanaryMonthEnd[UNITED_ADAPTIVE_N];
datetime g_adHardPauseUntil[UNITED_ADAPTIVE_N];
datetime g_adPostCanaryCooldownUntil[UNITED_ADAPTIVE_N];
double g_adLastClosedMonthPl[UNITED_ADAPTIVE_N];
datetime g_unitedAdaptiveLastUpdate = 0;
string UnitedAdaptive_StratName(const int s)
{
const string names[] =
{
"DarvasBox", "EMASlope", "RSICrossOver", "RM_MidPoint",
"RS_Scalp_AAPL", "RS_Scalp_BTC", "RS_Scalp_NVDA", "RS_Scalp_TSLA", "RS_Scalp_XAU",
"RRA_EURUSD", "RRA_AUDUSD", "SecretSauce", "SuperEMA"
};
if(s >= 0 && s < UNITED_ADAPTIVE_N)
return names[s];
return "?";
}
void UnitedAdaptive_Init()
{
for(int i = 0; i < UNITED_ADAPTIVE_N; i++)
{
g_adHardPaused[i] = false;
g_adCanaryWaiting[i] = false;
g_adCanaryActive[i] = false;
g_adCanaryMonthStart[i] = 0;
g_adCanaryMonthEnd[i] = 0;
g_adHardPauseUntil[i] = 0;
g_adPostCanaryCooldownUntil[i] = 0;
g_adLastClosedMonthPl[i] = 0.0;
}
g_unitedAdaptiveLastUpdate = 0;
}
datetime UnitedAdaptive_MonthStartInt(const int y, const int m)
{
MqlDateTime d;
d.year = y;
d.mon = m;
d.day = 1;
d.hour = 0;
d.min = 0;
d.sec = 0;
return StructToTime(d);
}
void UnitedAdaptive_NextYm(int &y, int &m)
{
m++;
if(m > 12)
{
m = 1;
y++;
}
}
void UnitedAdaptive_ClosedMonthYm(const int offsetFromLastComplete, int &y, int &m)
{
MqlDateTime now;
TimeToStruct(TimeCurrent(), now);
int ly = now.year;
int lm = now.mon - 1;
if(lm < 1)
{
lm = 12;
ly--;
}
for(int i = 0; i < offsetFromLastComplete; i++)
{
lm--;
if(lm < 1)
{
lm = 12;
ly--;
}
}
y = ly;
m = lm;
}
// Start of calendar day: offset 0 = yesterday 00:00 (last fully closed day), 1 = day before, ...
datetime UnitedAdaptive_ClosedDayStart(const int offsetFromLastCompleteDay)
{
MqlDateTime n;
TimeToStruct(TimeCurrent(), n);
n.hour = 0;
n.min = 0;
n.sec = 0;
const datetime today0 = StructToTime(n);
return today0 - (datetime)((offsetFromLastCompleteDay + 1) * 86400);
}
// Bucket index 0 = yesterday. -1 = today (incomplete) or invalid.
int UnitedAdaptive_ClosedDayOffsetFromDealTime(const datetime dt)
{
MqlDateTime d, n;
TimeToStruct(dt, d);
d.hour = 0;
d.min = 0;
d.sec = 0;
const datetime dealDay0 = StructToTime(d);
TimeToStruct(TimeCurrent(), n);
n.hour = 0;
n.min = 0;
n.sec = 0;
const datetime today0 = StructToTime(n);
const long deltaSec = (long)(today0 - dealDay0);
if(deltaSec < 86400L)
return -1;
const int daysAgo = (int)(deltaSec / 86400L);
return daysAgo - 1;
}
datetime UnitedAdaptive_AddMonthsWallClock(const datetime dt0, const int months)
{
MqlDateTime t;
TimeToStruct(dt0, t);
for(int i = 0; i < months; i++)
{
t.mon++;
if(t.mon > 12)
{
t.mon = 1;
t.year++;
}
}
return StructToTime(t);
}
bool UnitedAdaptive_RMDealMatches(const long mg)
{
if(EnableRSIMidPointHijack)
{
if(RM_InpEnableRSIFollow && mg == (long)RM_InpMagicNumberRSIFollow)
return true;
if(RM_InpEnableRSIReverse && mg == (long)RM_InpMagicNumberRSIReverse)
return true;
if(RM_InpEnableEMACross && mg == (long)RM_InpMagicNumberEMACross)
return true;
}
return false;
}
bool UnitedAdaptive_DealBelongsToStrat(const int s, const long mg)
{
if(s == UNITED_AD_DARVAS)
return EnableDarvasBox && mg == (long)DB_MagicNumber;
if(s == UNITED_AD_ES)
return EnableEMASlopeDistance && mg == (long)ES_MagicNumber;
if(s == UNITED_AD_RC)
return EnableRSICrossOverReversal && mg == (long)RC_MagicNumber;
if(s == UNITED_AD_RM)
return UnitedAdaptive_RMDealMatches(mg);
if(s == UNITED_AD_RS_APPL)
return EnableRSIScalpingAPPL && mg == (long)RS_APPL_MagicNumber;
if(s == UNITED_AD_RS_BTC)
return EnableRSIScalpingBTCUSD && mg == (long)RS_BTCUSD_MagicNumber;
if(s == UNITED_AD_RS_NVDA)
return EnableRSIScalpingNVDA && mg == (long)RS_NVDA_MagicNumber;
if(s == UNITED_AD_RS_TSLA)
return EnableRSIScalpingTSLA && mg == (long)RS_TSLA_MagicNumber;
if(s == UNITED_AD_RS_XAU)
return EnableRSIScalpingXAUUSD && mg == (long)RS_XAUUSD_MagicNumber;
if(s == UNITED_AD_RRA_EUR)
return EnableRSIReversalEURUSD && mg == (long)RRA_EURUSD_MagicNumber;
if(s == UNITED_AD_RRA_AUD)
return EnableRSIReversalAUDUSD && mg == (long)RRA_AUDUSD_MagicNumber;
if(s == UNITED_AD_RSS)
return EnableRSISecretSauceXAUUSD && mg == (long)RSS_XAUUSD_MagicNumber;
if(s == UNITED_AD_SUPEREMA)
return EnableSuperEMA && mg == (long)SE_MagicNumber;
return false;
}
double UnitedAdaptive_SumStratDealsRange(const int s, const datetime from, const datetime to)
{
if(from >= to)
return 0.0;
if(!HistorySelect(from, to))
return 0.0;
double sum = 0.0;
const int n = HistoryDealsTotal();
for(int i = 0; i < n; i++)
{
const ulong t = HistoryDealGetTicket(i);
if(t == 0)
continue;
const long mg = (long)HistoryDealGetInteger(t, DEAL_MAGIC);
if(!UnitedAdaptive_DealBelongsToStrat(s, mg))
continue;
sum += HistoryDealGetDouble(t, DEAL_PROFIT);
sum += HistoryDealGetDouble(t, DEAL_SWAP);
sum += HistoryDealGetDouble(t, DEAL_COMMISSION);
}
return sum;
}
void UnitedAdaptive_StartCanaryWait(const int s)
{
if(InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY)
{
MqlDateTime t;
TimeToStruct(TimeCurrent(), t);
t.hour = 0;
t.min = 0;
t.sec = 0;
const datetime today0 = StructToTime(t);
g_adCanaryMonthStart[s] = today0 + 86400;
g_adCanaryMonthEnd[s] = g_adCanaryMonthStart[s] + 86400;
g_adCanaryWaiting[s] = true;
g_adCanaryActive[s] = false;
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" -> CANARY WAIT until ", TimeToString(g_adCanaryMonthStart[s], TIME_DATE),
" then 1 day at lot x ", DoubleToString(InpAdaptiveCanaryLotMult, 4));
return;
}
MqlDateTime t;
TimeToStruct(TimeCurrent(), t);
t.mon++;
if(t.mon > 12)
{
t.mon = 1;
t.year++;
}
t.day = 1;
t.hour = 0;
t.min = 0;
t.sec = 0;
g_adCanaryMonthStart[s] = StructToTime(t);
int ey = t.year;
int em = t.mon;
UnitedAdaptive_NextYm(ey, em);
g_adCanaryMonthEnd[s] = UnitedAdaptive_MonthStartInt(ey, em);
g_adCanaryWaiting[s] = true;
g_adCanaryActive[s] = false;
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" -> CANARY WAIT until ", TimeToString(g_adCanaryMonthStart[s], TIME_DATE),
" then 1 month at lot x ", DoubleToString(InpAdaptiveCanaryLotMult, 4));
}
void UnitedAdaptive_TryExpireHardPauses()
{
if(InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY)
{
if(InpAdaptiveHardRetryDays <= 0)
return;
}
else if(InpAdaptiveHardRetryMonths <= 0)
return;
const datetime now = TimeCurrent();
for(int s = 0; s < UNITED_ADAPTIVE_N; s++)
{
if(!g_adHardPaused[s])
continue;
if(g_adHardPauseUntil[s] > 0 && now >= g_adHardPauseUntil[s])
{
g_adHardPaused[s] = false;
g_adHardPauseUntil[s] = 0;
if(InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY)
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" hard pause RETRY (after ", InpAdaptiveHardRetryDays, " d)");
else
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" hard pause RETRY (after ", InpAdaptiveHardRetryMonths, " mo)");
}
}
}
void UnitedAdaptive_ProcessCanaryTransitions()
{
if(!InpAdaptiveEnable)
return;
UnitedAdaptive_TryExpireHardPauses();
const datetime now = TimeCurrent();
for(int s = 0; s < UNITED_ADAPTIVE_N; s++)
{
if(g_adCanaryWaiting[s] && !g_adCanaryActive[s] && now >= g_adCanaryMonthStart[s])
{
g_adCanaryWaiting[s] = false;
g_adCanaryActive[s] = true;
if(InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY)
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s), " CANARY ACTIVE (probation day)");
else
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s), " CANARY ACTIVE (probation month)");
}
if(g_adCanaryActive[s] && now >= g_adCanaryMonthEnd[s])
{
const double pl = UnitedAdaptive_SumStratDealsRange(s, g_adCanaryMonthStart[s], g_adCanaryMonthEnd[s]);
g_adCanaryActive[s] = false;
g_adCanaryWaiting[s] = false;
if(pl > 0.0)
{
if(InpAdaptivePostCanaryCooldownDays > 0)
g_adPostCanaryCooldownUntil[s] = TimeCurrent() + InpAdaptivePostCanaryCooldownDays * 86400;
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" canary OK P/L=", DoubleToString(pl, 2), " -> full size");
}
else
{
g_adHardPaused[s] = true;
if(InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY)
{
if(InpAdaptiveHardRetryDays > 0)
g_adHardPauseUntil[s] = now + (datetime)InpAdaptiveHardRetryDays * 86400;
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" canary FAIL P/L=", DoubleToString(pl, 2), " -> HARD PAUSE",
(InpAdaptiveHardRetryDays > 0 ? " (auto-retry later)" : ""));
}
else
{
if(InpAdaptiveHardRetryMonths > 0)
g_adHardPauseUntil[s] = UnitedAdaptive_AddMonthsWallClock(now, InpAdaptiveHardRetryMonths);
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" canary FAIL P/L=", DoubleToString(pl, 2), " -> HARD PAUSE",
(InpAdaptiveHardRetryMonths > 0 ? " (auto-retry later)" : ""));
}
}
}
}
}
bool UnitedAdaptive_StratLastMonthIsLosing(const int s)
{
if(s < 0 || s >= UNITED_ADAPTIVE_N)
return false;
const double thr = MathMax(0.0, InpDdLotCapStratLossThreshold);
return g_adLastClosedMonthPl[s] < -thr;
}
void UnitedAdaptive_RecomputeStreaks()
{
const bool needMonthPlCap = InpDdLotCapEnable && InpDdLotCapPerStratEnable;
const bool adaptMonth = InpAdaptiveEnable && InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_MONTH;
const bool adaptDay = InpAdaptiveEnable && InpAdaptiveStreakUnit == ADAPTIVE_STREAK_BY_DAY;
int nMonthOff = 0;
int streakReqM = 1;
if(adaptMonth)
{
streakReqM = MathMax(1, InpAdaptiveRedStreak);
const int L = MathMax(InpAdaptiveLookbackMonths, streakReqM + 1);
nMonthOff = MathMin(L, 63);
}
else if(needMonthPlCap)
nMonthOff = 2;
int nDayOff = 0;
int streakReqD = 1;
if(adaptDay)
{
streakReqD = MathMax(1, InpAdaptiveRedStreak);
const int L = MathMax(InpAdaptiveLookbackDays, streakReqD + 1);
nDayOff = MathMin(L, UNITED_AD_MAX_DAY_BUCKETS);
}
if(nMonthOff == 0 && nDayOff == 0)
return;
const datetime to = TimeCurrent() + 60;
datetime from = to;
if(nMonthOff > 0)
{
int oy = 0, om = 0;
UnitedAdaptive_ClosedMonthYm(nMonthOff - 1, oy, om);
const datetime mf = UnitedAdaptive_MonthStartInt(oy, om);
if(mf < from)
from = mf;
}
if(nDayOff > 0)
{
const datetime df = UnitedAdaptive_ClosedDayStart(nDayOff - 1);
if(df < from)
from = df;
}
if(from >= to || !HistorySelect(from, to))
return;
double monthBuck[UNITED_ADAPTIVE_N][64];
double dayBuck[UNITED_ADAPTIVE_N][UNITED_AD_MAX_DAY_BUCKETS];
for(int s = 0; s < UNITED_ADAPTIVE_N; s++)
{
for(int o = 0; o < 64; o++)
monthBuck[s][o] = 0.0;
for(int o = 0; o < UNITED_AD_MAX_DAY_BUCKETS; o++)
dayBuck[s][o] = 0.0;
}
const int total = HistoryDealsTotal();
for(int i = 0; i < total; i++)
{
const ulong tk = HistoryDealGetTicket(i);
if(tk == 0)
continue;
const long mg = (long)HistoryDealGetInteger(tk, DEAL_MAGIC);
const datetime dt = (datetime)HistoryDealGetInteger(tk, DEAL_TIME);
const double pl = HistoryDealGetDouble(tk, DEAL_PROFIT)
+ HistoryDealGetDouble(tk, DEAL_SWAP)
+ HistoryDealGetDouble(tk, DEAL_COMMISSION);
if(nMonthOff > 0)
{
for(int o = 0; o < nMonthOff; o++)
{
int y = 0, m = 0;
UnitedAdaptive_ClosedMonthYm(o, y, m);
const datetime ms = UnitedAdaptive_MonthStartInt(y, m);
int ny = y, nm = m;
UnitedAdaptive_NextYm(ny, nm);
const datetime me = UnitedAdaptive_MonthStartInt(ny, nm);
if(dt < ms || dt >= me)
continue;
if(EnableDarvasBox && mg == (long)DB_MagicNumber)
monthBuck[UNITED_AD_DARVAS][o] += pl;
if(EnableEMASlopeDistance && mg == (long)ES_MagicNumber)
monthBuck[UNITED_AD_ES][o] += pl;
if(EnableRSICrossOverReversal && mg == (long)RC_MagicNumber)
monthBuck[UNITED_AD_RC][o] += pl;
if(UnitedAdaptive_RMDealMatches(mg))
monthBuck[UNITED_AD_RM][o] += pl;
if(EnableRSIScalpingAPPL && mg == (long)RS_APPL_MagicNumber)
monthBuck[UNITED_AD_RS_APPL][o] += pl;
if(EnableRSIScalpingBTCUSD && mg == (long)RS_BTCUSD_MagicNumber)
monthBuck[UNITED_AD_RS_BTC][o] += pl;
if(EnableRSIScalpingNVDA && mg == (long)RS_NVDA_MagicNumber)
monthBuck[UNITED_AD_RS_NVDA][o] += pl;
if(EnableRSIScalpingTSLA && mg == (long)RS_TSLA_MagicNumber)
monthBuck[UNITED_AD_RS_TSLA][o] += pl;
if(EnableRSIScalpingXAUUSD && mg == (long)RS_XAUUSD_MagicNumber)
monthBuck[UNITED_AD_RS_XAU][o] += pl;
if(EnableRSIReversalEURUSD && mg == (long)RRA_EURUSD_MagicNumber)
monthBuck[UNITED_AD_RRA_EUR][o] += pl;
if(EnableRSIReversalAUDUSD && mg == (long)RRA_AUDUSD_MagicNumber)
monthBuck[UNITED_AD_RRA_AUD][o] += pl;
if(EnableRSISecretSauceXAUUSD && mg == (long)RSS_XAUUSD_MagicNumber)
monthBuck[UNITED_AD_RSS][o] += pl;
if(EnableSuperEMA && mg == (long)SE_MagicNumber)
monthBuck[UNITED_AD_SUPEREMA][o] += pl;
break;
}
}
if(nDayOff > 0)
{
const int dOff = UnitedAdaptive_ClosedDayOffsetFromDealTime(dt);
if(dOff >= 0 && dOff < nDayOff)
{
if(EnableDarvasBox && mg == (long)DB_MagicNumber)
dayBuck[UNITED_AD_DARVAS][dOff] += pl;
if(EnableEMASlopeDistance && mg == (long)ES_MagicNumber)
dayBuck[UNITED_AD_ES][dOff] += pl;
if(EnableRSICrossOverReversal && mg == (long)RC_MagicNumber)
dayBuck[UNITED_AD_RC][dOff] += pl;
if(UnitedAdaptive_RMDealMatches(mg))
dayBuck[UNITED_AD_RM][dOff] += pl;
if(EnableRSIScalpingAPPL && mg == (long)RS_APPL_MagicNumber)
dayBuck[UNITED_AD_RS_APPL][dOff] += pl;
if(EnableRSIScalpingBTCUSD && mg == (long)RS_BTCUSD_MagicNumber)
dayBuck[UNITED_AD_RS_BTC][dOff] += pl;
if(EnableRSIScalpingNVDA && mg == (long)RS_NVDA_MagicNumber)
dayBuck[UNITED_AD_RS_NVDA][dOff] += pl;
if(EnableRSIScalpingTSLA && mg == (long)RS_TSLA_MagicNumber)
dayBuck[UNITED_AD_RS_TSLA][dOff] += pl;
if(EnableRSIScalpingXAUUSD && mg == (long)RS_XAUUSD_MagicNumber)
dayBuck[UNITED_AD_RS_XAU][dOff] += pl;
if(EnableRSIReversalEURUSD && mg == (long)RRA_EURUSD_MagicNumber)
dayBuck[UNITED_AD_RRA_EUR][dOff] += pl;
if(EnableRSIReversalAUDUSD && mg == (long)RRA_AUDUSD_MagicNumber)
dayBuck[UNITED_AD_RRA_AUD][dOff] += pl;
if(EnableRSISecretSauceXAUUSD && mg == (long)RSS_XAUUSD_MagicNumber)
dayBuck[UNITED_AD_RSS][dOff] += pl;
if(EnableSuperEMA && mg == (long)SE_MagicNumber)
dayBuck[UNITED_AD_SUPEREMA][dOff] += pl;
}
}
}
if(nMonthOff > 0)
{
for(int s = 0; s < UNITED_ADAPTIVE_N; s++)
g_adLastClosedMonthPl[s] = monthBuck[s][0];
}
if(!InpAdaptiveEnable)
return;
const double thr = MathMax(0.0, InpAdaptiveRedThreshold);
const bool useDay = adaptDay;
const int streakReq = useDay ? streakReqD : streakReqM;
const int nOff = useDay ? nDayOff : nMonthOff;
for(int s = 0; s < UNITED_ADAPTIVE_N; s++)
{
if(g_adHardPaused[s])
continue;
if(g_adCanaryActive[s] || g_adCanaryWaiting[s])
{
int consecOk = 0;
for(int o = 0; o < streakReq && o < nOff; o++)
{
const double bpl = useDay ? dayBuck[s][o] : monthBuck[s][o];
if(bpl < -thr)
consecOk++;
else
break;
}
const bool streakBad = (consecOk >= streakReq);
if(!streakBad && g_adCanaryWaiting[s] && !g_adCanaryActive[s])
{
g_adCanaryWaiting[s] = false;
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s), " canary wait CANCELLED (streak cleared)");
}
continue;
}
int consec = 0;
for(int o = 0; o < streakReq && o < nOff; o++)
{
const double bpl = useDay ? dayBuck[s][o] : monthBuck[s][o];
if(bpl < -thr)
consec++;
else
break;
}
const bool streakBad = (consec >= streakReq);
if(!streakBad)
continue;
const bool prevHard = g_adHardPaused[s];
if(InpAdaptiveCanaryLotMult > 0.0)
{
if(!g_adCanaryWaiting[s] && !g_adCanaryActive[s])
{
if(g_adPostCanaryCooldownUntil[s] > TimeCurrent())
continue;
UnitedAdaptive_StartCanaryWait(s);
}
}
else
{
g_adHardPaused[s] = true;
if(!prevHard && useDay && InpAdaptiveHardRetryDays > 0)
g_adHardPauseUntil[s] = TimeCurrent() + (datetime)InpAdaptiveHardRetryDays * 86400;
else if(!prevHard && !useDay && InpAdaptiveHardRetryMonths > 0)
g_adHardPauseUntil[s] = UnitedAdaptive_AddMonthsWallClock(TimeCurrent(), InpAdaptiveHardRetryMonths);
if(!prevHard)
Print("AdaptiveRegime: ", UnitedAdaptive_StratName(s),
" HARD PAUSE (streak, canary disabled)");
}
}
}
void UnitedAdaptive_UpdateIfDue()
{
if(!InpAdaptiveEnable && (!InpDdLotCapEnable || !InpDdLotCapPerStratEnable))
{
UnitedAdaptive_Init();
return;
}
int everySec = 3600;
if(InpAdaptiveEnable)
everySec = MathMin(everySec, MathMax(60, InpAdaptiveUpdateSeconds));
if(InpDdLotCapEnable && InpDdLotCapPerStratEnable)
everySec = MathMin(everySec, MathMax(60, InpDdLotCapUpdateSeconds));
if(g_unitedAdaptiveLastUpdate > 0 && (TimeCurrent() - g_unitedAdaptiveLastUpdate) < everySec)
return;
g_unitedAdaptiveLastUpdate = TimeCurrent();
UnitedAdaptive_RecomputeStreaks();
}
double UnitedAdaptive_GetLotMult(const int stratId)
{
if(stratId < 0 || stratId >= UNITED_ADAPTIVE_N)
return 1.0;
if(!InpAdaptiveEnable)
return 1.0;
if(g_adCanaryActive[stratId])
return MathMax(0.0, InpAdaptiveCanaryLotMult);
return 1.0;
}
bool UnitedAdaptive_StrategyActive(const int stratId)
{
if(stratId < 0 || stratId >= UNITED_ADAPTIVE_N)
return true;
if(!InpAdaptiveEnable)
return true;
if(g_adHardPaused[stratId])
return false;
if(g_adCanaryWaiting[stratId] && !g_adCanaryActive[stratId])
return false;
return true;
}
#endif
@@ -1,75 +0,0 @@
# Pepperstone US - Symbol Setup Guide
## Finding Correct Symbol Names in MetaTrader 5
### Step-by-Step Instructions:
1. **Open Market Watch Window**
- Press `Ctrl+M` or go to `View > Market Watch`
2. **Show All Symbols**
- Right-click in the Market Watch window
- Select `Show All` or `Symbols`
- This shows all available symbols from your broker
3. **Search for Your Symbols**
- Use the search box in the Market Watch window
- Search for: "AAPL", "MSFT", "NVDA", "TSLA", "BTCUSD", "XAUUSD"
4. **Note the Exact Symbol Name**
- The symbol name shown in Market Watch is what you need to use
- Common formats for Pepperstone US:
- Stocks: `AAPL.US`, `MSFT.US`, `NVDA.US`, `TSLA.US`
- Or: `NASDAQ:AAPL`, `NASDAQ:MSFT`, etc.
- Or: Just `AAPL`, `MSFT`, etc. (if available)
5. **Add to Market Watch**
- Double-click the symbol to add it to your Market Watch
- Or right-click and select `Show`
6. **Update EA Inputs**
- Open the EA inputs in MetaTrader 5
- Update each symbol parameter with the exact name from Market Watch
## Common Pepperstone US Symbol Formats
### US Stocks:
- **Apple**: `AAPL.US` or `NASDAQ:AAPL` or `AAPL`
- **Microsoft**: `MSFT.US` or `NASDAQ:MSFT` or `MSFT`
- **NVIDIA**: `NVDA.US` or `NASDAQ:NVDA` or `NVDA`
- **Tesla**: `TSLA.US` or `NASDAQ:TSLA` or `TSLA`
### Cryptocurrencies:
- **Bitcoin**: `BTCUSD` or `BTC/USD` or `BTCUSD.c`
### Precious Metals:
- **Gold**: `XAUUSD` or `GOLD` or `XAU/USD`
## Important Notes:
1. **Symbol Names are Case-Sensitive**: Use exact capitalization
2. **Add Symbols to Market Watch**: Symbols must be in Market Watch for the EA to access them
3. **Check Trading Hours**: US stocks trade during US market hours (9:30 AM - 4:00 PM ET)
4. **CFD vs Stock**: Pepperstone offers CFDs on stocks, not actual stocks
5. **Spread**: Check the spread for each symbol - some may have wider spreads
## Troubleshooting:
### If Symbol Not Found:
1. Check if you're connected to Pepperstone US server
2. Verify your account type supports the symbol
3. Contact Pepperstone support for symbol availability
4. Check if symbol requires special account permissions
### If EA Shows "Symbol Not Available":
1. Make sure symbol is added to Market Watch
2. Verify symbol name matches exactly (including dots, colons, etc.)
3. Check broker connection status
4. Try different symbol format variations
## Testing Symbols:
You can test if a symbol works by:
1. Opening a chart with that symbol
2. If chart opens successfully, the symbol name is correct
3. Use that exact symbol name in the EA inputs
@@ -1,438 +0,0 @@
//+------------------------------------------------------------------+
//| RSISecretSauceStrategy.mqh |
//| RSI Secret Sauce: leave 70/30 zone, re-enter, peak/bottom entry |
//+------------------------------------------------------------------+
struct RSISecretSauceData
{
string symbol;
bool isInitialized;
CTrade trade;
CPositionInfo positionInfo;
int rsiHandle;
int atrHandle;
double rsiBuffer[];
double atrBuffer[];
double highBuffer[];
double lowBuffer[];
bool rsiWasOverbought;
bool rsiWasOversold;
bool rsiBackInRange;
datetime lastRSIExitTime;
datetime lastRSIReentryTime;
datetime lastTradeTime;
datetime lastBarTime;
ENUM_TIMEFRAMES timeframe;
int rsiPeriod;
double rsiOverbought;
double rsiOversold;
int rsiLookback;
int peakBars;
bool requireDivergence;
double stopLossATR;
double takeProfitATR;
int atrPeriod;
bool useSwingStopLoss;
int swingLookback;
int maxPositions;
int minBarsBetweenTrades;
int magicNumber;
int slippage;
};
bool RSS_UpdateIndicators(RSISecretSauceData& d);
void RSS_UpdateRSIState(RSISecretSauceData& d);
bool RSS_CanOpenNewPosition(RSISecretSauceData& d);
void RSS_CheckEntrySignals(RSISecretSauceData& d, const double lotSize);
bool RSS_IsRSIPeak(RSISecretSauceData& d);
bool RSS_IsRSIBottom(RSISecretSauceData& d);
void RSS_OpenPosition(RSISecretSauceData& d, ENUM_POSITION_TYPE type, const double lotSize);
bool RSS_CalculateStops(RSISecretSauceData& d, double price, ENUM_POSITION_TYPE type, double& sl, double& tp);
double RSS_GetSwingStopLoss(RSISecretSauceData& d, ENUM_POSITION_TYPE type);
bool InitRSISecretSauce(RSISecretSauceData& d,
const string symbol,
const ENUM_TIMEFRAMES timeframe,
const int rsiPeriod,
const double rsiOverbought,
const double rsiOversold,
const int rsiLookback,
const int peakBars,
const bool requireDivergence,
const double stopLossATR,
const double takeProfitATR,
const int atrPeriod,
const bool useSwingStopLoss,
const int swingLookback,
const int maxPositions,
const int minBarsBetweenTrades,
const int magicNumber,
const int slippage)
{
d.symbol = symbol;
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.isInitialized = false;
d.rsiHandle = INVALID_HANDLE;
d.atrHandle = INVALID_HANDLE;
d.rsiWasOverbought = false;
d.rsiWasOversold = false;
d.rsiBackInRange = false;
d.lastRSIExitTime = 0;
d.lastRSIReentryTime = 0;
d.lastTradeTime = 0;
d.lastBarTime = 0;
if(!SymbolSelect(d.symbol, true))
{
Print("RSISecretSauce: Symbol '", d.symbol, "' not available in Market Watch.");
return false;
}
d.timeframe = timeframe;
d.rsiPeriod = rsiPeriod;
d.rsiOverbought = rsiOverbought;
d.rsiOversold = rsiOversold;
d.rsiLookback = rsiLookback;
d.peakBars = peakBars;
d.requireDivergence = requireDivergence;
d.stopLossATR = stopLossATR;
d.takeProfitATR = takeProfitATR;
d.atrPeriod = atrPeriod;
d.useSwingStopLoss = useSwingStopLoss;
d.swingLookback = swingLookback;
d.maxPositions = maxPositions;
d.minBarsBetweenTrades = minBarsBetweenTrades;
d.magicNumber = magicNumber;
d.slippage = slippage;
Sleep(100);
int retry = 0;
while(retry < 5 && d.rsiHandle == INVALID_HANDLE)
{
d.rsiHandle = iRSI(d.symbol, d.timeframe, d.rsiPeriod, PRICE_CLOSE);
if(d.rsiHandle == INVALID_HANDLE)
{
if(GetLastError() == 4805 && retry < 4)
{
Sleep(1000);
retry++;
continue;
}
Print("RSISecretSauce: Failed to create RSI for '", d.symbol, "'");
return false;
}
}
retry = 0;
while(retry < 5 && d.atrHandle == INVALID_HANDLE)
{
d.atrHandle = iATR(d.symbol, d.timeframe, d.atrPeriod);
if(d.atrHandle == INVALID_HANDLE)
{
if(GetLastError() == 4805 && retry < 4)
{
Sleep(1000);
retry++;
continue;
}
Print("RSISecretSauce: Failed to create ATR for '", d.symbol, "'");
IndicatorRelease(d.rsiHandle);
d.rsiHandle = INVALID_HANDLE;
return false;
}
}
ArraySetAsSeries(d.rsiBuffer, true);
ArraySetAsSeries(d.atrBuffer, true);
ArraySetAsSeries(d.highBuffer, true);
ArraySetAsSeries(d.lowBuffer, true);
d.trade.SetExpertMagicNumber(d.magicNumber);
d.trade.SetDeviationInPoints(d.slippage);
d.trade.SetTypeFilling(ORDER_FILLING_FOK);
d.isInitialized = true;
Print("RSISecretSauce: Initialized for '", d.symbol, "' TF=", EnumToString(d.timeframe));
return true;
}
void DeinitRSISecretSauce(RSISecretSauceData& d)
{
if(d.rsiHandle != INVALID_HANDLE)
IndicatorRelease(d.rsiHandle);
if(d.atrHandle != INVALID_HANDLE)
IndicatorRelease(d.atrHandle);
d.rsiHandle = INVALID_HANDLE;
d.atrHandle = INVALID_HANDLE;
d.isInitialized = false;
}
bool RSS_UpdateIndicators(RSISecretSauceData& d)
{
int rsiBarsNeeded = d.rsiLookback + 5;
if(CopyBuffer(d.rsiHandle, 0, 0, rsiBarsNeeded, d.rsiBuffer) < rsiBarsNeeded)
return false;
if(CopyBuffer(d.atrHandle, 0, 0, 2, d.atrBuffer) < 2)
return false;
if(CopyHigh(d.symbol, d.timeframe, 0, d.swingLookback + 5, d.highBuffer) < d.swingLookback + 5)
return false;
if(CopyLow(d.symbol, d.timeframe, 0, d.swingLookback + 5, d.lowBuffer) < d.swingLookback + 5)
return false;
return true;
}
void RSS_UpdateRSIState(RSISecretSauceData& d)
{
double rsiCurrent = d.rsiBuffer[0];
double rsiPrev = d.rsiBuffer[1];
if(rsiPrev >= d.rsiOverbought && rsiCurrent < d.rsiOverbought)
{
d.rsiWasOverbought = true;
d.rsiBackInRange = true;
d.lastRSIExitTime = TimeCurrent();
d.lastRSIReentryTime = TimeCurrent();
}
if(rsiPrev <= d.rsiOversold && rsiCurrent > d.rsiOversold)
{
d.rsiWasOversold = true;
d.rsiBackInRange = true;
d.lastRSIExitTime = TimeCurrent();
d.lastRSIReentryTime = TimeCurrent();
}
if(rsiCurrent >= d.rsiOverbought)
{
d.rsiWasOverbought = false;
d.rsiBackInRange = false;
}
if(rsiCurrent <= d.rsiOversold)
{
d.rsiWasOversold = false;
d.rsiBackInRange = false;
}
}
bool RSS_CanOpenNewPosition(RSISecretSauceData& d)
{
int positionCount = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(d.positionInfo.SelectByIndex(i))
{
if(d.positionInfo.Symbol() == d.symbol && d.positionInfo.Magic() == d.magicNumber)
positionCount++;
}
}
if(positionCount >= d.maxPositions)
return false;
if(d.lastTradeTime > 0)
{
int barsSince = Bars(d.symbol, d.timeframe, d.lastTradeTime, TimeCurrent());
if(barsSince < d.minBarsBetweenTrades)
return false;
}
return true;
}
bool RSS_IsRSIPeak(RSISecretSauceData& d)
{
if(ArraySize(d.rsiBuffer) < d.peakBars + 2)
return false;
double currentRSI = d.rsiBuffer[0];
bool isPeak = true;
for(int i = 1; i <= d.peakBars; i++)
{
if(d.rsiBuffer[i] >= currentRSI)
{
isPeak = false;
break;
}
}
if(d.rsiBuffer[1] >= currentRSI)
isPeak = false;
return isPeak;
}
bool RSS_IsRSIBottom(RSISecretSauceData& d)
{
if(ArraySize(d.rsiBuffer) < d.peakBars + 2)
return false;
double currentRSI = d.rsiBuffer[0];
bool isBottom = true;
for(int i = 1; i <= d.peakBars; i++)
{
if(d.rsiBuffer[i] <= currentRSI)
{
isBottom = false;
break;
}
}
if(d.rsiBuffer[1] <= currentRSI)
isBottom = false;
return isBottom;
}
void RSS_CheckEntrySignals(RSISecretSauceData& d, const double lotSize)
{
if(d.rsiWasOverbought && d.rsiBackInRange)
{
if(d.rsiBuffer[0] < d.rsiOverbought)
{
if(RSS_IsRSIPeak(d))
RSS_OpenPosition(d, POSITION_TYPE_BUY, lotSize);
}
}
if(d.rsiWasOversold && d.rsiBackInRange)
{
if(d.rsiBuffer[0] > d.rsiOversold)
{
if(RSS_IsRSIBottom(d))
RSS_OpenPosition(d, POSITION_TYPE_SELL, lotSize);
}
}
}
bool RSS_CalculateStops(RSISecretSauceData& d, double price, ENUM_POSITION_TYPE type, double& sl, double& tp)
{
double atrValue = d.atrBuffer[0];
if(atrValue <= 0)
atrValue = price * 0.01;
double slDistance = atrValue * d.stopLossATR;
double tpDistance = atrValue * d.takeProfitATR;
int digits = (int)SymbolInfoInteger(d.symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(d.symbol, SYMBOL_POINT);
int stopsLevel = (int)SymbolInfoInteger(d.symbol, SYMBOL_TRADE_STOPS_LEVEL);
double minStopDistance = MathMax(stopsLevel * point, point * 10);
if(d.useSwingStopLoss)
{
double swingStop = RSS_GetSwingStopLoss(d, type);
if(swingStop > 0)
{
if(type == POSITION_TYPE_BUY)
{
if(swingStop < price && (price - swingStop) > minStopDistance)
slDistance = price - swingStop;
}
else
{
if(swingStop > price && (swingStop - price) > minStopDistance)
slDistance = swingStop - price;
}
}
}
if(slDistance < minStopDistance)
slDistance = minStopDistance;
if(tpDistance < minStopDistance)
tpDistance = minStopDistance;
if(type == POSITION_TYPE_BUY)
{
sl = NormalizeDouble(price - slDistance, digits);
tp = NormalizeDouble(price + tpDistance, digits);
}
else
{
sl = NormalizeDouble(price + slDistance, digits);
tp = NormalizeDouble(price - tpDistance, digits);
}
return true;
}
double RSS_GetSwingStopLoss(RSISecretSauceData& d, ENUM_POSITION_TYPE type)
{
if(type == POSITION_TYPE_BUY)
{
double lowestLow = d.lowBuffer[0];
for(int i = 1; i < d.swingLookback && i < ArraySize(d.lowBuffer); i++)
{
if(d.lowBuffer[i] < lowestLow)
lowestLow = d.lowBuffer[i];
}
return lowestLow;
}
double highestHigh = d.highBuffer[0];
for(int i = 1; i < d.swingLookback && i < ArraySize(d.highBuffer); i++)
{
if(d.highBuffer[i] > highestHigh)
highestHigh = d.highBuffer[i];
}
return highestHigh;
}
void RSS_OpenPosition(RSISecretSauceData& d, ENUM_POSITION_TYPE type, const double lotSize)
{
double price = (type == POSITION_TYPE_BUY) ?
SymbolInfoDouble(d.symbol, SYMBOL_ASK) :
SymbolInfoDouble(d.symbol, SYMBOL_BID);
if(price <= 0)
return;
double sl = 0.0, tp = 0.0;
if(!RSS_CalculateStops(d, price, type, sl, tp))
return;
string comment = "RSI_Secret_" + (type == POSITION_TYPE_BUY ? "LONG" : "SHORT");
bool result = false;
if(type == POSITION_TYPE_BUY)
result = d.trade.Buy(lotSize, d.symbol, 0, sl, tp, comment);
else
result = d.trade.Sell(lotSize, d.symbol, 0, sl, tp, comment);
if(result)
{
d.lastTradeTime = TimeCurrent();
if(type == POSITION_TYPE_BUY)
d.rsiWasOverbought = false;
else
d.rsiWasOversold = false;
d.rsiBackInRange = false;
}
}
void ProcessRSISecretSauce(RSISecretSauceData& d, const double lotSize)
{
if(!d.isInitialized)
return;
int requiredBars = MathMax(d.rsiLookback, d.swingLookback) + 10;
if(Bars(d.symbol, d.timeframe) < requiredBars)
return;
datetime currentBarTime = iTime(d.symbol, d.timeframe, 0);
if(currentBarTime == d.lastBarTime)
return;
d.lastBarTime = currentBarTime;
if(!RSS_UpdateIndicators(d))
return;
RSS_UpdateRSIState(d);
if(RSS_CanOpenNewPosition(d))
RSS_CheckEntrySignals(d, lotSize);
}
@@ -1,437 +0,0 @@
//+------------------------------------------------------------------+
//| UnitedProfitPanel.mqh — chart object P&L by strategy / magic |
//| One OBJ_LABEL per line (MT5 often ignores \n in a single label). |
//| Include only after all United EA `input` declarations. |
//+------------------------------------------------------------------+
#ifndef UNITED_PROFIT_PANEL_MQH
#define UNITED_PROFIT_PANEL_MQH
#define UNITED_PNL_MAX_LINES 48
struct UnitedPnLRow
{
string name;
long magic;
};
UnitedPnLRow g_unitedPnLRows[];
int g_unitedPnLRowCount = 0;
int g_unitedPnL_visibleLineCount = 0;
string UnitedPnL_Obj(const string suffix) { return "UnitedPnL_" + suffix; }
long UnitedPnL_ChartId() { return ChartID(); }
string UnitedPnL_LineObjName(const int idx) { return UnitedPnL_Obj("L") + IntegerToString(idx); }
datetime UnitedPnL_StartOfYear(const datetime now)
{
MqlDateTime dt;
TimeToStruct(now, dt);
dt.mon = 1;
dt.day = 1;
dt.hour = 0;
dt.min = 0;
dt.sec = 0;
return StructToTime(dt);
}
datetime UnitedPnL_StartOfMonth(const datetime now)
{
MqlDateTime dt;
TimeToStruct(now, dt);
dt.day = 1;
dt.hour = 0;
dt.min = 0;
dt.sec = 0;
return StructToTime(dt);
}
int UnitedPnL_FindRowIndex(const long magic)
{
for(int r = 0; r < g_unitedPnLRowCount; r++)
{
if(g_unitedPnLRows[r].magic == magic)
return r;
}
return -1;
}
bool UnitedPnL_ScanDealsOnce(double &yearPl[], double &monthPl[], const datetime y0, const datetime m0, const datetime now)
{
const int R = g_unitedPnLRowCount;
ArrayResize(yearPl, R);
ArrayResize(monthPl, R);
for(int j = 0; j < R; j++)
{
yearPl[j] = 0.0;
monthPl[j] = 0.0;
}
if(R <= 0 || y0 >= now)
return true;
datetime to = now;
if(to <= y0)
to = y0 + 1;
if(!HistorySelect(y0, to))
return false;
const int n = HistoryDealsTotal();
for(int i = 0; i < n; i++)
{
const ulong dealTicket = HistoryDealGetTicket(i);
if(dealTicket == 0)
continue;
const long mg = (long)HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
const int idx = UnitedPnL_FindRowIndex(mg);
if(idx < 0)
continue;
const datetime dt = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME);
const double p = HistoryDealGetDouble(dealTicket, DEAL_PROFIT)
+ HistoryDealGetDouble(dealTicket, DEAL_SWAP)
+ HistoryDealGetDouble(dealTicket, DEAL_COMMISSION);
yearPl[idx] += p;
if(dt >= m0)
monthPl[idx] += p;
}
return true;
}
double UnitedPnL_SumFloatingForMagic(const long magic)
{
double sum = 0.0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
const ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
if(!PositionSelectByTicket(ticket))
continue;
if((long)PositionGetInteger(POSITION_MAGIC) != magic)
continue;
sum += PositionGetDouble(POSITION_PROFIT);
sum += PositionGetDouble(POSITION_SWAP);
}
return sum;
}
void UnitedPnL_CollectRows()
{
g_unitedPnLRowCount = 0;
ArrayResize(g_unitedPnLRows, 24);
if(EnableDarvasBox)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "DarvasBox";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)DB_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableEMASlopeDistance)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "EMASlope";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)ES_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSICrossOverReversal)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RSICrossOver";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RC_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIMidPointHijack)
{
if(RM_InpEnableRSIFollow)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RM_RSIFollow";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RM_InpMagicNumberRSIFollow;
g_unitedPnLRowCount++;
}
if(RM_InpEnableRSIReverse)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RM_RSIRev";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RM_InpMagicNumberRSIReverse;
g_unitedPnLRowCount++;
}
if(RM_InpEnableEMACross)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RM_EMACross";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RM_InpMagicNumberEMACross;
g_unitedPnLRowCount++;
}
}
if(EnableRSIScalpingAPPL)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RS_Scalp_AAPL";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RS_APPL_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIScalpingBTCUSD)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RS_Scalp_BTC";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RS_BTCUSD_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIScalpingNVDA)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RS_Scalp_NVDA";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RS_NVDA_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIScalpingTSLA)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RS_Scalp_TSLA";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RS_TSLA_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIScalpingXAUUSD)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RS_Scalp_XAU";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RS_XAUUSD_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIReversalEURUSD)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RRA_EURUSD";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RRA_EURUSD_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSIReversalAUDUSD)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "RRA_AUDUSD";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RRA_AUDUSD_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableRSISecretSauceXAUUSD)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "SecretSauce";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)RSS_XAUUSD_MagicNumber;
g_unitedPnLRowCount++;
}
if(EnableSuperEMA)
{
g_unitedPnLRows[g_unitedPnLRowCount].name = "SuperEMA";
g_unitedPnLRows[g_unitedPnLRowCount].magic = (long)SE_MagicNumber;
g_unitedPnLRowCount++;
}
ArrayResize(g_unitedPnLRows, MathMax(g_unitedPnLRowCount, 1));
}
void UnitedPnL_EnsureObjects()
{
const long ch = UnitedPnL_ChartId();
const string bg = UnitedPnL_Obj("BG");
if(ObjectFind(ch, bg) < 0)
{
if(!ObjectCreate(ch, bg, OBJ_RECTANGLE_LABEL, 0, 0, 0))
{
Print("UnitedPnL: BG ObjectCreate failed, err=", GetLastError());
return;
}
ObjectSetInteger(ch, bg, OBJPROP_BORDER_TYPE, BORDER_FLAT);
ObjectSetInteger(ch, bg, OBJPROP_COLOR, C'90,90,90');
ObjectSetInteger(ch, bg, OBJPROP_BGCOLOR, C'25,25,30');
ObjectSetInteger(ch, bg, OBJPROP_WIDTH, 1);
ObjectSetInteger(ch, bg, OBJPROP_BACK, false);
ObjectSetInteger(ch, bg, OBJPROP_SELECTABLE, false);
ObjectSetInteger(ch, bg, OBJPROP_HIDDEN, false);
ObjectSetInteger(ch, bg, OBJPROP_ZORDER, 0);
}
for(int i = 0; i < UNITED_PNL_MAX_LINES; i++)
{
const string nm = UnitedPnL_LineObjName(i);
if(ObjectFind(ch, nm) >= 0)
continue;
if(!ObjectCreate(ch, nm, OBJ_LABEL, 0, 0, 0))
{
Print("UnitedPnL: line ", i, " ObjectCreate failed, err=", GetLastError());
continue;
}
ObjectSetString(ch, nm, OBJPROP_FONT, "Arial");
ObjectSetInteger(ch, nm, OBJPROP_FONTSIZE, UnitedPanel_FontSize);
ObjectSetInteger(ch, nm, OBJPROP_BACK, false);
ObjectSetInteger(ch, nm, OBJPROP_SELECTABLE, false);
ObjectSetInteger(ch, nm, OBJPROP_HIDDEN, false);
ObjectSetInteger(ch, nm, OBJPROP_ZORDER, 2);
}
}
void UnitedPnL_ApplyGeometry()
{
if(!UnitedPanel_Enable)
return;
const long ch = UnitedPnL_ChartId();
const string bg = UnitedPnL_Obj("BG");
if(ObjectFind(ch, bg) < 0)
return;
const int lineH = UnitedPanel_FontSize + 5;
const int vis = MathMax(g_unitedPnL_visibleLineCount, 6);
const int h = UnitedPanel_YMargin * 2 + lineH * vis;
const ENUM_BASE_CORNER corner = (ENUM_BASE_CORNER)UnitedPanel_Corner;
ObjectSetInteger(ch, bg, OBJPROP_CORNER, corner);
ObjectSetInteger(ch, bg, OBJPROP_XDISTANCE, UnitedPanel_X);
ObjectSetInteger(ch, bg, OBJPROP_YDISTANCE, UnitedPanel_Y);
ObjectSetInteger(ch, bg, OBJPROP_XSIZE, UnitedPanel_Width);
ObjectSetInteger(ch, bg, OBJPROP_YSIZE, MathMax(h, 80));
const int baseX = UnitedPanel_X + UnitedPanel_XMargin;
const int baseY = UnitedPanel_Y + UnitedPanel_YMargin;
for(int i = 0; i < UNITED_PNL_MAX_LINES; i++)
{
const string nm = UnitedPnL_LineObjName(i);
if(ObjectFind(ch, nm) < 0)
continue;
ObjectSetInteger(ch, nm, OBJPROP_CORNER, corner);
ObjectSetInteger(ch, nm, OBJPROP_XDISTANCE, baseX);
ObjectSetInteger(ch, nm, OBJPROP_YDISTANCE, baseY + i * lineH);
ObjectSetInteger(ch, nm, OBJPROP_FONTSIZE, UnitedPanel_FontSize);
}
}
void UnitedPnL_RefreshText()
{
const long ch = UnitedPnL_ChartId();
const string bg = UnitedPnL_Obj("BG");
if(ObjectFind(ch, bg) < 0)
return;
UnitedPnL_CollectRows();
const datetime now = TimeCurrent();
const datetime y0 = UnitedPnL_StartOfYear(now);
const datetime m0 = UnitedPnL_StartOfMonth(now);
const string cur = AccountInfoString(ACCOUNT_CURRENCY);
double yearPl[];
double monthPl[];
const bool histOk = UnitedPnL_ScanDealsOnce(yearPl, monthPl, y0, m0, now);
const string histNote = histOk ? "" : " [hist fail: Toolbox>History]";
double sumY = 0.0, sumM = 0.0, sumF = 0.0;
string lines[];
int n = 0;
ArrayResize(lines, UNITED_PNL_MAX_LINES);
lines[n++] = "United EA " + cur + histNote;
lines[n++] = UnitedPanel_ShowFloating
? "Y/M = closed deals | F = open P/L+swap"
: "Y/M = closed deal P/L+swap+comm";
lines[n++] = "----------------------------------";
for(int r = 0; r < g_unitedPnLRowCount; r++)
{
const long mg = g_unitedPnLRows[r].magic;
double yv = 0.0, mv = 0.0;
if(histOk && r < ArraySize(yearPl))
yv = yearPl[r];
if(histOk && r < ArraySize(monthPl))
mv = monthPl[r];
const double fv = UnitedPanel_ShowFloating ? UnitedPnL_SumFloatingForMagic(mg) : 0.0;
sumY += yv;
sumM += mv;
sumF += fv;
}
string tot = "TOTAL Y:" + DoubleToString(sumY, 2) + " M:" + DoubleToString(sumM, 2);
if(UnitedPanel_ShowFloating)
tot += " F:" + DoubleToString(sumF, 2);
lines[n++] = tot;
lines[n++] = "----------------------------------";
if(g_unitedPnLRowCount == 0)
lines[n++] = "(no strategies enabled)";
else
{
for(int r = 0; r < g_unitedPnLRowCount; r++)
{
if(n >= UNITED_PNL_MAX_LINES - 1)
break;
const long mg = g_unitedPnLRows[r].magic;
double yv = 0.0, mv = 0.0;
if(histOk && r < ArraySize(yearPl))
yv = yearPl[r];
if(histOk && r < ArraySize(monthPl))
mv = monthPl[r];
const double fv = UnitedPanel_ShowFloating ? UnitedPnL_SumFloatingForMagic(mg) : 0.0;
lines[n++] = g_unitedPnLRows[r].name + " [" + IntegerToString((int)mg) + "]";
string row2 = " Y:" + DoubleToString(yv, 2) + " M:" + DoubleToString(mv, 2);
if(UnitedPanel_ShowFloating)
row2 += " F:" + DoubleToString(fv, 2);
lines[n++] = row2;
}
}
g_unitedPnL_visibleLineCount = n;
color c = clrSilver;
if(sumM > 0.0001)
c = clrPaleGreen;
else if(sumM < -0.0001)
c = clrTomato;
for(int i = 0; i < UNITED_PNL_MAX_LINES; i++)
{
const string nm = UnitedPnL_LineObjName(i);
if(ObjectFind(ch, nm) < 0)
continue;
if(i < n)
{
ObjectSetString(ch, nm, OBJPROP_TEXT, lines[i]);
ObjectSetInteger(ch, nm, OBJPROP_COLOR, c);
}
else
{
ObjectSetString(ch, nm, OBJPROP_TEXT, "");
}
}
UnitedPnL_ApplyGeometry();
ChartRedraw(ch);
}
void UnitedProfitPanelInit()
{
if(!UnitedPanel_Enable)
return;
UnitedPnL_EnsureObjects();
UnitedPnL_CollectRows();
g_unitedPnL_visibleLineCount = 6;
UnitedPnL_ApplyGeometry();
UnitedPnL_RefreshText();
}
void UnitedProfitPanelDeinit()
{
ObjectsDeleteAll(UnitedPnL_ChartId(), "UnitedPnL_");
}
void UnitedProfitPanelRefresh()
{
if(!UnitedPanel_Enable)
return;
UnitedPnL_RefreshText();
}
void UnitedProfitPanelOnChartEvent(const int id)
{
if(!UnitedPanel_Enable)
return;
if(id == CHARTEVENT_CHART_CHANGE)
{
UnitedPnL_CollectRows();
UnitedPnL_ApplyGeometry();
ChartRedraw(UnitedPnL_ChartId());
}
}
#endif
@@ -1,6 +0,0 @@
\begin{figure}[t]
\centering
\includegraphics[width=\linewidth]{frontline/MQL5/_united_dynamic/report/pnl_by_magic_robot.pdf}
\caption{Net closed P\&L by robot magic number from the united\_dynamic live report export. Bars show net realized P\&L (USD) and the label \texttt{n} is the number of closed trades. Because the MT5 report does not expose per-deal magic directly in this extract, XAUUSD trades that come from multiple XAU strategies are shown as one mixed bucket.}
\label{fig:united-dynamic-pnl-by-magic}
\end{figure}
@@ -1,6 +0,0 @@
\begin{figure*}[t]
\centering
\includegraphics[width=\textwidth]{frontline/MQL5/_united_dynamic/report/pnl_timeseries_by_robot.pdf}
\caption{Cumulative closed P\&L over time split by robot. Non-XAU robots are mapped directly by symbol-to-magic configuration; XAU trades are assigned by ticket-matched strategy comments when available, and otherwise grouped into an unattributed XAU bucket.}
\label{fig:united-dynamic-pnl-timeseries-by-robot}
\end{figure*}
@@ -1,6 +0,0 @@
\begin{figure}[t]
\centering
\includegraphics[width=\linewidth]{frontline/MQL5/_united_dynamic/report/pnl_timeseries_line.pdf}
\caption{Cumulative closed P\&L over time for the united\_dynamic account history in \texttt{ReportHistory-51389369.xlsx}. The curve is formed by sorting closed deals by close timestamp and cumulatively summing realized deal P\&L.}
\label{fig:united-dynamic-pnl-timeseries}
\end{figure}
@@ -1,9 +0,0 @@
symbol,magic_number,robot,count,sum
MSFT.US,20002,RSI Scalping MSFT,12,-1042.0
EURUSD,30001,RSI Reversal Asian EURUSD,20,-264.84999999999997
BTCUSD,123459123,RSI Scalping BTCUSD,11,-203.41000000000003
NVDA.US,20003,RSI Scalping NVDA,32,-42.54000000000002
AAPL.US,20001,RSI Scalping AAPL,5,-2.0
AUDUSD,30002,RSI Reversal Asian AUDUSD,14,78.08000000000001
XAUUSD,MIXED,XAUUSD Multi-Strategy Bucket,291,1953.66
TSLA.US,125421321,RSI Scalping TSLA,16,2352.57
1 symbol magic_number robot count sum
2 MSFT.US 20002 RSI Scalping MSFT 12 -1042.0
3 EURUSD 30001 RSI Reversal Asian EURUSD 20 -264.84999999999997
4 BTCUSD 123459123 RSI Scalping BTCUSD 11 -203.41000000000003
5 NVDA.US 20003 RSI Scalping NVDA 32 -42.54000000000002
6 AAPL.US 20001 RSI Scalping AAPL 5 -2.0
7 AUDUSD 30002 RSI Reversal Asian AUDUSD 14 78.08000000000001
8 XAUUSD MIXED XAUUSD Multi-Strategy Bucket 291 1953.66
9 TSLA.US 125421321 RSI Scalping TSLA 16 2352.57
Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

@@ -1,386 +0,0 @@
close_time,125421321 RSI Scalping TSLA,XAU Unattributed (multiple robots),129102315 RSI Scalping XAUUSD,30002 RSI Reversal Asian AUDUSD,20003 RSI Scalping NVDA,12350 EMA Slope Distance (XAU),123459123 RSI Scalping BTCUSD,30001 RSI Reversal Asian EURUSD,20002 RSI Scalping MSFT
2026-01-05 08:00:00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
2026-01-05 12:06:01,0.0,0.0,0.0,0.0,0.0,61.98,0.0,0.0,0.0
2026-01-05 18:06:21,0.0,0.0,0.0,0.0,0.0,86.07,0.0,0.0,0.0
2026-01-06 07:55:38,0.0,0.0,0.0,0.0,0.0,86.07,0.0,-3.0,0.0
2026-01-06 08:00:00,0.0,0.0,0.0,4.2,0.0,86.07,0.0,-3.0,0.0
2026-01-06 12:00:00,0.0,0.0,-81.78,4.2,0.0,86.07,0.0,-3.0,0.0
2026-01-06 15:13:04,0.0,0.0,-78.69,4.2,0.0,86.07,0.0,-3.0,0.0
2026-01-06 16:39:10,0.0,0.0,-78.69,4.2,0.0,111.69,0.0,-3.0,0.0
2026-01-06 19:42:51,0.0,0.0,-78.69,4.2,0.0,101.72999999999999,0.0,-3.0,0.0
2026-01-07 08:00:00,0.0,0.0,-78.69,12.2,0.0,101.72999999999999,0.0,-3.0,0.0
2026-01-07 11:00:00,0.0,0.0,-78.69,12.2,0.0,29.189999999999984,0.0,-3.0,0.0
2026-01-08 08:21:15,0.0,0.0,-78.69,12.2,0.0,29.339999999999982,0.0,-3.0,0.0
2026-01-08 18:00:00,0.0,0.0,-78.69,12.2,0.0,29.339999999999982,0.0,-3.0,-49.1
2026-01-09 07:00:00,0.0,0.0,-78.69,12.2,0.0,29.339999999999982,0.0,-3.0,-49.1
2026-01-12 03:00:00,0.0,0.0,296.85,12.2,0.0,29.339999999999982,0.0,-3.0,-49.1
2026-01-12 05:43:32,0.0,0.0,296.85,12.2,0.0,36.11999999999998,0.0,-3.0,-49.1
2026-01-12 06:00:00,0.0,0.0,296.85,12.2,0.0,35.399999999999984,0.0,-3.0,-49.1
2026-01-12 06:01:28,0.0,0.0,296.85,12.2,0.0,35.399999999999984,0.0,-3.8,-49.1
2026-01-13 00:01:01,0.0,0.0,296.85,12.2,0.0,35.399999999999984,0.0,-10.2,-49.1
2026-01-13 03:00:00,0.0,0.0,246.06000000000003,12.2,0.0,35.399999999999984,0.0,-10.2,-49.1
2026-01-13 16:28:43,0.0,0.0,267.48,12.2,0.0,56.819999999999986,0.0,-10.2,-49.1
2026-01-13 20:00:00,0.0,0.0,267.48,12.2,0.0,-63.00000000000001,0.0,-10.2,-49.1
2026-01-14 05:28:14,0.0,0.0,267.48,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-14 07:19:03,0.0,0.0,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-14 15:00:44,0.0,-11.19,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-14 17:11:47,49.1,-11.19,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-15 03:00:00,49.1,-74.88,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-15 07:28:43,49.1,-69.75,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-15 17:00:00,49.1,-141.66,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-16 08:00:00,49.1,-152.35999999999999,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-19 01:01:01,49.1,-348.98,305.1,12.2,0.0,-72.63000000000001,0.0,-10.2,-49.1
2026-01-19 02:08:19,49.1,-348.98,305.1,12.2,0.0,-72.63000000000001,0.0,-0.6999999999999993,-49.1
2026-01-19 03:00:46,49.1,-354.74,305.1,12.2,0.0,-72.63000000000001,0.0,-0.6999999999999993,-49.1
2026-01-19 04:00:26,49.1,-354.74,305.1,12.2,0.0,-72.63000000000001,0.0,9.4,-49.1
2026-01-20 00:01:00,49.1,-354.74,305.1,12.2,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 07:24:12,49.1,-282.38,305.1,12.2,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 08:00:00,49.1,-282.38,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 09:51:16,49.1,-271.4,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 10:19:24,49.1,-254.29999999999998,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 12:00:07,49.1,-247.93999999999997,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-20 15:34:19,49.1,-237.22999999999996,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-5.199999999999999,-49.1
2026-01-21 00:01:00,49.1,-237.22999999999996,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-21 17:24:43,49.1,-145.00999999999996,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 02:00:00,49.1,-361.5799999999999,305.1,-4.199999999999999,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 08:00:00,49.1,-459.2299999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 18:00:00,23.700000000000003,-459.2299999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 18:30:02,23.700000000000003,-434.1799999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 21:27:07,23.700000000000003,-334.9099999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-22 22:00:00,23.700000000000003,-335.6599999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-23 03:00:00,23.700000000000003,-498.8299999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.3,-49.1
2026-01-23 04:44:42,23.700000000000003,-498.8299999999999,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-23 05:16:54,23.700000000000003,-506.74999999999994,305.1,-31.4,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-23 08:00:00,23.700000000000003,-506.74999999999994,305.1,-46.0,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-23 11:00:00,23.700000000000003,-388.3399999999999,305.1,-46.0,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-26 04:00:00,23.700000000000003,34.3300000000001,305.1,-46.0,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-26 08:00:00,23.700000000000003,34.3300000000001,305.1,-34.4,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-26 21:00:00,23.700000000000003,65.1700000000001,305.1,-34.4,0.0,-72.63000000000001,0.0,-81.39999999999999,-49.1
2026-01-27 00:01:00,23.700000000000003,65.1700000000001,305.1,-34.4,0.0,-72.63000000000001,0.0,-214.09999999999997,-49.1
2026-01-27 04:00:00,23.700000000000003,-41.089999999999904,305.1,-34.4,0.0,-72.63000000000001,0.0,-214.09999999999997,-49.1
2026-01-27 05:07:00,23.700000000000003,-41.089999999999904,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 06:09:45,23.700000000000003,-40.60999999999991,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 08:50:00,23.700000000000003,-5.089999999999904,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 09:12:16,23.700000000000003,-0.25999999999990386,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 11:45:33,23.700000000000003,2.560000000000096,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 16:00:00,23.700000000000003,-61.159999999999904,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 17:03:41,54.300000000000004,-61.159999999999904,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-27 23:00:30,54.300000000000004,159.3400000000001,305.1,-34.4,0.0,-72.63000000000001,0.0,-207.59999999999997,-49.1
2026-01-28 03:31:17,54.300000000000004,159.3400000000001,305.1,-34.4,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 07:01:59,54.300000000000004,588.97,305.1,-34.4,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 08:00:00,54.300000000000004,588.97,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 09:00:38,54.300000000000004,601.69,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 10:12:05,54.300000000000004,603.82,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 14:12:22,54.300000000000004,604.0,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 17:12:17,54.300000000000004,647.86,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,-49.1
2026-01-28 18:53:19,54.300000000000004,647.86,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,2.3999999999999986
2026-01-28 19:08:19,54.300000000000004,645.46,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,2.3999999999999986
2026-01-29 02:00:01,54.300000000000004,-0.8899999999999864,305.1,-27.2,0.0,-72.63000000000001,0.0,-171.69999999999996,2.3999999999999986
2026-01-29 07:58:06,54.300000000000004,-0.8899999999999864,305.1,-27.2,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-29 08:00:00,54.300000000000004,-0.8899999999999864,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-29 12:38:43,54.300000000000004,8.890000000000013,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 01:01:01,54.300000000000004,-650.63,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 04:00:00,54.300000000000004,-1064.69,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 06:00:34,54.300000000000004,-1001.1800000000001,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 07:00:00,54.300000000000004,-1003.58,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 09:00:00,54.300000000000004,-1044.07,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 11:00:10,54.300000000000004,-873.4,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 20:00:04,54.300000000000004,-397.51,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-01-30 23:00:03,54.300000000000004,-318.01,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 02:00:00,54.300000000000004,-244.57,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 04:00:10,54.300000000000004,-85.47999999999999,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 07:13:20,54.300000000000004,-60.609999999999985,305.1,-57.8,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 08:00:00,54.300000000000004,-60.609999999999985,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 08:12:16,54.300000000000004,-30.879999999999985,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 09:16:31,54.300000000000004,-23.319999999999986,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 10:24:18,54.300000000000004,32.72000000000001,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-03 17:27:59,154.4,32.72000000000001,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-159.99999999999997,2.3999999999999986
2026-02-04 04:50:05,154.4,32.72000000000001,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-152.49999999999997,2.3999999999999986
2026-02-04 07:00:00,154.4,31.830000000000013,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-152.49999999999997,2.3999999999999986
2026-02-04 07:00:02,154.4,482.03999999999996,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-152.49999999999997,2.3999999999999986
2026-02-04 12:13:15,154.4,487.61999999999995,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-152.49999999999997,2.3999999999999986
2026-02-04 18:24:11,154.4,558.9,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-152.49999999999997,2.3999999999999986
2026-02-05 00:01:00,154.4,558.9,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-05 01:01:00,154.4,305.93999999999994,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-05 04:00:00,154.4,145.13999999999993,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-05 08:00:12,154.4,155.80999999999992,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-05 17:48:31,154.4,177.07999999999993,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-05 23:01:58,154.4,181.36999999999992,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-06 01:01:01,154.4,131.0399999999999,305.1,-61.599999999999994,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-06 04:01:08,154.4,131.0399999999999,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-06 08:00:00,154.4,-452.8200000000001,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 03:51:31,154.4,-249.7200000000001,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 03:59:22,154.4,-83.5700000000001,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 07:00:00,154.4,-87.02000000000011,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 13:00:00,154.4,73.72999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 15:00:02,154.4,69.55999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-09 17:43:21,-126.6,69.55999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 05:00:00,-126.6,-29.140000000000114,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 07:00:00,-126.6,-30.010000000000115,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 07:15:30,-126.6,50.63999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 10:50:55,-126.6,76.61999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 11:13:05,-126.6,111.65999999999988,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 12:54:34,-126.6,123.17999999999988,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 13:18:10,-126.6,126.59999999999988,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 16:25:00,-126.6,213.71999999999989,305.1,9.400000000000006,0.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 16:45:00,-126.6,213.71999999999989,305.1,9.400000000000006,2.0,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 17:00:00,-126.6,213.71999999999989,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 17:15:40,-126.6,213.8999999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,2.3999999999999986
2026-02-10 21:00:01,-126.6,213.8999999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 04:02:06,-126.6,237.0299999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 07:48:46,-126.6,237.9299999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 08:00:00,-126.6,218.2799999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 11:49:18,-126.6,235.7999999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 12:27:16,-126.6,295.1599999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 13:24:06,-126.6,304.6699999999999,305.1,9.400000000000006,2.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 17:25:57,-126.6,304.6699999999999,305.1,9.400000000000006,3.0,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-11 19:20:00,-126.6,304.6699999999999,305.1,9.400000000000006,3.0,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 05:00:00,-126.6,174.6699999999999,305.1,9.400000000000006,3.0,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 07:00:00,-126.6,173.1699999999999,305.1,9.400000000000006,3.0,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 09:00:00,-126.6,14.919999999999902,305.1,9.400000000000006,3.0,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 17:45:00,-126.6,14.919999999999902,305.1,9.400000000000006,17.45,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 18:00:01,-126.6,14.919999999999902,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 20:01:58,-126.6,43.119999999999905,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-12 23:02:07,-126.6,97.1499999999999,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 05:18:27,-126.6,105.3999999999999,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 08:00:00,-126.6,0.9699999999998994,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 15:42:45,-126.6,-294.7100000000001,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 19:00:00,-126.6,-488.5700000000001,305.1,9.400000000000006,19.849999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 21:42:00,-126.6,-488.5700000000001,305.1,9.400000000000006,28.349999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 21:58:36,-126.6,-446.1500000000001,305.1,9.400000000000006,28.349999999999998,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-13 22:00:00,-126.6,-446.1500000000001,305.1,9.400000000000006,32.55,-72.63000000000001,0.0,-129.39999999999998,-20.5
2026-02-16 02:00:00,-126.6,-446.1500000000001,305.1,9.400000000000006,32.55,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-16 05:00:00,-126.6,-579.1000000000001,305.1,9.400000000000006,32.55,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-17 17:00:00,-49.8,-579.1000000000001,305.1,9.400000000000006,32.55,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-17 17:45:00,-49.8,-579.1000000000001,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-19 22:00:00,-49.8,-133.80000000000013,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-20 07:00:00,-49.8,-201.30000000000013,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-23 02:00:00,-49.8,1316.8999999999999,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 02:00:00,-49.8,407.79999999999984,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 04:00:00,-49.8,860.9999999999998,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 10:01:34,-49.8,880.3799999999998,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 14:01:01,-49.8,873.7799999999997,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 18:00:00,-49.8,759.9899999999998,305.1,9.400000000000006,26.449999999999996,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-24 18:15:00,-49.8,759.9899999999998,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-25 05:55:01,-49.8,762.1799999999998,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-25 08:00:56,-49.8,811.8899999999999,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-25 16:00:00,-49.8,634.3899999999999,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-25 18:07:26,-49.8,624.6399999999999,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-25 23:00:03,-49.8,442.65999999999985,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-26 03:00:00,-49.8,375.05999999999983,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,-16.6,-129.39999999999998,-20.5
2026-02-26 06:00:00,-49.8,375.05999999999983,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 13:00:00,-49.8,293.0099999999998,305.1,9.400000000000006,-58.300000000000004,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 16:45:00,-49.8,293.0099999999998,305.1,9.400000000000006,21.699999999999996,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 16:46:48,-49.8,293.0099999999998,305.1,9.400000000000006,26.399999999999995,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 16:46:53,-49.8,293.0099999999998,305.1,9.400000000000006,52.099999999999994,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 16:46:56,-49.8,293.0099999999998,305.1,9.400000000000006,89.94999999999999,-72.63000000000001,106.34,-129.39999999999998,-20.5
2026-02-26 18:56:28,-49.8,293.0099999999998,305.1,9.400000000000006,89.94999999999999,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-26 20:45:00,-49.8,293.0099999999998,305.1,9.400000000000006,40.44999999999999,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-26 22:30:01,-49.8,293.0099999999998,305.1,9.400000000000006,3.6999999999999886,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 07:00:01,-49.8,292.3299999999998,305.1,9.400000000000006,3.6999999999999886,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 16:45:00,-49.8,292.3299999999998,305.1,9.400000000000006,5.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 18:00:00,-49.8,292.3299999999998,305.1,9.400000000000006,13.199999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 18:00:33,-49.8,329.3799999999998,305.1,9.400000000000006,13.199999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 18:15:00,-49.8,329.3799999999998,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 20:15:53,-49.8,337.0899999999998,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 21:03:14,187.2,337.0899999999998,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-02-27 23:01:44,187.2,377.5299999999998,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 01:03:37,187.2,1653.3299999999997,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 02:00:03,187.2,1747.1699999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 06:01:54,187.2,1803.8999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 09:01:24,187.2,1889.0999999999997,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 09:13:03,187.2,1095.8999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 17:00:00,187.2,1730.3999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 18:00:30,187.2,1378.8899999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-02 23:30:48,187.2,1418.6999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 02:00:21,187.2,1442.7299999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 05:17:20,187.2,1477.2599999999995,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 11:00:00,187.2,530.9999999999995,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 12:00:00,187.2,529.2599999999995,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 13:00:18,187.2,593.6999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-18.25
2026-03-03 16:31:02,187.2,593.6999999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-03 17:00:05,187.2,897.6599999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-03 20:00:21,187.2,935.6399999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-03 22:00:04,187.2,996.3299999999997,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-04 18:00:00,187.2,828.2399999999997,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-04 20:00:10,187.2,844.6499999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,106.34,-129.39999999999998,-98.75
2026-03-05 04:00:00,187.2,844.6499999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 05:00:00,187.2,668.1899999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 09:00:00,187.2,415.9899999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 16:00:00,187.2,371.4299999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 16:00:11,187.2,456.3299999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 19:02:14,187.2,515.6099999999996,305.1,9.400000000000006,11.449999999999989,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-05 20:30:00,187.2,515.6099999999996,305.1,9.400000000000006,-1.0500000000000114,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-06 12:00:00,187.2,417.5299999999996,305.1,9.400000000000006,-1.0500000000000114,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-06 15:00:00,187.2,355.42999999999955,305.1,9.400000000000006,-1.0500000000000114,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-06 17:00:00,187.2,209.44999999999956,305.1,9.400000000000006,-1.0500000000000114,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-06 22:30:00,187.2,209.44999999999956,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 01:01:22,187.2,288.10999999999956,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 04:06:01,187.2,357.8299999999996,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 05:00:00,187.2,-362.5700000000004,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 09:00:00,187.2,-525.8900000000003,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 12:01:35,187.2,-530.5700000000003,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 17:00:00,599.95,-530.5700000000003,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-09 17:00:25,599.95,-500.0600000000003,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 01:01:33,599.95,-490.52000000000027,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 05:02:32,599.95,-405.5600000000003,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 08:00:01,599.95,-407.40000000000026,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 09:05:27,599.95,-379.41000000000025,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 11:03:06,599.95,-369.30000000000024,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 17:00:17,599.95,-311.97000000000025,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-10 19:03:01,599.95,-253.23000000000025,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-11 07:00:00,599.95,-253.71000000000024,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-11 10:00:00,599.95,299.38999999999976,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-11 15:00:01,599.95,158.68999999999977,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-11 16:31:01,510.95000000000005,158.68999999999977,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-98.75
2026-03-11 18:00:00,510.95000000000005,158.68999999999977,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 03:09:47,510.95000000000005,155.53999999999976,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 06:01:28,510.95000000000005,152.23999999999975,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 11:00:00,510.95000000000005,32.05999999999975,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 12:00:00,510.95000000000005,40.11999999999975,305.1,9.400000000000006,-71.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 17:30:01,510.95000000000005,40.11999999999975,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 18:46:42,510.95000000000005,102.39999999999975,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 19:04:29,510.95000000000005,151.41999999999976,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-131.25
2026-03-12 21:00:02,510.95000000000005,151.41999999999976,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-12 21:01:15,510.95000000000005,196.56999999999977,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-12 23:01:04,510.95000000000005,216.24999999999977,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-13 08:00:00,510.95000000000005,195.32999999999976,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-13 18:00:14,510.95000000000005,286.34999999999974,305.1,9.400000000000006,27.19999999999999,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-13 19:30:00,510.95000000000005,286.34999999999974,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,259.51,-129.39999999999998,-174.5
2026-03-13 23:00:00,510.95000000000005,286.34999999999974,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-13 23:00:35,510.95000000000005,330.9299999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 03:00:15,510.95000000000005,355.52999999999975,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 05:00:33,510.95000000000005,376.43999999999977,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 11:00:31,510.95000000000005,392.00999999999976,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 13:09:14,510.95000000000005,429.08999999999975,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 14:00:00,510.95000000000005,457.3099999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,28.92999999999998,-129.39999999999998,-174.5
2026-03-16 15:00:00,510.95000000000005,457.3099999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-1.2600000000000229,-129.39999999999998,-174.5
2026-03-16 17:00:00,501.95000000000005,457.3099999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-1.2600000000000229,-129.39999999999998,-174.5
2026-03-17 11:00:01,501.95000000000005,457.3099999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-17 14:00:00,501.95000000000005,401.4499999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-17 14:08:21,501.95000000000005,421.4899999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-17 19:18:11,501.95000000000005,429.28999999999974,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-17 23:04:43,501.95000000000005,424.45999999999975,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 05:00:33,501.95000000000005,418.78999999999974,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 06:00:00,501.95000000000005,401.00999999999976,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 07:24:05,501.95000000000005,394.76999999999975,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 14:14:57,501.95000000000005,443.4299999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 16:31:00,503.70000000000005,443.4299999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 16:42:22,503.70000000000005,580.7099999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 18:00:39,503.70000000000005,597.5699999999997,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 22:04:29,503.70000000000005,618.3899999999998,305.1,9.400000000000006,-16.55000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-18 22:45:00,503.70000000000005,618.3899999999998,305.1,9.400000000000006,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 01:01:09,503.70000000000005,647.6999999999997,305.1,9.400000000000006,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 05:07:38,503.70000000000005,647.6999999999997,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 09:00:35,503.70000000000005,659.9999999999997,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 11:00:07,503.70000000000005,761.2199999999997,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 13:00:36,503.70000000000005,783.0299999999996,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 16:20:36,503.70000000000005,1087.8299999999997,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 16:31:00,1279.2,1087.8299999999997,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-19 18:00:12,1279.2,1136.1899999999996,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-129.39999999999998,-174.5
2026-03-20 04:50:41,1279.2,1136.1899999999996,305.1,51.60000000000001,-35.05000000000001,-72.63000000000001,-142.25000000000003,-109.49999999999997,-174.5
2026-03-20 18:00:00,1279.2,1136.1899999999996,305.1,51.60000000000001,-186.55,-72.63000000000001,-142.25000000000003,-109.49999999999997,-174.5
2026-03-20 20:45:00,1279.2,1136.1899999999996,305.1,51.60000000000001,-275.05,-72.63000000000001,-142.25000000000003,-109.49999999999997,-174.5
2026-03-23 23:00:00,1279.2,1136.1899999999996,305.1,51.60000000000001,-275.05,-72.63000000000001,-225.91000000000003,-109.49999999999997,-174.5
2026-03-24 04:00:00,1279.2,1009.8699999999997,305.1,51.60000000000001,-275.05,-72.63000000000001,-225.91000000000003,-109.49999999999997,-174.5
2026-03-24 17:30:00,1279.2,1009.8699999999997,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-109.49999999999997,-174.5
2026-03-25 02:00:30,1279.2,1028.9499999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-109.49999999999997,-174.5
2026-03-25 04:00:04,1279.2,1065.3699999999997,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-109.49999999999997,-174.5
2026-03-25 04:54:18,1279.2,1065.3699999999997,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-25 16:31:01,871.7,1065.3699999999997,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-25 23:00:00,871.7,871.1799999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 01:01:01,871.7,1292.4799999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 05:00:47,871.7,1284.1699999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 12:00:55,871.7,1305.8899999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 13:00:00,871.7,1353.8899999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 15:00:47,871.7,1347.1999999999996,305.1,51.60000000000001,-392.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 17:30:00,871.7,1347.1999999999996,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 20:00:33,871.7,1457.0299999999995,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-26 23:11:44,871.7,1488.7099999999996,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 04:00:00,871.7,1421.1099999999997,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 04:00:03,871.7,1417.3899999999996,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 09:00:00,871.7,1308.3699999999997,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 14:00:12,871.7,1330.2699999999998,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 16:31:00,1699.7,1330.2699999999998,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 18:00:01,1699.7,1054.2399999999998,305.1,51.60000000000001,-391.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 20:30:01,1699.7,1054.2399999999998,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-174.5
2026-03-27 21:00:00,1699.7,1054.2399999999998,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 03:00:01,1699.7,828.9099999999997,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 04:00:13,1699.7,70.40999999999974,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 05:00:00,1699.7,-33.84000000000026,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 09:00:03,1699.7,33.29999999999974,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 10:00:00,1699.7,32.679999999999744,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 12:06:36,1699.7,44.169999999999746,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 15:00:29,1699.7,113.01999999999974,305.1,51.60000000000001,-477.05,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 22:30:00,1699.7,113.01999999999974,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-30 23:00:00,1699.7,37.119999999999735,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-102.99999999999997,-117.5
2026-03-31 04:50:01,1699.7,37.119999999999735,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 05:00:17,1699.7,129.66999999999973,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 07:00:00,1699.7,129.30999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 09:00:13,1699.7,122.34999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 11:02:00,1699.7,133.98999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 15:14:01,1699.7,167.58999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 17:09:58,1699.7,253.86999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 21:10:02,1699.7,253.86999999999972,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-03-31 22:08:48,1699.7,448.26999999999975,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-04-01 03:00:31,1699.7,475.2399999999998,305.1,51.60000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-04-01 08:00:00,1699.7,475.2399999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-94.59999999999997,-117.5
2026-04-02 00:01:00,1699.7,475.2399999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-02 08:00:00,1699.7,1736.6399999999999,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-02 18:00:01,1699.7,1470.8999999999999,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-06 03:01:14,1699.7,1538.61,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-06 08:00:00,1699.7,1426.62,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-06 12:50:29,1699.7,1448.79,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-06 17:00:00,1699.7,1295.09,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-117.5
2026-04-06 18:00:00,1699.7,1295.09,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-188.5
2026-04-06 18:40:05,1699.7,1295.09,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-188.5
2026-04-06 20:00:00,1699.7,1195.1899999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-188.5
2026-04-06 20:00:01,2471.7,1195.1899999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-225.91000000000003,-138.49999999999997,-188.5
2026-04-07 01:00:00,2471.7,1195.1899999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-113.86000000000003,-138.49999999999997,-188.5
2026-04-07 08:00:01,2471.7,1094.1499999999999,305.1,99.80000000000001,-642.55,-72.63000000000001,-113.86000000000003,-138.49999999999997,-188.5
2026-04-07 14:00:00,2471.7,998.3899999999999,305.1,99.80000000000001,-642.55,-72.63000000000001,-113.86000000000003,-138.49999999999997,-188.5
2026-04-07 16:00:00,2471.7,684.1899999999998,305.1,99.80000000000001,-642.55,-72.63000000000001,-113.86000000000003,-138.49999999999997,-188.5
2026-04-07 17:30:00,2471.7,684.1899999999998,305.1,99.80000000000001,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-188.5
2026-04-07 18:00:01,2471.7,684.1899999999998,305.1,99.80000000000001,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-07 21:00:00,2471.7,555.0999999999998,305.1,99.80000000000001,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-08 01:01:06,2471.7,678.7299999999998,305.1,99.80000000000001,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-08 03:00:07,2471.7,712.4799999999998,305.1,99.80000000000001,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-08 08:00:00,2471.7,712.4799999999998,305.1,-72.39999999999998,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-08 09:08:23,2471.7,730.9599999999998,305.1,-72.39999999999998,-264.04999999999995,-72.63000000000001,-113.86000000000003,-138.49999999999997,-356.5
2026-04-08 10:00:00,2471.7,730.9599999999998,305.1,-72.39999999999998,-264.04999999999995,-72.63000000000001,-96.76000000000002,-138.49999999999997,-356.5
2026-04-08 16:31:00,2471.7,730.9599999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-138.49999999999997,-356.5
2026-04-08 18:20:00,2471.7,730.9599999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-138.49999999999997,-356.5
2026-04-08 20:00:00,2471.7,1312.6599999999999,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-138.49999999999997,-356.5
2026-04-08 21:00:01,2471.7,1056.0099999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-138.49999999999997,-356.5
2026-04-09 00:01:00,2471.7,1056.0099999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-356.5
2026-04-09 13:00:01,2471.7,978.8799999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-356.5
2026-04-09 16:31:01,2471.7,978.8799999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-09 17:00:38,2471.7,995.0199999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-09 19:13:39,2471.7,1057.1799999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-09 21:01:21,2471.7,1073.4099999999999,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-10 01:01:52,2471.7,1075.2699999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-10 05:00:02,2471.7,1155.7699999999998,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-10 05:00:30,2471.7,1149.5899999999997,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-10 17:00:01,2471.7,1149.9499999999996,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-953.0
2026-04-10 18:36:21,2471.7,1149.9499999999996,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-10 21:00:00,2471.7,985.5499999999996,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-13 01:01:02,2471.7,641.7499999999995,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-13 01:01:03,2471.7,1087.5699999999995,305.1,-72.39999999999998,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-13 07:33:34,2471.7,1087.5699999999995,305.1,78.08000000000001,198.95000000000005,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-13 18:00:01,2471.7,1087.5699999999995,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-13 20:00:00,2352.5699999999997,787.4099999999994,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-14 04:00:02,2352.5699999999997,813.0899999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-14 06:00:57,2352.5699999999997,833.8799999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-14 08:02:23,2352.5699999999997,847.8799999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-14 09:00:04,2352.5699999999997,844.2399999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-96.76000000000002,-211.49999999999997,-1042.0
2026-04-14 09:00:07,2352.5699999999997,844.2399999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,0.9899999999999807,-211.49999999999997,-1042.0
2026-04-14 12:05:23,2352.5699999999997,851.1599999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,0.9899999999999807,-211.49999999999997,-1042.0
2026-04-14 18:00:36,2352.5699999999997,939.3599999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,0.9899999999999807,-211.49999999999997,-1042.0
2026-04-14 21:21:16,2352.5699999999997,1039.9199999999994,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,0.9899999999999807,-211.49999999999997,-1042.0
2026-04-14 23:00:00,2352.5699999999997,1039.9199999999994,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-211.49999999999997,-1042.0
2026-04-14 23:04:34,2352.5699999999997,1068.0699999999995,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-211.49999999999997,-1042.0
2026-04-15 00:01:00,2352.5699999999997,1068.0699999999995,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-264.84999999999997,-1042.0
2026-04-15 05:15:57,2352.5699999999997,1086.4199999999994,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-264.84999999999997,-1042.0
2026-04-15 08:30:19,2352.5699999999997,1076.7199999999993,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-264.84999999999997,-1042.0
2026-04-15 12:00:00,2352.5699999999997,1796.5999999999995,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-264.84999999999997,-1042.0
2026-04-15 14:00:00,2352.5699999999997,1721.9599999999994,305.1,78.08000000000001,-42.539999999999964,-72.63000000000001,-203.41000000000003,-264.84999999999997,-1042.0
1 close_time 125421321 RSI Scalping TSLA XAU Unattributed (multiple robots) 129102315 RSI Scalping XAUUSD 30002 RSI Reversal Asian AUDUSD 20003 RSI Scalping NVDA 12350 EMA Slope Distance (XAU) 123459123 RSI Scalping BTCUSD 30001 RSI Reversal Asian EURUSD 20002 RSI Scalping MSFT
2 2026-01-05 08:00:00 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 2026-01-05 12:06:01 0.0 0.0 0.0 0.0 0.0 61.98 0.0 0.0 0.0
4 2026-01-05 18:06:21 0.0 0.0 0.0 0.0 0.0 86.07 0.0 0.0 0.0
5 2026-01-06 07:55:38 0.0 0.0 0.0 0.0 0.0 86.07 0.0 -3.0 0.0
6 2026-01-06 08:00:00 0.0 0.0 0.0 4.2 0.0 86.07 0.0 -3.0 0.0
7 2026-01-06 12:00:00 0.0 0.0 -81.78 4.2 0.0 86.07 0.0 -3.0 0.0
8 2026-01-06 15:13:04 0.0 0.0 -78.69 4.2 0.0 86.07 0.0 -3.0 0.0
9 2026-01-06 16:39:10 0.0 0.0 -78.69 4.2 0.0 111.69 0.0 -3.0 0.0
10 2026-01-06 19:42:51 0.0 0.0 -78.69 4.2 0.0 101.72999999999999 0.0 -3.0 0.0
11 2026-01-07 08:00:00 0.0 0.0 -78.69 12.2 0.0 101.72999999999999 0.0 -3.0 0.0
12 2026-01-07 11:00:00 0.0 0.0 -78.69 12.2 0.0 29.189999999999984 0.0 -3.0 0.0
13 2026-01-08 08:21:15 0.0 0.0 -78.69 12.2 0.0 29.339999999999982 0.0 -3.0 0.0
14 2026-01-08 18:00:00 0.0 0.0 -78.69 12.2 0.0 29.339999999999982 0.0 -3.0 -49.1
15 2026-01-09 07:00:00 0.0 0.0 -78.69 12.2 0.0 29.339999999999982 0.0 -3.0 -49.1
16 2026-01-12 03:00:00 0.0 0.0 296.85 12.2 0.0 29.339999999999982 0.0 -3.0 -49.1
17 2026-01-12 05:43:32 0.0 0.0 296.85 12.2 0.0 36.11999999999998 0.0 -3.0 -49.1
18 2026-01-12 06:00:00 0.0 0.0 296.85 12.2 0.0 35.399999999999984 0.0 -3.0 -49.1
19 2026-01-12 06:01:28 0.0 0.0 296.85 12.2 0.0 35.399999999999984 0.0 -3.8 -49.1
20 2026-01-13 00:01:01 0.0 0.0 296.85 12.2 0.0 35.399999999999984 0.0 -10.2 -49.1
21 2026-01-13 03:00:00 0.0 0.0 246.06000000000003 12.2 0.0 35.399999999999984 0.0 -10.2 -49.1
22 2026-01-13 16:28:43 0.0 0.0 267.48 12.2 0.0 56.819999999999986 0.0 -10.2 -49.1
23 2026-01-13 20:00:00 0.0 0.0 267.48 12.2 0.0 -63.00000000000001 0.0 -10.2 -49.1
24 2026-01-14 05:28:14 0.0 0.0 267.48 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
25 2026-01-14 07:19:03 0.0 0.0 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
26 2026-01-14 15:00:44 0.0 -11.19 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
27 2026-01-14 17:11:47 49.1 -11.19 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
28 2026-01-15 03:00:00 49.1 -74.88 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
29 2026-01-15 07:28:43 49.1 -69.75 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
30 2026-01-15 17:00:00 49.1 -141.66 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
31 2026-01-16 08:00:00 49.1 -152.35999999999999 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
32 2026-01-19 01:01:01 49.1 -348.98 305.1 12.2 0.0 -72.63000000000001 0.0 -10.2 -49.1
33 2026-01-19 02:08:19 49.1 -348.98 305.1 12.2 0.0 -72.63000000000001 0.0 -0.6999999999999993 -49.1
34 2026-01-19 03:00:46 49.1 -354.74 305.1 12.2 0.0 -72.63000000000001 0.0 -0.6999999999999993 -49.1
35 2026-01-19 04:00:26 49.1 -354.74 305.1 12.2 0.0 -72.63000000000001 0.0 9.4 -49.1
36 2026-01-20 00:01:00 49.1 -354.74 305.1 12.2 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
37 2026-01-20 07:24:12 49.1 -282.38 305.1 12.2 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
38 2026-01-20 08:00:00 49.1 -282.38 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
39 2026-01-20 09:51:16 49.1 -271.4 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
40 2026-01-20 10:19:24 49.1 -254.29999999999998 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
41 2026-01-20 12:00:07 49.1 -247.93999999999997 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
42 2026-01-20 15:34:19 49.1 -237.22999999999996 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -5.199999999999999 -49.1
43 2026-01-21 00:01:00 49.1 -237.22999999999996 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -81.3 -49.1
44 2026-01-21 17:24:43 49.1 -145.00999999999996 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -81.3 -49.1
45 2026-01-22 02:00:00 49.1 -361.5799999999999 305.1 -4.199999999999999 0.0 -72.63000000000001 0.0 -81.3 -49.1
46 2026-01-22 08:00:00 49.1 -459.2299999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
47 2026-01-22 18:00:00 23.700000000000003 -459.2299999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
48 2026-01-22 18:30:02 23.700000000000003 -434.1799999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
49 2026-01-22 21:27:07 23.700000000000003 -334.9099999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
50 2026-01-22 22:00:00 23.700000000000003 -335.6599999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
51 2026-01-23 03:00:00 23.700000000000003 -498.8299999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.3 -49.1
52 2026-01-23 04:44:42 23.700000000000003 -498.8299999999999 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
53 2026-01-23 05:16:54 23.700000000000003 -506.74999999999994 305.1 -31.4 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
54 2026-01-23 08:00:00 23.700000000000003 -506.74999999999994 305.1 -46.0 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
55 2026-01-23 11:00:00 23.700000000000003 -388.3399999999999 305.1 -46.0 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
56 2026-01-26 04:00:00 23.700000000000003 34.3300000000001 305.1 -46.0 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
57 2026-01-26 08:00:00 23.700000000000003 34.3300000000001 305.1 -34.4 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
58 2026-01-26 21:00:00 23.700000000000003 65.1700000000001 305.1 -34.4 0.0 -72.63000000000001 0.0 -81.39999999999999 -49.1
59 2026-01-27 00:01:00 23.700000000000003 65.1700000000001 305.1 -34.4 0.0 -72.63000000000001 0.0 -214.09999999999997 -49.1
60 2026-01-27 04:00:00 23.700000000000003 -41.089999999999904 305.1 -34.4 0.0 -72.63000000000001 0.0 -214.09999999999997 -49.1
61 2026-01-27 05:07:00 23.700000000000003 -41.089999999999904 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
62 2026-01-27 06:09:45 23.700000000000003 -40.60999999999991 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
63 2026-01-27 08:50:00 23.700000000000003 -5.089999999999904 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
64 2026-01-27 09:12:16 23.700000000000003 -0.25999999999990386 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
65 2026-01-27 11:45:33 23.700000000000003 2.560000000000096 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
66 2026-01-27 16:00:00 23.700000000000003 -61.159999999999904 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
67 2026-01-27 17:03:41 54.300000000000004 -61.159999999999904 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
68 2026-01-27 23:00:30 54.300000000000004 159.3400000000001 305.1 -34.4 0.0 -72.63000000000001 0.0 -207.59999999999997 -49.1
69 2026-01-28 03:31:17 54.300000000000004 159.3400000000001 305.1 -34.4 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
70 2026-01-28 07:01:59 54.300000000000004 588.97 305.1 -34.4 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
71 2026-01-28 08:00:00 54.300000000000004 588.97 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
72 2026-01-28 09:00:38 54.300000000000004 601.69 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
73 2026-01-28 10:12:05 54.300000000000004 603.82 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
74 2026-01-28 14:12:22 54.300000000000004 604.0 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
75 2026-01-28 17:12:17 54.300000000000004 647.86 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 -49.1
76 2026-01-28 18:53:19 54.300000000000004 647.86 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 2.3999999999999986
77 2026-01-28 19:08:19 54.300000000000004 645.46 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 2.3999999999999986
78 2026-01-29 02:00:01 54.300000000000004 -0.8899999999999864 305.1 -27.2 0.0 -72.63000000000001 0.0 -171.69999999999996 2.3999999999999986
79 2026-01-29 07:58:06 54.300000000000004 -0.8899999999999864 305.1 -27.2 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
80 2026-01-29 08:00:00 54.300000000000004 -0.8899999999999864 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
81 2026-01-29 12:38:43 54.300000000000004 8.890000000000013 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
82 2026-01-30 01:01:01 54.300000000000004 -650.63 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
83 2026-01-30 04:00:00 54.300000000000004 -1064.69 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
84 2026-01-30 06:00:34 54.300000000000004 -1001.1800000000001 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
85 2026-01-30 07:00:00 54.300000000000004 -1003.58 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
86 2026-01-30 09:00:00 54.300000000000004 -1044.07 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
87 2026-01-30 11:00:10 54.300000000000004 -873.4 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
88 2026-01-30 20:00:04 54.300000000000004 -397.51 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
89 2026-01-30 23:00:03 54.300000000000004 -318.01 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
90 2026-02-03 02:00:00 54.300000000000004 -244.57 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
91 2026-02-03 04:00:10 54.300000000000004 -85.47999999999999 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
92 2026-02-03 07:13:20 54.300000000000004 -60.609999999999985 305.1 -57.8 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
93 2026-02-03 08:00:00 54.300000000000004 -60.609999999999985 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
94 2026-02-03 08:12:16 54.300000000000004 -30.879999999999985 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
95 2026-02-03 09:16:31 54.300000000000004 -23.319999999999986 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
96 2026-02-03 10:24:18 54.300000000000004 32.72000000000001 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
97 2026-02-03 17:27:59 154.4 32.72000000000001 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -159.99999999999997 2.3999999999999986
98 2026-02-04 04:50:05 154.4 32.72000000000001 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -152.49999999999997 2.3999999999999986
99 2026-02-04 07:00:00 154.4 31.830000000000013 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -152.49999999999997 2.3999999999999986
100 2026-02-04 07:00:02 154.4 482.03999999999996 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -152.49999999999997 2.3999999999999986
101 2026-02-04 12:13:15 154.4 487.61999999999995 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -152.49999999999997 2.3999999999999986
102 2026-02-04 18:24:11 154.4 558.9 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -152.49999999999997 2.3999999999999986
103 2026-02-05 00:01:00 154.4 558.9 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
104 2026-02-05 01:01:00 154.4 305.93999999999994 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
105 2026-02-05 04:00:00 154.4 145.13999999999993 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
106 2026-02-05 08:00:12 154.4 155.80999999999992 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
107 2026-02-05 17:48:31 154.4 177.07999999999993 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
108 2026-02-05 23:01:58 154.4 181.36999999999992 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
109 2026-02-06 01:01:01 154.4 131.0399999999999 305.1 -61.599999999999994 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
110 2026-02-06 04:01:08 154.4 131.0399999999999 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
111 2026-02-06 08:00:00 154.4 -452.8200000000001 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
112 2026-02-09 03:51:31 154.4 -249.7200000000001 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
113 2026-02-09 03:59:22 154.4 -83.5700000000001 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
114 2026-02-09 07:00:00 154.4 -87.02000000000011 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
115 2026-02-09 13:00:00 154.4 73.72999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
116 2026-02-09 15:00:02 154.4 69.55999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
117 2026-02-09 17:43:21 -126.6 69.55999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
118 2026-02-10 05:00:00 -126.6 -29.140000000000114 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
119 2026-02-10 07:00:00 -126.6 -30.010000000000115 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
120 2026-02-10 07:15:30 -126.6 50.63999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
121 2026-02-10 10:50:55 -126.6 76.61999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
122 2026-02-10 11:13:05 -126.6 111.65999999999988 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
123 2026-02-10 12:54:34 -126.6 123.17999999999988 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
124 2026-02-10 13:18:10 -126.6 126.59999999999988 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
125 2026-02-10 16:25:00 -126.6 213.71999999999989 305.1 9.400000000000006 0.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
126 2026-02-10 16:45:00 -126.6 213.71999999999989 305.1 9.400000000000006 2.0 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
127 2026-02-10 17:00:00 -126.6 213.71999999999989 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
128 2026-02-10 17:15:40 -126.6 213.8999999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 2.3999999999999986
129 2026-02-10 21:00:01 -126.6 213.8999999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
130 2026-02-11 04:02:06 -126.6 237.0299999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
131 2026-02-11 07:48:46 -126.6 237.9299999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
132 2026-02-11 08:00:00 -126.6 218.2799999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
133 2026-02-11 11:49:18 -126.6 235.7999999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
134 2026-02-11 12:27:16 -126.6 295.1599999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
135 2026-02-11 13:24:06 -126.6 304.6699999999999 305.1 9.400000000000006 2.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
136 2026-02-11 17:25:57 -126.6 304.6699999999999 305.1 9.400000000000006 3.0 -72.63000000000001 0.0 -129.39999999999998 -20.5
137 2026-02-11 19:20:00 -126.6 304.6699999999999 305.1 9.400000000000006 3.0 -72.63000000000001 0.0 -129.39999999999998 -20.5
138 2026-02-12 05:00:00 -126.6 174.6699999999999 305.1 9.400000000000006 3.0 -72.63000000000001 0.0 -129.39999999999998 -20.5
139 2026-02-12 07:00:00 -126.6 173.1699999999999 305.1 9.400000000000006 3.0 -72.63000000000001 0.0 -129.39999999999998 -20.5
140 2026-02-12 09:00:00 -126.6 14.919999999999902 305.1 9.400000000000006 3.0 -72.63000000000001 0.0 -129.39999999999998 -20.5
141 2026-02-12 17:45:00 -126.6 14.919999999999902 305.1 9.400000000000006 17.45 -72.63000000000001 0.0 -129.39999999999998 -20.5
142 2026-02-12 18:00:01 -126.6 14.919999999999902 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
143 2026-02-12 20:01:58 -126.6 43.119999999999905 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
144 2026-02-12 23:02:07 -126.6 97.1499999999999 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
145 2026-02-13 05:18:27 -126.6 105.3999999999999 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
146 2026-02-13 08:00:00 -126.6 0.9699999999998994 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
147 2026-02-13 15:42:45 -126.6 -294.7100000000001 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
148 2026-02-13 19:00:00 -126.6 -488.5700000000001 305.1 9.400000000000006 19.849999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
149 2026-02-13 21:42:00 -126.6 -488.5700000000001 305.1 9.400000000000006 28.349999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
150 2026-02-13 21:58:36 -126.6 -446.1500000000001 305.1 9.400000000000006 28.349999999999998 -72.63000000000001 0.0 -129.39999999999998 -20.5
151 2026-02-13 22:00:00 -126.6 -446.1500000000001 305.1 9.400000000000006 32.55 -72.63000000000001 0.0 -129.39999999999998 -20.5
152 2026-02-16 02:00:00 -126.6 -446.1500000000001 305.1 9.400000000000006 32.55 -72.63000000000001 -16.6 -129.39999999999998 -20.5
153 2026-02-16 05:00:00 -126.6 -579.1000000000001 305.1 9.400000000000006 32.55 -72.63000000000001 -16.6 -129.39999999999998 -20.5
154 2026-02-17 17:00:00 -49.8 -579.1000000000001 305.1 9.400000000000006 32.55 -72.63000000000001 -16.6 -129.39999999999998 -20.5
155 2026-02-17 17:45:00 -49.8 -579.1000000000001 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
156 2026-02-19 22:00:00 -49.8 -133.80000000000013 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
157 2026-02-20 07:00:00 -49.8 -201.30000000000013 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
158 2026-02-23 02:00:00 -49.8 1316.8999999999999 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
159 2026-02-24 02:00:00 -49.8 407.79999999999984 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
160 2026-02-24 04:00:00 -49.8 860.9999999999998 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
161 2026-02-24 10:01:34 -49.8 880.3799999999998 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
162 2026-02-24 14:01:01 -49.8 873.7799999999997 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
163 2026-02-24 18:00:00 -49.8 759.9899999999998 305.1 9.400000000000006 26.449999999999996 -72.63000000000001 -16.6 -129.39999999999998 -20.5
164 2026-02-24 18:15:00 -49.8 759.9899999999998 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
165 2026-02-25 05:55:01 -49.8 762.1799999999998 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
166 2026-02-25 08:00:56 -49.8 811.8899999999999 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
167 2026-02-25 16:00:00 -49.8 634.3899999999999 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
168 2026-02-25 18:07:26 -49.8 624.6399999999999 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
169 2026-02-25 23:00:03 -49.8 442.65999999999985 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
170 2026-02-26 03:00:00 -49.8 375.05999999999983 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 -16.6 -129.39999999999998 -20.5
171 2026-02-26 06:00:00 -49.8 375.05999999999983 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 106.34 -129.39999999999998 -20.5
172 2026-02-26 13:00:00 -49.8 293.0099999999998 305.1 9.400000000000006 -58.300000000000004 -72.63000000000001 106.34 -129.39999999999998 -20.5
173 2026-02-26 16:45:00 -49.8 293.0099999999998 305.1 9.400000000000006 21.699999999999996 -72.63000000000001 106.34 -129.39999999999998 -20.5
174 2026-02-26 16:46:48 -49.8 293.0099999999998 305.1 9.400000000000006 26.399999999999995 -72.63000000000001 106.34 -129.39999999999998 -20.5
175 2026-02-26 16:46:53 -49.8 293.0099999999998 305.1 9.400000000000006 52.099999999999994 -72.63000000000001 106.34 -129.39999999999998 -20.5
176 2026-02-26 16:46:56 -49.8 293.0099999999998 305.1 9.400000000000006 89.94999999999999 -72.63000000000001 106.34 -129.39999999999998 -20.5
177 2026-02-26 18:56:28 -49.8 293.0099999999998 305.1 9.400000000000006 89.94999999999999 -72.63000000000001 106.34 -129.39999999999998 -18.25
178 2026-02-26 20:45:00 -49.8 293.0099999999998 305.1 9.400000000000006 40.44999999999999 -72.63000000000001 106.34 -129.39999999999998 -18.25
179 2026-02-26 22:30:01 -49.8 293.0099999999998 305.1 9.400000000000006 3.6999999999999886 -72.63000000000001 106.34 -129.39999999999998 -18.25
180 2026-02-27 07:00:01 -49.8 292.3299999999998 305.1 9.400000000000006 3.6999999999999886 -72.63000000000001 106.34 -129.39999999999998 -18.25
181 2026-02-27 16:45:00 -49.8 292.3299999999998 305.1 9.400000000000006 5.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
182 2026-02-27 18:00:00 -49.8 292.3299999999998 305.1 9.400000000000006 13.199999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
183 2026-02-27 18:00:33 -49.8 329.3799999999998 305.1 9.400000000000006 13.199999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
184 2026-02-27 18:15:00 -49.8 329.3799999999998 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
185 2026-02-27 20:15:53 -49.8 337.0899999999998 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
186 2026-02-27 21:03:14 187.2 337.0899999999998 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
187 2026-02-27 23:01:44 187.2 377.5299999999998 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
188 2026-03-02 01:03:37 187.2 1653.3299999999997 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
189 2026-03-02 02:00:03 187.2 1747.1699999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
190 2026-03-02 06:01:54 187.2 1803.8999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
191 2026-03-02 09:01:24 187.2 1889.0999999999997 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
192 2026-03-02 09:13:03 187.2 1095.8999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
193 2026-03-02 17:00:00 187.2 1730.3999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
194 2026-03-02 18:00:30 187.2 1378.8899999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
195 2026-03-02 23:30:48 187.2 1418.6999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
196 2026-03-03 02:00:21 187.2 1442.7299999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
197 2026-03-03 05:17:20 187.2 1477.2599999999995 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
198 2026-03-03 11:00:00 187.2 530.9999999999995 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
199 2026-03-03 12:00:00 187.2 529.2599999999995 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
200 2026-03-03 13:00:18 187.2 593.6999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -18.25
201 2026-03-03 16:31:02 187.2 593.6999999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
202 2026-03-03 17:00:05 187.2 897.6599999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
203 2026-03-03 20:00:21 187.2 935.6399999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
204 2026-03-03 22:00:04 187.2 996.3299999999997 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
205 2026-03-04 18:00:00 187.2 828.2399999999997 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
206 2026-03-04 20:00:10 187.2 844.6499999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 106.34 -129.39999999999998 -98.75
207 2026-03-05 04:00:00 187.2 844.6499999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
208 2026-03-05 05:00:00 187.2 668.1899999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
209 2026-03-05 09:00:00 187.2 415.9899999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
210 2026-03-05 16:00:00 187.2 371.4299999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
211 2026-03-05 16:00:11 187.2 456.3299999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
212 2026-03-05 19:02:14 187.2 515.6099999999996 305.1 9.400000000000006 11.449999999999989 -72.63000000000001 259.51 -129.39999999999998 -98.75
213 2026-03-05 20:30:00 187.2 515.6099999999996 305.1 9.400000000000006 -1.0500000000000114 -72.63000000000001 259.51 -129.39999999999998 -98.75
214 2026-03-06 12:00:00 187.2 417.5299999999996 305.1 9.400000000000006 -1.0500000000000114 -72.63000000000001 259.51 -129.39999999999998 -98.75
215 2026-03-06 15:00:00 187.2 355.42999999999955 305.1 9.400000000000006 -1.0500000000000114 -72.63000000000001 259.51 -129.39999999999998 -98.75
216 2026-03-06 17:00:00 187.2 209.44999999999956 305.1 9.400000000000006 -1.0500000000000114 -72.63000000000001 259.51 -129.39999999999998 -98.75
217 2026-03-06 22:30:00 187.2 209.44999999999956 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
218 2026-03-09 01:01:22 187.2 288.10999999999956 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
219 2026-03-09 04:06:01 187.2 357.8299999999996 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
220 2026-03-09 05:00:00 187.2 -362.5700000000004 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
221 2026-03-09 09:00:00 187.2 -525.8900000000003 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
222 2026-03-09 12:01:35 187.2 -530.5700000000003 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
223 2026-03-09 17:00:00 599.95 -530.5700000000003 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
224 2026-03-09 17:00:25 599.95 -500.0600000000003 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
225 2026-03-10 01:01:33 599.95 -490.52000000000027 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
226 2026-03-10 05:02:32 599.95 -405.5600000000003 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
227 2026-03-10 08:00:01 599.95 -407.40000000000026 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
228 2026-03-10 09:05:27 599.95 -379.41000000000025 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
229 2026-03-10 11:03:06 599.95 -369.30000000000024 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
230 2026-03-10 17:00:17 599.95 -311.97000000000025 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
231 2026-03-10 19:03:01 599.95 -253.23000000000025 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
232 2026-03-11 07:00:00 599.95 -253.71000000000024 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
233 2026-03-11 10:00:00 599.95 299.38999999999976 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
234 2026-03-11 15:00:01 599.95 158.68999999999977 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
235 2026-03-11 16:31:01 510.95000000000005 158.68999999999977 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -98.75
236 2026-03-11 18:00:00 510.95000000000005 158.68999999999977 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -131.25
237 2026-03-12 03:09:47 510.95000000000005 155.53999999999976 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -131.25
238 2026-03-12 06:01:28 510.95000000000005 152.23999999999975 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -131.25
239 2026-03-12 11:00:00 510.95000000000005 32.05999999999975 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -131.25
240 2026-03-12 12:00:00 510.95000000000005 40.11999999999975 305.1 9.400000000000006 -71.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -131.25
241 2026-03-12 17:30:01 510.95000000000005 40.11999999999975 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -131.25
242 2026-03-12 18:46:42 510.95000000000005 102.39999999999975 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -131.25
243 2026-03-12 19:04:29 510.95000000000005 151.41999999999976 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -131.25
244 2026-03-12 21:00:02 510.95000000000005 151.41999999999976 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -174.5
245 2026-03-12 21:01:15 510.95000000000005 196.56999999999977 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -174.5
246 2026-03-12 23:01:04 510.95000000000005 216.24999999999977 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -174.5
247 2026-03-13 08:00:00 510.95000000000005 195.32999999999976 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -174.5
248 2026-03-13 18:00:14 510.95000000000005 286.34999999999974 305.1 9.400000000000006 27.19999999999999 -72.63000000000001 259.51 -129.39999999999998 -174.5
249 2026-03-13 19:30:00 510.95000000000005 286.34999999999974 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 259.51 -129.39999999999998 -174.5
250 2026-03-13 23:00:00 510.95000000000005 286.34999999999974 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
251 2026-03-13 23:00:35 510.95000000000005 330.9299999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
252 2026-03-16 03:00:15 510.95000000000005 355.52999999999975 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
253 2026-03-16 05:00:33 510.95000000000005 376.43999999999977 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
254 2026-03-16 11:00:31 510.95000000000005 392.00999999999976 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
255 2026-03-16 13:09:14 510.95000000000005 429.08999999999975 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
256 2026-03-16 14:00:00 510.95000000000005 457.3099999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 28.92999999999998 -129.39999999999998 -174.5
257 2026-03-16 15:00:00 510.95000000000005 457.3099999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -1.2600000000000229 -129.39999999999998 -174.5
258 2026-03-16 17:00:00 501.95000000000005 457.3099999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -1.2600000000000229 -129.39999999999998 -174.5
259 2026-03-17 11:00:01 501.95000000000005 457.3099999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
260 2026-03-17 14:00:00 501.95000000000005 401.4499999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
261 2026-03-17 14:08:21 501.95000000000005 421.4899999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
262 2026-03-17 19:18:11 501.95000000000005 429.28999999999974 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
263 2026-03-17 23:04:43 501.95000000000005 424.45999999999975 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
264 2026-03-18 05:00:33 501.95000000000005 418.78999999999974 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
265 2026-03-18 06:00:00 501.95000000000005 401.00999999999976 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
266 2026-03-18 07:24:05 501.95000000000005 394.76999999999975 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
267 2026-03-18 14:14:57 501.95000000000005 443.4299999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
268 2026-03-18 16:31:00 503.70000000000005 443.4299999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
269 2026-03-18 16:42:22 503.70000000000005 580.7099999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
270 2026-03-18 18:00:39 503.70000000000005 597.5699999999997 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
271 2026-03-18 22:04:29 503.70000000000005 618.3899999999998 305.1 9.400000000000006 -16.55000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
272 2026-03-18 22:45:00 503.70000000000005 618.3899999999998 305.1 9.400000000000006 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
273 2026-03-19 01:01:09 503.70000000000005 647.6999999999997 305.1 9.400000000000006 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
274 2026-03-19 05:07:38 503.70000000000005 647.6999999999997 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
275 2026-03-19 09:00:35 503.70000000000005 659.9999999999997 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
276 2026-03-19 11:00:07 503.70000000000005 761.2199999999997 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
277 2026-03-19 13:00:36 503.70000000000005 783.0299999999996 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
278 2026-03-19 16:20:36 503.70000000000005 1087.8299999999997 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
279 2026-03-19 16:31:00 1279.2 1087.8299999999997 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
280 2026-03-19 18:00:12 1279.2 1136.1899999999996 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -129.39999999999998 -174.5
281 2026-03-20 04:50:41 1279.2 1136.1899999999996 305.1 51.60000000000001 -35.05000000000001 -72.63000000000001 -142.25000000000003 -109.49999999999997 -174.5
282 2026-03-20 18:00:00 1279.2 1136.1899999999996 305.1 51.60000000000001 -186.55 -72.63000000000001 -142.25000000000003 -109.49999999999997 -174.5
283 2026-03-20 20:45:00 1279.2 1136.1899999999996 305.1 51.60000000000001 -275.05 -72.63000000000001 -142.25000000000003 -109.49999999999997 -174.5
284 2026-03-23 23:00:00 1279.2 1136.1899999999996 305.1 51.60000000000001 -275.05 -72.63000000000001 -225.91000000000003 -109.49999999999997 -174.5
285 2026-03-24 04:00:00 1279.2 1009.8699999999997 305.1 51.60000000000001 -275.05 -72.63000000000001 -225.91000000000003 -109.49999999999997 -174.5
286 2026-03-24 17:30:00 1279.2 1009.8699999999997 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -109.49999999999997 -174.5
287 2026-03-25 02:00:30 1279.2 1028.9499999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -109.49999999999997 -174.5
288 2026-03-25 04:00:04 1279.2 1065.3699999999997 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -109.49999999999997 -174.5
289 2026-03-25 04:54:18 1279.2 1065.3699999999997 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
290 2026-03-25 16:31:01 871.7 1065.3699999999997 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
291 2026-03-25 23:00:00 871.7 871.1799999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
292 2026-03-26 01:01:01 871.7 1292.4799999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
293 2026-03-26 05:00:47 871.7 1284.1699999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
294 2026-03-26 12:00:55 871.7 1305.8899999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
295 2026-03-26 13:00:00 871.7 1353.8899999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
296 2026-03-26 15:00:47 871.7 1347.1999999999996 305.1 51.60000000000001 -392.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
297 2026-03-26 17:30:00 871.7 1347.1999999999996 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
298 2026-03-26 20:00:33 871.7 1457.0299999999995 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
299 2026-03-26 23:11:44 871.7 1488.7099999999996 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
300 2026-03-27 04:00:00 871.7 1421.1099999999997 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
301 2026-03-27 04:00:03 871.7 1417.3899999999996 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
302 2026-03-27 09:00:00 871.7 1308.3699999999997 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
303 2026-03-27 14:00:12 871.7 1330.2699999999998 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
304 2026-03-27 16:31:00 1699.7 1330.2699999999998 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
305 2026-03-27 18:00:01 1699.7 1054.2399999999998 305.1 51.60000000000001 -391.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
306 2026-03-27 20:30:01 1699.7 1054.2399999999998 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -174.5
307 2026-03-27 21:00:00 1699.7 1054.2399999999998 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
308 2026-03-30 03:00:01 1699.7 828.9099999999997 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
309 2026-03-30 04:00:13 1699.7 70.40999999999974 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
310 2026-03-30 05:00:00 1699.7 -33.84000000000026 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
311 2026-03-30 09:00:03 1699.7 33.29999999999974 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
312 2026-03-30 10:00:00 1699.7 32.679999999999744 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
313 2026-03-30 12:06:36 1699.7 44.169999999999746 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
314 2026-03-30 15:00:29 1699.7 113.01999999999974 305.1 51.60000000000001 -477.05 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
315 2026-03-30 22:30:00 1699.7 113.01999999999974 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
316 2026-03-30 23:00:00 1699.7 37.119999999999735 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -102.99999999999997 -117.5
317 2026-03-31 04:50:01 1699.7 37.119999999999735 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
318 2026-03-31 05:00:17 1699.7 129.66999999999973 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
319 2026-03-31 07:00:00 1699.7 129.30999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
320 2026-03-31 09:00:13 1699.7 122.34999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
321 2026-03-31 11:02:00 1699.7 133.98999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
322 2026-03-31 15:14:01 1699.7 167.58999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
323 2026-03-31 17:09:58 1699.7 253.86999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
324 2026-03-31 21:10:02 1699.7 253.86999999999972 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
325 2026-03-31 22:08:48 1699.7 448.26999999999975 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
326 2026-04-01 03:00:31 1699.7 475.2399999999998 305.1 51.60000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
327 2026-04-01 08:00:00 1699.7 475.2399999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -94.59999999999997 -117.5
328 2026-04-02 00:01:00 1699.7 475.2399999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
329 2026-04-02 08:00:00 1699.7 1736.6399999999999 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
330 2026-04-02 18:00:01 1699.7 1470.8999999999999 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
331 2026-04-06 03:01:14 1699.7 1538.61 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
332 2026-04-06 08:00:00 1699.7 1426.62 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
333 2026-04-06 12:50:29 1699.7 1448.79 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
334 2026-04-06 17:00:00 1699.7 1295.09 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -117.5
335 2026-04-06 18:00:00 1699.7 1295.09 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -188.5
336 2026-04-06 18:40:05 1699.7 1295.09 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -188.5
337 2026-04-06 20:00:00 1699.7 1195.1899999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -188.5
338 2026-04-06 20:00:01 2471.7 1195.1899999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -225.91000000000003 -138.49999999999997 -188.5
339 2026-04-07 01:00:00 2471.7 1195.1899999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -113.86000000000003 -138.49999999999997 -188.5
340 2026-04-07 08:00:01 2471.7 1094.1499999999999 305.1 99.80000000000001 -642.55 -72.63000000000001 -113.86000000000003 -138.49999999999997 -188.5
341 2026-04-07 14:00:00 2471.7 998.3899999999999 305.1 99.80000000000001 -642.55 -72.63000000000001 -113.86000000000003 -138.49999999999997 -188.5
342 2026-04-07 16:00:00 2471.7 684.1899999999998 305.1 99.80000000000001 -642.55 -72.63000000000001 -113.86000000000003 -138.49999999999997 -188.5
343 2026-04-07 17:30:00 2471.7 684.1899999999998 305.1 99.80000000000001 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -188.5
344 2026-04-07 18:00:01 2471.7 684.1899999999998 305.1 99.80000000000001 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
345 2026-04-07 21:00:00 2471.7 555.0999999999998 305.1 99.80000000000001 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
346 2026-04-08 01:01:06 2471.7 678.7299999999998 305.1 99.80000000000001 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
347 2026-04-08 03:00:07 2471.7 712.4799999999998 305.1 99.80000000000001 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
348 2026-04-08 08:00:00 2471.7 712.4799999999998 305.1 -72.39999999999998 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
349 2026-04-08 09:08:23 2471.7 730.9599999999998 305.1 -72.39999999999998 -264.04999999999995 -72.63000000000001 -113.86000000000003 -138.49999999999997 -356.5
350 2026-04-08 10:00:00 2471.7 730.9599999999998 305.1 -72.39999999999998 -264.04999999999995 -72.63000000000001 -96.76000000000002 -138.49999999999997 -356.5
351 2026-04-08 16:31:00 2471.7 730.9599999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -138.49999999999997 -356.5
352 2026-04-08 18:20:00 2471.7 730.9599999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -138.49999999999997 -356.5
353 2026-04-08 20:00:00 2471.7 1312.6599999999999 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -138.49999999999997 -356.5
354 2026-04-08 21:00:01 2471.7 1056.0099999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -138.49999999999997 -356.5
355 2026-04-09 00:01:00 2471.7 1056.0099999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -356.5
356 2026-04-09 13:00:01 2471.7 978.8799999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -356.5
357 2026-04-09 16:31:01 2471.7 978.8799999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
358 2026-04-09 17:00:38 2471.7 995.0199999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
359 2026-04-09 19:13:39 2471.7 1057.1799999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
360 2026-04-09 21:01:21 2471.7 1073.4099999999999 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
361 2026-04-10 01:01:52 2471.7 1075.2699999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
362 2026-04-10 05:00:02 2471.7 1155.7699999999998 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
363 2026-04-10 05:00:30 2471.7 1149.5899999999997 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
364 2026-04-10 17:00:01 2471.7 1149.9499999999996 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -953.0
365 2026-04-10 18:36:21 2471.7 1149.9499999999996 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
366 2026-04-10 21:00:00 2471.7 985.5499999999996 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
367 2026-04-13 01:01:02 2471.7 641.7499999999995 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
368 2026-04-13 01:01:03 2471.7 1087.5699999999995 305.1 -72.39999999999998 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
369 2026-04-13 07:33:34 2471.7 1087.5699999999995 305.1 78.08000000000001 198.95000000000005 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
370 2026-04-13 18:00:01 2471.7 1087.5699999999995 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
371 2026-04-13 20:00:00 2352.5699999999997 787.4099999999994 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
372 2026-04-14 04:00:02 2352.5699999999997 813.0899999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
373 2026-04-14 06:00:57 2352.5699999999997 833.8799999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
374 2026-04-14 08:02:23 2352.5699999999997 847.8799999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
375 2026-04-14 09:00:04 2352.5699999999997 844.2399999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -96.76000000000002 -211.49999999999997 -1042.0
376 2026-04-14 09:00:07 2352.5699999999997 844.2399999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 0.9899999999999807 -211.49999999999997 -1042.0
377 2026-04-14 12:05:23 2352.5699999999997 851.1599999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 0.9899999999999807 -211.49999999999997 -1042.0
378 2026-04-14 18:00:36 2352.5699999999997 939.3599999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 0.9899999999999807 -211.49999999999997 -1042.0
379 2026-04-14 21:21:16 2352.5699999999997 1039.9199999999994 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 0.9899999999999807 -211.49999999999997 -1042.0
380 2026-04-14 23:00:00 2352.5699999999997 1039.9199999999994 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -211.49999999999997 -1042.0
381 2026-04-14 23:04:34 2352.5699999999997 1068.0699999999995 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -211.49999999999997 -1042.0
382 2026-04-15 00:01:00 2352.5699999999997 1068.0699999999995 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -264.84999999999997 -1042.0
383 2026-04-15 05:15:57 2352.5699999999997 1086.4199999999994 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -264.84999999999997 -1042.0
384 2026-04-15 08:30:19 2352.5699999999997 1076.7199999999993 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -264.84999999999997 -1042.0
385 2026-04-15 12:00:00 2352.5699999999997 1796.5999999999995 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -264.84999999999997 -1042.0
386 2026-04-15 14:00:00 2352.5699999999997 1721.9599999999994 305.1 78.08000000000001 -42.539999999999964 -72.63000000000001 -203.41000000000003 -264.84999999999997 -1042.0
Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

@@ -1,102 +0,0 @@
close_time,daily_pnl,cum_pnl
2026-01-05,85.61999999999999,85.61999999999999
2026-01-06,-61.83,23.789999999999992
2026-01-07,-64.69000000000001,-40.90000000000002
2026-01-08,-48.95,-89.85000000000002
2026-01-09,-0.17,-90.02000000000002
2026-01-10,0.0,-90.02000000000002
2026-01-11,0.0,-90.02000000000002
2026-01-12,380.8,290.78
2026-01-13,-134.17,156.60999999999999
2026-01-14,65.9,222.51
2026-01-15,-130.47,92.03999999999999
2026-01-16,-10.7,81.33999999999999
2026-01-17,0.0,81.33999999999999
2026-01-18,0.0,81.33999999999999
2026-01-19,-182.78,-101.44000000000001
2026-01-20,86.51,-14.930000000000007
2026-01-21,16.120000000000005,1.1899999999999977
2026-01-22,-243.25,-242.06
2026-01-23,-67.38,-309.44
2026-01-24,0.0,-309.44
2026-01-25,0.0,-309.44
2026-01-26,465.11,155.67000000000002
2026-01-27,-1.4299999999999784,154.24000000000004
2026-01-28,580.72,734.96
2026-01-29,-655.47,79.49000000000001
2026-01-30,-326.9,-247.40999999999997
2026-01-31,0.0,-247.40999999999997
2026-02-01,0.0,-247.40999999999997
2026-02-02,0.0,-247.40999999999997
2026-02-03,447.03,199.62
2026-02-04,533.68,733.3
2026-02-05,-354.43,378.86999999999995
2026-02-06,-563.19,-184.3200000000001
2026-02-07,0.0,-184.3200000000001
2026-02-08,0.0,-184.3200000000001
2026-02-09,241.38,57.05999999999989
2026-02-10,123.99000000000001,181.0499999999999
2026-02-11,111.97,293.01999999999987
2026-02-12,-190.67000000000002,102.34999999999985
2026-02-13,-530.6,-428.25000000000017
2026-02-14,0.0,-428.25000000000017
2026-02-15,0.0,-428.25000000000017
2026-02-16,-149.54999999999998,-577.8000000000002
2026-02-17,70.7,-507.1000000000002
2026-02-18,0.0,-507.1000000000002
2026-02-19,445.3,-61.80000000000018
2026-02-20,-67.5,-129.30000000000018
2026-02-21,0.0,-129.30000000000018
2026-02-22,0.0,-129.30000000000018
2026-02-23,1518.2,1388.8999999999999
2026-02-24,-656.6600000000001,732.2399999999998
2026-02-25,-317.33,414.9099999999998
2026-02-26,37.540000000000006,452.4499999999998
2026-02-27,329.27,781.7199999999998
2026-02-28,0.0,781.7199999999998
2026-03-01,0.0,781.7199999999998
2026-03-02,1041.1699999999998,1822.8899999999996
2026-03-03,-502.8700000000001,1320.0199999999995
2026-03-04,-151.68,1168.3399999999995
2026-03-05,-188.37,979.9699999999995
2026-03-06,-376.65999999999997,603.3099999999995
2026-03-07,0.0,603.3099999999995
2026-03-08,0.0,603.3099999999995
2026-03-09,-296.76,306.5499999999995
2026-03-10,246.82999999999998,553.3799999999994
2026-03-11,290.42,843.7999999999995
2026-03-12,113.06,956.8599999999994
2026-03-13,-159.65000000000003,797.2099999999994
2026-03-14,0.0,797.2099999999994
2026-03-15,0.0,797.2099999999994
2026-03-16,87.19,884.3999999999994
2026-03-17,-173.84,710.5599999999994
2026-03-18,177.18,887.7399999999993
2026-03-19,1335.5,2223.2399999999993
2026-03-20,-220.1,2003.1399999999994
2026-03-21,0.0,2003.1399999999994
2026-03-22,0.0,2003.1399999999994
2026-03-23,-83.66,1919.4799999999993
2026-03-24,-243.82,1675.6599999999994
2026-03-25,-539.69,1135.9699999999993
2026-03-26,618.53,1754.4999999999993
2026-03-27,365.03,2119.5299999999993
2026-03-28,0.0,2119.5299999999993
2026-03-29,0.0,2119.5299999999993
2026-03-30,-1182.6200000000001,936.9099999999992
2026-03-31,425.55,1362.4599999999991
2026-04-01,75.17,1437.6299999999992
2026-04-02,951.76,2389.3899999999994
2026-04-03,0.0,2389.3899999999994
2026-04-04,0.0,2389.3899999999994
2026-04-05,0.0,2389.3899999999994
2026-04-06,421.78999999999996,2811.1799999999994
2026-04-07,-317.53999999999996,2493.6399999999994
2026-04-08,798.5600000000001,3292.1999999999994
2026-04-09,-652.1,2640.0999999999995
2026-04-10,-176.86,2463.2399999999993
2026-04-11,0.0,2463.2399999999993
2026-04-12,0.0,2463.2399999999993
2026-04-13,-408.28000000000003,2054.959999999999
2026-04-14,174.01000000000002,2228.9699999999993
2026-04-15,600.54,2829.5099999999993
1 close_time daily_pnl cum_pnl
2 2026-01-05 85.61999999999999 85.61999999999999
3 2026-01-06 -61.83 23.789999999999992
4 2026-01-07 -64.69000000000001 -40.90000000000002
5 2026-01-08 -48.95 -89.85000000000002
6 2026-01-09 -0.17 -90.02000000000002
7 2026-01-10 0.0 -90.02000000000002
8 2026-01-11 0.0 -90.02000000000002
9 2026-01-12 380.8 290.78
10 2026-01-13 -134.17 156.60999999999999
11 2026-01-14 65.9 222.51
12 2026-01-15 -130.47 92.03999999999999
13 2026-01-16 -10.7 81.33999999999999
14 2026-01-17 0.0 81.33999999999999
15 2026-01-18 0.0 81.33999999999999
16 2026-01-19 -182.78 -101.44000000000001
17 2026-01-20 86.51 -14.930000000000007
18 2026-01-21 16.120000000000005 1.1899999999999977
19 2026-01-22 -243.25 -242.06
20 2026-01-23 -67.38 -309.44
21 2026-01-24 0.0 -309.44
22 2026-01-25 0.0 -309.44
23 2026-01-26 465.11 155.67000000000002
24 2026-01-27 -1.4299999999999784 154.24000000000004
25 2026-01-28 580.72 734.96
26 2026-01-29 -655.47 79.49000000000001
27 2026-01-30 -326.9 -247.40999999999997
28 2026-01-31 0.0 -247.40999999999997
29 2026-02-01 0.0 -247.40999999999997
30 2026-02-02 0.0 -247.40999999999997
31 2026-02-03 447.03 199.62
32 2026-02-04 533.68 733.3
33 2026-02-05 -354.43 378.86999999999995
34 2026-02-06 -563.19 -184.3200000000001
35 2026-02-07 0.0 -184.3200000000001
36 2026-02-08 0.0 -184.3200000000001
37 2026-02-09 241.38 57.05999999999989
38 2026-02-10 123.99000000000001 181.0499999999999
39 2026-02-11 111.97 293.01999999999987
40 2026-02-12 -190.67000000000002 102.34999999999985
41 2026-02-13 -530.6 -428.25000000000017
42 2026-02-14 0.0 -428.25000000000017
43 2026-02-15 0.0 -428.25000000000017
44 2026-02-16 -149.54999999999998 -577.8000000000002
45 2026-02-17 70.7 -507.1000000000002
46 2026-02-18 0.0 -507.1000000000002
47 2026-02-19 445.3 -61.80000000000018
48 2026-02-20 -67.5 -129.30000000000018
49 2026-02-21 0.0 -129.30000000000018
50 2026-02-22 0.0 -129.30000000000018
51 2026-02-23 1518.2 1388.8999999999999
52 2026-02-24 -656.6600000000001 732.2399999999998
53 2026-02-25 -317.33 414.9099999999998
54 2026-02-26 37.540000000000006 452.4499999999998
55 2026-02-27 329.27 781.7199999999998
56 2026-02-28 0.0 781.7199999999998
57 2026-03-01 0.0 781.7199999999998
58 2026-03-02 1041.1699999999998 1822.8899999999996
59 2026-03-03 -502.8700000000001 1320.0199999999995
60 2026-03-04 -151.68 1168.3399999999995
61 2026-03-05 -188.37 979.9699999999995
62 2026-03-06 -376.65999999999997 603.3099999999995
63 2026-03-07 0.0 603.3099999999995
64 2026-03-08 0.0 603.3099999999995
65 2026-03-09 -296.76 306.5499999999995
66 2026-03-10 246.82999999999998 553.3799999999994
67 2026-03-11 290.42 843.7999999999995
68 2026-03-12 113.06 956.8599999999994
69 2026-03-13 -159.65000000000003 797.2099999999994
70 2026-03-14 0.0 797.2099999999994
71 2026-03-15 0.0 797.2099999999994
72 2026-03-16 87.19 884.3999999999994
73 2026-03-17 -173.84 710.5599999999994
74 2026-03-18 177.18 887.7399999999993
75 2026-03-19 1335.5 2223.2399999999993
76 2026-03-20 -220.1 2003.1399999999994
77 2026-03-21 0.0 2003.1399999999994
78 2026-03-22 0.0 2003.1399999999994
79 2026-03-23 -83.66 1919.4799999999993
80 2026-03-24 -243.82 1675.6599999999994
81 2026-03-25 -539.69 1135.9699999999993
82 2026-03-26 618.53 1754.4999999999993
83 2026-03-27 365.03 2119.5299999999993
84 2026-03-28 0.0 2119.5299999999993
85 2026-03-29 0.0 2119.5299999999993
86 2026-03-30 -1182.6200000000001 936.9099999999992
87 2026-03-31 425.55 1362.4599999999991
88 2026-04-01 75.17 1437.6299999999992
89 2026-04-02 951.76 2389.3899999999994
90 2026-04-03 0.0 2389.3899999999994
91 2026-04-04 0.0 2389.3899999999994
92 2026-04-05 0.0 2389.3899999999994
93 2026-04-06 421.78999999999996 2811.1799999999994
94 2026-04-07 -317.53999999999996 2493.6399999999994
95 2026-04-08 798.5600000000001 3292.1999999999994
96 2026-04-09 -652.1 2640.0999999999995
97 2026-04-10 -176.86 2463.2399999999993
98 2026-04-11 0.0 2463.2399999999993
99 2026-04-12 0.0 2463.2399999999993
100 2026-04-13 -408.28000000000003 2054.959999999999
101 2026-04-14 174.01000000000002 2228.9699999999993
102 2026-04-15 600.54 2829.5099999999993
Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

@@ -1,75 +0,0 @@
# Pepperstone US - Symbol Setup Guide
## Finding Correct Symbol Names in MetaTrader 5
### Step-by-Step Instructions:
1. **Open Market Watch Window**
- Press `Ctrl+M` or go to `View > Market Watch`
2. **Show All Symbols**
- Right-click in the Market Watch window
- Select `Show All` or `Symbols`
- This shows all available symbols from your broker
3. **Search for Your Symbols**
- Use the search box in the Market Watch window
- Search for: "AAPL", "MSFT", "NVDA", "TSLA", "BTCUSD", "XAUUSD"
4. **Note the Exact Symbol Name**
- The symbol name shown in Market Watch is what you need to use
- Common formats for Pepperstone US:
- Stocks: `AAPL.US`, `MSFT.US`, `NVDA.US`, `TSLA.US`
- Or: `NASDAQ:AAPL`, `NASDAQ:MSFT`, etc.
- Or: Just `AAPL`, `MSFT`, etc. (if available)
5. **Add to Market Watch**
- Double-click the symbol to add it to your Market Watch
- Or right-click and select `Show`
6. **Update EA Inputs**
- Open the EA inputs in MetaTrader 5
- Update each symbol parameter with the exact name from Market Watch
## Common Pepperstone US Symbol Formats
### US Stocks:
- **Apple**: `AAPL.US` or `NASDAQ:AAPL` or `AAPL`
- **Microsoft**: `MSFT.US` or `NASDAQ:MSFT` or `MSFT`
- **NVIDIA**: `NVDA.US` or `NASDAQ:NVDA` or `NVDA`
- **Tesla**: `TSLA.US` or `NASDAQ:TSLA` or `TSLA`
### Cryptocurrencies:
- **Bitcoin**: `BTCUSD` or `BTC/USD` or `BTCUSD.c`
### Precious Metals:
- **Gold**: `XAUUSD` or `GOLD` or `XAU/USD`
## Important Notes:
1. **Symbol Names are Case-Sensitive**: Use exact capitalization
2. **Add Symbols to Market Watch**: Symbols must be in Market Watch for the EA to access them
3. **Check Trading Hours**: US stocks trade during US market hours (9:30 AM - 4:00 PM ET)
4. **CFD vs Stock**: Pepperstone offers CFDs on stocks, not actual stocks
5. **Spread**: Check the spread for each symbol - some may have wider spreads
## Troubleshooting:
### If Symbol Not Found:
1. Check if you're connected to Pepperstone US server
2. Verify your account type supports the symbol
3. Contact Pepperstone support for symbol availability
4. Check if symbol requires special account permissions
### If EA Shows "Symbol Not Available":
1. Make sure symbol is added to Market Watch
2. Verify symbol name matches exactly (including dots, colons, etc.)
3. Check broker connection status
4. Try different symbol format variations
## Testing Symbols:
You can test if a symbol works by:
1. Opening a chart with that symbol
2. If chart opens successfully, the symbol name is correct
3. Use that exact symbol name in the EA inputs
View File
@@ -0,0 +1,387 @@
//+------------------------------------------------------------------+
//| RSIConsolidationStrategy.mqh |
//| Ported from cluster-0/RSIConsolidation/RSIConsolidation.mq5 |
//+------------------------------------------------------------------+
#ifndef RSI_CONSOLIDATION_STRATEGY_MQH
#define RSI_CONSOLIDATION_STRATEGY_MQH
struct RSIConsolidationData
{
string symbol;
bool isInitialized;
CTrade trade;
ENUM_TIMEFRAMES signalTF;
bool entryOnNewBarOnly;
int adxPeriod;
double adxMax;
bool useATRRatioFilter;
int atrPeriod;
int atrSmaPeriod;
double atrRatioMax;
bool useFlatEMAFilter;
int emaFast;
int emaSlow;
double emaSeparationMaxPct;
int rsiPeriod;
ENUM_APPLIED_PRICE rsiPrice;
double rsiOversold;
double rsiOverbought;
bool useRSIMeanExit;
double rsiExitLong;
double rsiExitShort;
double slAtrMult;
double tpAtrMult;
int maxBarsInTrade;
ulong magic;
int slippage;
int maxSpreadPoints;
int h_rsi;
int h_adx;
int h_atr;
int h_ema_fast;
int h_ema_slow;
datetime lastBar;
};
bool RCO_Copy1(const int handle, double &v)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(handle, 0, 0, 1, b) < 1)
return false;
v = b[0];
return true;
}
bool RCO_RsiBuffers(RSIConsolidationData &d, double &cur, double &prev, double &twoAgo)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(d.h_rsi, 0, 0, 3, b) < 3)
return false;
cur = b[0];
prev = b[1];
twoAgo = b[2];
return true;
}
double RCO_NormalizeVolume(const string sym, double vol)
{
double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
if(step > 0.0)
vol = MathFloor(vol / step) * step;
if(vol < minLot)
vol = minLot;
if(vol > maxLot)
vol = maxLot;
return vol;
}
int RCO_CurrentSpreadPoints(const string sym)
{
long spread = 0;
if(!SymbolInfoInteger(sym, SYMBOL_SPREAD, spread))
return 999999;
return (int)spread;
}
double RCO_MinStopsDistancePrice(const string sym)
{
long lvl = 0;
if(!SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL, lvl))
return 0;
double pt = SymbolInfoDouble(sym, SYMBOL_POINT);
if(pt <= 0)
return 0;
return (double)lvl * pt;
}
bool RCO_RegimeIsConsolidation(RSIConsolidationData &d)
{
double adx = 0;
if(!RCO_Copy1(d.h_adx, adx))
return false;
if(adx >= d.adxMax)
return false;
if(d.useATRRatioFilter)
{
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, d.atrSmaPeriod + 1, atrArr) < d.atrSmaPeriod + 1)
return false;
double sum = 0;
for(int i = 1; i <= d.atrSmaPeriod; i++)
sum += atrArr[i];
double smaAtr = sum / (double)d.atrSmaPeriod;
if(smaAtr <= 0.0)
return false;
double ratio = atrArr[0] / smaAtr;
if(ratio > d.atrRatioMax)
return false;
}
if(d.useFlatEMAFilter)
{
double ef[], es[];
ArraySetAsSeries(ef, true);
ArraySetAsSeries(es, true);
if(CopyBuffer(d.h_ema_fast, 0, 0, 1, ef) < 1)
return false;
if(CopyBuffer(d.h_ema_slow, 0, 0, 1, es) < 1)
return false;
double c = SymbolInfoDouble(d.symbol, SYMBOL_BID);
if(c <= 0)
return false;
double sep = MathAbs(ef[0] - es[0]) / c * 100.0;
if(sep > d.emaSeparationMaxPct)
return false;
}
return true;
}
bool RCO_EntryBuyCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo <= d.rsiOversold && prev > d.rsiOversold);
}
bool RCO_EntrySellCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo >= d.rsiOverbought && prev < d.rsiOverbought);
}
void RCO_TryCloseByRSI(RSIConsolidationData &d, const ENUM_POSITION_TYPE typ, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
if(!d.useRSIMeanExit)
return;
if(typ == POSITION_TYPE_BUY && rsi >= d.rsiExitLong)
d.trade.PositionClose(tk);
else if(typ == POSITION_TYPE_SELL && rsi <= d.rsiExitShort)
d.trade.PositionClose(tk);
}
void RCO_ManageOpenPosition(RSIConsolidationData &d, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
ENUM_POSITION_TYPE typ = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openT = (datetime)PositionGetInteger(POSITION_TIME);
int barsAgo = iBarShift(d.symbol, d.signalTF, openT, false);
if(barsAgo >= 0 && barsAgo >= d.maxBarsInTrade)
{
d.trade.PositionClose(tk);
return;
}
RCO_TryCloseByRSI(d, typ, rsi);
}
bool InitRSIConsolidation(RSIConsolidationData &d,
const string inpSymbol,
const ENUM_TIMEFRAMES signalTF,
const bool entryOnNewBarOnly,
const int adxPeriod,
const double adxMax,
const bool useATRRatioFilter,
const int atrPeriod,
const int atrSmaPeriod,
const double atrRatioMax,
const bool useFlatEMAFilter,
const int emaFast,
const int emaSlow,
const double emaSeparationMaxPct,
const int rsiPeriod,
const ENUM_APPLIED_PRICE rsiPrice,
const double rsiOversold,
const double rsiOverbought,
const bool useRSIMeanExit,
const double rsiExitLong,
const double rsiExitShort,
const double slAtrMult,
const double tpAtrMult,
const int maxBarsInTrade,
const ulong magic,
const int slippage,
const int maxSpreadPoints)
{
d.isInitialized = false;
d.symbol = inpSymbol;
StringTrimLeft(d.symbol);
StringTrimRight(d.symbol);
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.signalTF = signalTF;
d.entryOnNewBarOnly = entryOnNewBarOnly;
d.adxPeriod = adxPeriod;
d.adxMax = adxMax;
d.useATRRatioFilter = useATRRatioFilter;
d.atrPeriod = atrPeriod;
d.atrSmaPeriod = atrSmaPeriod;
d.atrRatioMax = atrRatioMax;
d.useFlatEMAFilter = useFlatEMAFilter;
d.emaFast = emaFast;
d.emaSlow = emaSlow;
d.emaSeparationMaxPct = emaSeparationMaxPct;
d.rsiPeriod = rsiPeriod;
d.rsiPrice = rsiPrice;
d.rsiOversold = rsiOversold;
d.rsiOverbought = rsiOverbought;
d.useRSIMeanExit = useRSIMeanExit;
d.rsiExitLong = rsiExitLong;
d.rsiExitShort = rsiExitShort;
d.slAtrMult = slAtrMult;
d.tpAtrMult = tpAtrMult;
d.maxBarsInTrade = maxBarsInTrade;
d.magic = magic;
d.slippage = slippage;
d.maxSpreadPoints = maxSpreadPoints;
d.lastBar = 0;
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
if(!SymbolSelect(d.symbol, true))
{
Print("RSIConsolidation: SymbolSelect failed: ", d.symbol);
return false;
}
d.trade.SetExpertMagicNumber((long)d.magic);
d.trade.SetDeviationInPoints(d.slippage);
d.trade.SetTypeFillingBySymbol(d.symbol);
d.h_rsi = iRSI(d.symbol, d.signalTF, d.rsiPeriod, d.rsiPrice);
d.h_adx = iADX(d.symbol, d.signalTF, d.adxPeriod);
d.h_atr = iATR(d.symbol, d.signalTF, d.atrPeriod);
d.h_ema_fast = iMA(d.symbol, d.signalTF, d.emaFast, 0, MODE_EMA, PRICE_CLOSE);
d.h_ema_slow = iMA(d.symbol, d.signalTF, d.emaSlow, 0, MODE_EMA, PRICE_CLOSE);
if(d.h_rsi == INVALID_HANDLE || d.h_adx == INVALID_HANDLE || d.h_atr == INVALID_HANDLE
|| d.h_ema_fast == INVALID_HANDLE || d.h_ema_slow == INVALID_HANDLE)
{
Print("RSIConsolidation: indicator init failed");
DeinitRSIConsolidation(d);
return false;
}
d.isInitialized = true;
Print("RSIConsolidation: symbol=", d.symbol, " TF=", EnumToString(d.signalTF));
return true;
}
void DeinitRSIConsolidation(RSIConsolidationData &d)
{
if(d.h_rsi != INVALID_HANDLE)
IndicatorRelease(d.h_rsi);
if(d.h_adx != INVALID_HANDLE)
IndicatorRelease(d.h_adx);
if(d.h_atr != INVALID_HANDLE)
IndicatorRelease(d.h_atr);
if(d.h_ema_fast != INVALID_HANDLE)
IndicatorRelease(d.h_ema_fast);
if(d.h_ema_slow != INVALID_HANDLE)
IndicatorRelease(d.h_ema_slow);
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
}
bool RCO_EnoughHistory(RSIConsolidationData &d)
{
int need = MathMax(d.rsiPeriod + 3, MathMax(d.adxPeriod + 2, d.atrSmaPeriod + 3));
if(Bars(d.symbol, d.signalTF) < need)
return false;
return true;
}
void ProcessRSIConsolidation(RSIConsolidationData &d, const double lots)
{
if(!d.isInitialized)
return;
if(!RCO_EnoughHistory(d))
return;
if(d.maxSpreadPoints > 0 && RCO_CurrentSpreadPoints(d.symbol) > d.maxSpreadPoints)
return;
double rsi, rsiPrev, rsi2;
if(!RCO_RsiBuffers(d, rsi, rsiPrev, rsi2))
return;
datetime barTime = iTime(d.symbol, d.signalTF, 0);
bool isNew = (barTime != d.lastBar);
if(PositionExistsByMagic(d.symbol, d.magic))
{
RCO_ManageOpenPosition(d, rsi);
if(isNew)
d.lastBar = barTime;
return;
}
if(d.entryOnNewBarOnly && !isNew)
return;
d.lastBar = barTime;
if(!RCO_RegimeIsConsolidation(d))
return;
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, 1, atrArr) < 1)
return;
double atr = atrArr[0];
int dig = (int)SymbolInfoInteger(d.symbol, SYMBOL_DIGITS);
double slDist = atr * d.slAtrMult;
double tpDist = atr * d.tpAtrMult;
double minD = RCO_MinStopsDistancePrice(d.symbol);
if(slDist < minD)
slDist = minD;
if(tpDist < minD)
tpDist = minD;
double vol = RCO_NormalizeVolume(d.symbol, lots);
if(RCO_EntryBuyCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, true))
return;
double ask = SymbolInfoDouble(d.symbol, SYMBOL_ASK);
double sl = ask - slDist;
double tp = ask + tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Buy(vol, d.symbol, ask, sl, tp, "RSIConsolidation BUY"))
Print("RSIConsolidation BUY failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
else if(RCO_EntrySellCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, false))
return;
double bid = SymbolInfoDouble(d.symbol, SYMBOL_BID);
double sl = bid + slDist;
double tp = bid - tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Sell(vol, d.symbol, bid, sl, tp, "RSIConsolidation SELL"))
Print("RSIConsolidation SELL failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
}
#endif // RSI_CONSOLIDATION_STRATEGY_MQH
@@ -20,6 +20,23 @@ bool WeekDays_Check(datetime aTime)
return(rcData.WeekDays[stm.day_of_week]);
}
bool RC_HourInWindow(const int h, const int beginRaw, const int endRaw)
{
const int b = beginRaw % 24;
const int e = endRaw % 24;
if(b == e)
return false;
if(b < e)
return (h >= b && h < e);
return (h >= b || h < e);
}
bool RC_TradingHoursAllow(const int currentHour)
{
return RC_HourInWindow(currentHour, RC_tradingHourOneBegin, RC_tradingHourOneEnd)
|| RC_HourInWindow(currentHour, RC_tradingHourTwoBegin, RC_tradingHourTwoEnd);
}
int TimeHour(datetime when = 0)
{
if(when == 0) when = TimeCurrent();
@@ -151,8 +168,7 @@ void ProcessRSICrossOverReversal(string symbol)
return;
}
if(!((currentHour < RC_tradingHourOneEnd && currentHour > RC_tradingHourOneBegin) ||
(currentHour < RC_tradingHourTwoEnd && currentHour > RC_tradingHourTwoBegin)))
if(!RC_TradingHoursAllow(currentHour))
{
Close_Position_MN(RC_MagicNumber);
return;
@@ -173,7 +189,7 @@ void ProcessRSICrossOverReversal(string symbol)
double previousEMA = ema[1];
double emaSlope = (currentEMA - previousEMA) * 100;
double closeCurr = iClose(Symbol(), Period(), 0);
const double closeCurr = iClose(rcData.symbol, RC_TimeFrame1, 0);
double priceToEmaDistance = (closeCurr - currentEMA) * 10;
bool isBuyPosition = false;
@@ -211,10 +227,10 @@ void ProcessRSICrossOverReversal(string symbol)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
return;
}
if(currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
if(!isTrendStrong &&
currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
!isSellPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -223,8 +239,9 @@ void ProcessRSICrossOverReversal(string symbol)
rcData.lastTradeTime = currentTime;
}
}
if(currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
if(!isTrendStrong &&
currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
!isBuyPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -22,6 +22,104 @@ struct RSIScalpingData {
int bars_against_count;
};
void ClosePosition(RSIScalpingData& data, int MagicNumber);
double RS_ATRPriceOnTF(const string symbol, const ENUM_TIMEFRAMES tf, const int period)
{
if(period < 1)
return 0.0;
MqlRates rates[];
const int need = period + 2;
if(CopyRates(symbol, tf, 0, need, rates) < need)
return 0.0;
ArraySetAsSeries(rates, true);
double sum = 0.0;
for(int i = 1; i <= period; i++)
{
const double hl = rates[i].high - rates[i].low;
const double hc = MathAbs(rates[i].high - rates[i + 1].close);
const double lc = MathAbs(rates[i].low - rates[i + 1].close);
sum += MathMax(hl, MathMax(hc, lc));
}
return sum / (double)period;
}
int RS_CountReversalEscapeSigns(RSIScalpingData& data, const ENUM_TIMEFRAMES tf,
const ENUM_POSITION_TYPE ptype, const double atr,
const double adverseAtrMult, const double rsiVelocity,
const double bodyAtrMult)
{
if(atr <= 0.0)
return 0;
const double entry = PositionGetDouble(POSITION_PRICE_OPEN);
const double bid = SymbolInfoDouble(data.symbol, SYMBOL_BID);
const double ask = SymbolInfoDouble(data.symbol, SYMBOL_ASK);
int signs = 0;
if(ptype == POSITION_TYPE_BUY)
{
if(entry - bid >= adverseAtrMult * atr)
signs++;
if(data.rsi_prev - data.rsi_current >= rsiVelocity)
signs++;
}
else if(ptype == POSITION_TYPE_SELL)
{
if(ask - entry >= adverseAtrMult * atr)
signs++;
if(data.rsi_current - data.rsi_prev >= rsiVelocity)
signs++;
}
else
return 0;
MqlRates r[];
if(CopyRates(data.symbol, tf, 0, 4, r) >= 4)
{
ArraySetAsSeries(r, true);
const double body = MathAbs(r[1].close - r[1].open);
if(body >= bodyAtrMult * atr)
{
if(ptype == POSITION_TYPE_BUY && r[1].close < r[1].open)
signs++;
else if(ptype == POSITION_TYPE_SELL && r[1].close > r[1].open)
signs++;
}
if(ptype == POSITION_TYPE_BUY)
{
if(r[1].close < r[2].close && r[2].close < r[3].close)
signs++;
}
else
{
if(r[1].close > r[2].close && r[2].close > r[3].close)
signs++;
}
}
return signs;
}
void RS_TryReversalEscape(RSIScalpingData& data, const ENUM_TIMEFRAMES tf, const int MagicNumber,
const int atrPeriod, const double adverseAtrMult, const int signsRequired,
const double rsiVelocity, const double bodyAtrMult)
{
if(!PositionSelectByMagic(data.symbol, (ulong)MagicNumber))
return;
const ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
const double atr = RS_ATRPriceOnTF(data.symbol, tf, atrPeriod);
if(atr <= 0.0)
return;
const int n = RS_CountReversalEscapeSigns(data, tf, ptype, atr, adverseAtrMult, rsiVelocity, bodyAtrMult);
if(n < signsRequired)
return;
ClosePosition(data, MagicNumber);
Print("RSIScalping: reversal escape symbol=", data.symbol, " signs=", n, " need=", signsRequired,
" ATR=", DoubleToString(atr, (int)SymbolInfoInteger(data.symbol, SYMBOL_DIGITS)));
}
string ErrorDescription(int errorCode)
{
switch(errorCode)
@@ -420,7 +518,9 @@ void ClosePosition(RSIScalpingData& data, int MagicNumber)
void ProcessRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES TimeFrame, int RSI_Period,
ENUM_APPLIED_PRICE RSI_Applied_Price, double RSI_Overbought,
double RSI_Oversold, double RSI_Target_Buy, double RSI_Target_Sell,
int BarsToWait, double LotSize, int MagicNumber)
int BarsToWait, double LotSize, int MagicNumber,
bool UseReversalEscape, int ReversalATRPeriod, double ReversalAdverseAtrMult,
int ReversalSignsRequired, double ReversalRsiVelocity, double ReversalBodyAtrMult)
{
// Skip if not initialized (symbol not available)
if(!data.isInitialized)
@@ -429,16 +529,25 @@ void ProcessRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES Ti
data.symbol = symbol; // Update symbol in case it changed
if(Bars(data.symbol, TimeFrame) < RSI_Period + 2)
return;
datetime current_bar_time = iTime(data.symbol, TimeFrame, 0);
if(current_bar_time == data.last_bar_time)
const datetime current_bar_time = iTime(data.symbol, TimeFrame, 0);
const bool new_bar = (current_bar_time != data.last_bar_time);
const bool in_pos = data.position_open || PositionExistsByMagic(data.symbol, MagicNumber);
if(!in_pos && !new_bar)
return;
data.last_bar_time = current_bar_time;
if(!UpdateRSI(data))
return;
if(in_pos && UseReversalEscape)
RS_TryReversalEscape(data, TimeFrame, MagicNumber, ReversalATRPeriod, ReversalAdverseAtrMult,
ReversalSignsRequired, ReversalRsiVelocity, ReversalBodyAtrMult);
if(!new_bar)
return;
data.last_bar_time = current_bar_time;
CheckExistingPosition(data, TimeFrame, MagicNumber, RSI_Oversold, RSI_Overbought,
RSI_Target_Buy, RSI_Target_Sell, BarsToWait);
@@ -228,6 +228,9 @@ int SuperEMA_BarsSinceOpen(SuperEMAData &d, const datetime openTime)
void SuperEMA_CloseTicket(SuperEMAData &d, const ulong ticket, const string reason)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
d.trade.SetExpertMagicNumber(d.magic);
if(d.trade.PositionClose(ticket))
SuperEMA_Log(d, "Close: " + reason);
@@ -235,6 +238,9 @@ void SuperEMA_CloseTicket(SuperEMAData &d, const ulong ticket, const string reas
void SuperEMA_ManageExits(SuperEMAData &d)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
@@ -412,9 +418,6 @@ void ProcessSuperEMA(SuperEMAData &d, const double lots)
SuperEMA_ManageExits(d);
if(d.oneTradeOnly && SuperEMA_PositionsByMagic(d) > 0)
return;
const int sh = d.emaTrendBars;
double h1 = 0.0, h2 = 0.0;
if(!SuperEMA_MacdHistAt(d, 1, h1) || !SuperEMA_MacdHistAt(d, 2, h2))
@@ -450,6 +453,16 @@ void ProcessSuperEMA(SuperEMAData &d, const double lots)
break;
}
if(d.oneTradeOnly && SuperEMA_PositionsByMagic(d) > 0)
{
if(wantBuy && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, true))
wantBuy = false;
if(wantSell && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, false))
wantSell = false;
if(!wantBuy && !wantSell)
return;
}
MqlTick tick;
if(!SymbolInfoTick(d.symbol, tick))
return;
@@ -458,13 +471,17 @@ void ProcessSuperEMA(SuperEMAData &d, const double lots)
if(wantBuy && !wantSell)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, true, sl, tp);
#endif
if(d.trade.Buy(lots, d.symbol, tick.ask, sl, tp, "United SuperEMA long"))
SuperEMA_Log(d, StringFormat("BUY ask=%.5f sl=%.5f", tick.ask, sl));
}
else if(wantSell && !wantBuy)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, false, sl, tp);
#endif
if(d.trade.Sell(lots, d.symbol, tick.bid, sl, tp, "United SuperEMA short"))
SuperEMA_Log(d, StringFormat("SELL bid=%.5f sl=%.5f", tick.bid, sl));
}
@@ -1,15 +1,11 @@
//+------------------------------------------------------------------+
//| UnitedEA.mq5 |
//| Cent ".c" symbols; InpDynamicRefDeposit MUST match ACCOUNT_ |
//| CURRENCY numbers (USC ~50k for ~$500, or USD ~500 — not mixed). |
//| Per-order max lots = broker spec 最大量 SYMBOL_VOLUME_MAX |
//| (often 1000 on *.c); EA cannot exceed it — see symbol contract. |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.10"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
@@ -17,22 +13,29 @@
#include <Indicators\Trend.mqh>
#include <Indicators\Volumes.mqh>
#include "MagicNumberHelpers.mqh"
// Lot globals must exist before strategy .mqh (Darvas uses g_DB_LotSize; EMA/RC/RM use g_ES/g_RC/g_RM)
double g_ES_LotSize;
double g_RC_LotSize;
double g_RM_LotSize;
double g_DB_LotSize;
double g_DynLotScaleLast = 1.0; // last applied scale: lots = baseLot * scale * InpLotSizeScale
double g_DynamicRefBaseline = 0.0; // when InpDynamicRefDeposit<=0, frozen ref = equity at first sizing call
// Include strategy implementations early so structs are available
#include "Strategies/DarvasBoxStrategy.mqh"
#include "Strategies/EMASlopeDistanceStrategy.mqh"
#include "Strategies/RSICrossOverReversalStrategy.mqh"
#include "Strategies/RSIMidPointHijackStrategy.mqh"
#include "Strategies/RSIScalpingStrategy.mqh"
#include "Strategies/SuperEMAStrategy.mqh"
#include "Strategies/RSIReversalAsianStrategy.mqh"
#include "Strategies/RSIConsolidationStrategy.mqh"
//+------------------------------------------------------------------+
//| Global Lot Size Variables (for dynamic lot sizing) |
//+------------------------------------------------------------------+
double g_ES_LotSize; // EMA Slope Distance lot size
double g_RC_LotSize; // RSI CrossOver Reversal lot size
double g_RM_LotSize; // RSI MidPoint Hijack lot size
bool United_MayOpenNewEntry(const string symbol, const ulong magic, const bool isBuy)
{
if(PositionExistsByMagic(symbol, magic))
return false;
return true;
}
//+------------------------------------------------------------------+
//| Strategy Enable/Disable Switches |
@@ -47,51 +50,30 @@ input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
input bool EnableSuperEMA = true;
input bool EnableRSIConsolidation = true;
input bool EnableRSIReversalAsianEURUSD = true;
input bool EnableRSIReversalAsianAUDUSD = true;
//+------------------------------------------------------------------+
//| Dynamic lot sizing — 默认「按比例」:lots = base × (equity/ref) × lotScale |
//| 可选幂曲线:lots = base × (equity/ref)^exp × lotScale(旧行为) |
//| min/max 约束的是「比例系数」不是手数本身;max<=0 表示比例系数上不封顶 |
//| |
//| USC (deposit currency) vs "lot size": |
//| • Equity/ref for the multiplier are BOTH in account currency |
//| (USC). Same units → ratio is correct; no ×100 on the ratio. |
//| • Strategy base lots (e.g. DB_BaseLotSize) are ORDER VOLUME in |
//| lots, not "USC lots". Broker SYMBOL_VOLUME_* / contract define |
//| how much margin and P/L appear in USC. |
//| • Do not multiply lot inputs by 100 only because balance is USC. |
//| If DD too high: raise InpDynamicRefDeposit and/or lower base lots.|
//| If balance is USD ~500 but ref is ~50k300k: mult→floor, lots→0.01.|
//| Ref<=0: 挂上时余额/净值为参考,之后手数随净值相对该基准的比例变化。 |
//| 单笔上限:品种规格里的「最大量」(SYMBOL_VOLUME_MAX),非 EA 参数。 |
//| InpMaxLotsPerOrderEA 再截一刀,防止动态+scale 顶满 1000 爆仓。 |
//+------------------------------------------------------------------+
enum ENUM_LOT_SCALE_CURVE
{
LOT_CURVE_PROPORTIONAL = 0, // 按比例:scale = 净值/参考(线性)
LOT_CURVE_POWER = 1 // 幂:scale = (净值/参考)^exp
};
input group "=== Dynamic lot sizing (动态手数) ==="
input bool InpDynamicLotEnable = true; // Enable balance/equity-based scaling
input ENUM_LOT_SCALE_CURVE InpDynamicLotCurve = LOT_CURVE_PROPORTIONAL; // 默认按比例;幂曲线=旧 (equity/ref)^exp
input double InpDynamicRefDeposit = 0.0; // <=0: auto — ref=挂上时净值/余额(与测试器初始一致则手数随盈利涨); >0 手动参考金
input bool InpDynamicRefEqualsEquity = false; // true: 比例系数固定为 1(只用基础手×lotScale)
input double InpDynamicExponent = 1.22; // 仅 LOT_CURVE_POWER 时:(净值/参考) 的指数
input double InpDynamicMinMult = 0.0; // 比例系数下限;<=0 不抬(按比例时净值<参考会缩小手数)
input double InpDynamicMaxMult = 20.0; // 比例系数上限;<=0 不封顶(高风险)
input bool InpDynamicUseEquity = true; // true=ACCOUNT_EQUITY, false=ACCOUNT_BALANCE
input double InpDynamicStockLotCap = 0.0; // Max lots after scale (0=off); raise if InpLotSizeScale is large
input double InpLotSizeScale = 1.0; // 全局手数倍率; 曾用100易过大,默认1按需再加
input double InpMaxLotsPerOrder = 20.0; // 单笔最大手数(0=仅券商SYMBOL_VOLUME_MAX); 保守可设5~10
input group "=== Centralized Lot Size (Granular Per Robot) ==="
input double LOT_ES_EMASlopeDistance = 0.05;
input double LOT_RC_RSICrossOver = 0.1;
input double LOT_RM_RSIMidPointHijack = 0.01;
input double LOT_RS_APPL = 100.0;
input double LOT_RS_BTCUSD = 0.15;
input double LOT_RS_NVDA = 60.0;
input double LOT_RS_TSLA = 20.0;
input double LOT_RS_XAUUSD = 0.02;
input double LOT_RRA_EURUSD = 0.01;
input double LOT_RRA_AUDUSD = 0.10;
input double LOT_SE_SuperEMA = 0.01;
input double LOT_RCO_RSIConsolidation = 0.04;
//+------------------------------------------------------------------+
//| Strategy 1: DarvasBoxXAUUSD (cent symbol) |
//| Strategy 1: DarvasBoxXAUUSD |
//+------------------------------------------------------------------+
input group "=== DarvasBox Strategy ==="
input string DB_Symbol = "XAUUSD.c";
input string DB_Symbol = "XAUUSD";
input int DB_BoxPeriod = 165;
input double DB_BoxDeviation = 30000; // Increased to allow larger ranges (was 25140)
input int DB_VolumeThreshold = 0; // Set to 0 to disable volume threshold check. Volume data from indicator used instead.
@@ -108,20 +90,19 @@ input double DB_TrendThreshold = 4.94;
input int DB_VolumeMA_Period = 110;
input double DB_VolumeThresholdMultiplier = 1.5;
input int DB_MagicNumber = 135790;
input double DB_BaseLotSize = 0.02; // Base lot at InpDynamicRefDeposit (Darvas)
//+------------------------------------------------------------------+
//| Strategy 2: EMASlopeDistanceCocktailXAUUSD |
//| Cent: gold is usually "XAUUSD.c" (verify in Market Watch). |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== EMA Slope Distance Strategy ==="
input string ES_Symbol = "XAUUSD.c";
input string ES_Symbol = "XAUUSD";
input int ES_EMA_Periode = 46;
input double ES_PreisSchwelle = 600.0;
input double ES_SteigungSchwelle = 80.0;
input int ES_ÜberwachungTimeout = 800;
input double ES_TrailingStop = 250.0;
input double ES_LotGröße = 0.05;
input double ES_LotGröße = 0.03;
input int ES_MagicNumber = 12350;
input bool ES_UseSpreadAdjustment = true;
input ENUM_TIMEFRAMES ES_Timeframe = PERIOD_H1;
@@ -132,17 +113,17 @@ input bool ES_CloseUnprofitableTrades = true;
//+------------------------------------------------------------------+
//| Strategy 3: RSICrossOverReversalXAUUSD |
//| Cent: use "XAUUSD.c" if that is what the broker lists. |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI CrossOver Reversal Strategy ==="
input string RC_Symbol = "XAUUSD.c";
input string RC_Symbol = "XAUUSD";
input int RC_MagicNumber = 7;
input int RC_rsiPeriod = 19;
input int RC_overboughtLevel = 93;
input int RC_oversoldLevel = 22;
input double RC_entryRSIBuySpread = 0;
input double RC_entryRSISellSpread = 0;
input double RC_lotSize = 0.02;
input double RC_lotSize = 0.01;
input int RC_slippage = 3;
input int RC_cooldownSeconds = 209;
input ENUM_TIMEFRAMES RC_TimeFrame1 = PERIOD_M1;
@@ -168,12 +149,12 @@ input bool RC_Saturday = false;
//+------------------------------------------------------------------+
//| Strategy 4: RSIMidPointHijackXAUUSD |
//| Cent: use "XAUUSD.c" if that is what the broker lists. |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI MidPoint Hijack Strategy ==="
input string RM_Symbol = "XAUUSD.c";
input string RM_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RM_InpTimeframe = PERIOD_H1;
input double RM_InpLotSize = 0.03;
input double RM_InpLotSize = 0.02;
input int RM_InpMagicNumberRSIFollow = 1001;
input int RM_InpMagicNumberRSIReverse = 1002;
input int RM_InpMagicNumberEMACross = 1003;
@@ -217,11 +198,16 @@ input int RM_InpEMADistancePeriod = 26;
//| - TSLA: Tesla stock |
//| - XAUUSD: Gold/USD |
//| |
//| USC cent: many symbols end with ".c" — use Market Watch names. |
//| Stocks may be "AAPL.US.c" or unchanged; verify before live. |
//| PEPPERSTONE US SYMBOL FORMATS: |
//| - Stocks may use: "AAPL.US", "NASDAQ:AAPL", or just "AAPL" |
//| - To find correct symbols: |
//| 1. Open Market Watch (Ctrl+M) |
//| 2. Right-click > Show All |
//| 3. Search for the stock name |
//| 4. Use the exact symbol name shown |
//+------------------------------------------------------------------+
input group "=== RSI Scalping APPL (AAPL) - cent ==="
input string RS_APPL_Symbol = "AAPL.US.c"; // If missing, try AAPL.US / NASDAQ:AAPL / AAPL
input group "=== RSI Scalping APPL (AAPL) - Pepperstone US ==="
input string RS_APPL_Symbol = "AAPL.US"; // Try: "AAPL.US", "NASDAQ:AAPL", or "AAPL"
input ENUM_TIMEFRAMES RS_APPL_TimeFrame = PERIOD_M10;
input int RS_APPL_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_APPL_RSI_Applied_Price = PRICE_CLOSE;
@@ -230,12 +216,12 @@ input double RS_APPL_RSI_Oversold = 78;
input double RS_APPL_RSI_Target_Buy = 94;
input double RS_APPL_RSI_Target_Sell = 44;
input int RS_APPL_BarsToWait = 7;
input double RS_APPL_LotSize = 38;
input double RS_APPL_LotSize = 25;
input int RS_APPL_MagicNumber = 20001;
input int RS_APPL_Slippage = 3;
input group "=== RSI Scalping BTCUSD ==="
input string RS_BTCUSD_Symbol = "BTCUSD.c"; // If missing, try BTCUSD or BTC/USD
input string RS_BTCUSD_Symbol = "BTCUSD"; // Pepperstone may use: "BTCUSD", "BTC/USD", or "BTCUSD.c"
input ENUM_TIMEFRAMES RS_BTCUSD_TimeFrame = PERIOD_H1;
input int RS_BTCUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_BTCUSD_RSI_Applied_Price = PRICE_CLOSE;
@@ -244,12 +230,12 @@ input double RS_BTCUSD_RSI_Oversold = 73;
input double RS_BTCUSD_RSI_Target_Buy = 88;
input double RS_BTCUSD_RSI_Target_Sell = 48;
input int RS_BTCUSD_BarsToWait = 6;
input double RS_BTCUSD_LotSize = 0.15;
input double RS_BTCUSD_LotSize = 0.1;
input int RS_BTCUSD_MagicNumber = 123459123;
input int RS_BTCUSD_Slippage = 3;
input group "=== RSI Scalping NVDA - cent ==="
input string RS_NVDA_Symbol = "NVDA.US.c"; // If missing, try NVDA.US / NASDAQ:NVDA / NVDA
input group "=== RSI Scalping NVDA - Pepperstone US ==="
input string RS_NVDA_Symbol = "NVDA.US"; // Try: "NVDA.US", "NASDAQ:NVDA", or "NVDA"
input ENUM_TIMEFRAMES RS_NVDA_TimeFrame = PERIOD_M15;
input int RS_NVDA_RSI_Period = 8;
input ENUM_APPLIED_PRICE RS_NVDA_RSI_Applied_Price = PRICE_CLOSE;
@@ -258,12 +244,12 @@ input double RS_NVDA_RSI_Oversold = 38;
input double RS_NVDA_RSI_Target_Buy = 90;
input double RS_NVDA_RSI_Target_Sell = 70;
input int RS_NVDA_BarsToWait = 5;
input double RS_NVDA_LotSize = 75;
input double RS_NVDA_LotSize = 50;
input int RS_NVDA_MagicNumber = 20003;
input int RS_NVDA_Slippage = 3;
input group "=== RSI Scalping TSLA - cent ==="
input string RS_TSLA_Symbol = "TSLA.US.c"; // If missing, try TSLA.US / NASDAQ:TSLA / TSLA
input group "=== RSI Scalping TSLA - Pepperstone US ==="
input string RS_TSLA_Symbol = "TSLA.US"; // Try: "TSLA.US", "NASDAQ:TSLA", or "TSLA"
input ENUM_TIMEFRAMES RS_TSLA_TimeFrame = PERIOD_H1;
input int RS_TSLA_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_TSLA_RSI_Applied_Price = PRICE_CLOSE;
@@ -272,12 +258,12 @@ input double RS_TSLA_RSI_Oversold = 73;
input double RS_TSLA_RSI_Target_Buy = 87;
input double RS_TSLA_RSI_Target_Sell = 33;
input int RS_TSLA_BarsToWait = 1;
input double RS_TSLA_LotSize = 75;
input double RS_TSLA_LotSize = 50;
input int RS_TSLA_MagicNumber = 125421321;
input int RS_TSLA_Slippage = 3;
input group "=== RSI Scalping XAUUSD ==="
input string RS_XAUUSD_Symbol = "XAUUSD.c";
input string RS_XAUUSD_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RS_XAUUSD_TimeFrame = PERIOD_H1;
input int RS_XAUUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_XAUUSD_RSI_Applied_Price = PRICE_CLOSE;
@@ -286,10 +272,18 @@ input double RS_XAUUSD_RSI_Oversold = 57;
input double RS_XAUUSD_RSI_Target_Buy = 80;
input double RS_XAUUSD_RSI_Target_Sell = 57;
input int RS_XAUUSD_BarsToWait = 4;
input double RS_XAUUSD_LotSize = 0.15;
input double RS_XAUUSD_LotSize = 0.1;
input int RS_XAUUSD_MagicNumber = 129102315;
input int RS_XAUUSD_Slippage = 3;
input group "=== RSI Scalping Reversal Escape (XAUUSD only) ==="
input bool RS_UseReversalEscape = true;
input int RS_ReversalATRPeriod = 14;
input double RS_ReversalAdverseAtrMult = 5.25;
input int RS_ReversalSignsRequired = 2;
input double RS_ReversalRsiVelocity = 16.0;
input double RS_ReversalBodyAtrMult = 5.1;
//+------------------------------------------------------------------+
//| Strategy 11-12: RSI Reversal Asian Strategies |
//| Each RSI Reversal Asian strategy trades on its own symbol: |
@@ -297,13 +291,13 @@ input int RS_XAUUSD_Slippage = 3;
//| - AUDUSD: Australian Dollar/USD |
//+------------------------------------------------------------------+
input group "=== RSI Reversal Asian EURUSD ==="
input string RRA_EURUSD_Symbol = "EURUSD.c";
input string RRA_EURUSD_Symbol = "EURUSD";
input int RRA_EURUSD_RSIPeriod = 28;
input double RRA_EURUSD_OverboughtLevel = 60;
input double RRA_EURUSD_OversoldLevel = 8;
input int RRA_EURUSD_TakeProfitPips = 175;
input int RRA_EURUSD_StopLossPips = 5;
input double RRA_EURUSD_MaxLotSize = 0.15;
input double RRA_EURUSD_MaxLotSize = 0.1;
input int RRA_EURUSD_MaxSpread = 1000;
input int RRA_EURUSD_MaxDuration = 270;
input bool RRA_EURUSD_UseStopLoss = false;
@@ -316,13 +310,13 @@ input int RRA_EURUSD_MagicNumber = 30001;
input int RRA_EURUSD_Slippage = 3;
input group "=== RSI Reversal Asian AUDUSD ==="
input string RRA_AUDUSD_Symbol = "AUDUSD.c";
input string RRA_AUDUSD_Symbol = "AUDUSD";
input int RRA_AUDUSD_RSIPeriod = 28;
input double RRA_AUDUSD_OverboughtLevel = 68;
input double RRA_AUDUSD_OversoldLevel = 30;
input int RRA_AUDUSD_TakeProfitPips = 175;
input int RRA_AUDUSD_StopLossPips = 5;
input double RRA_AUDUSD_MaxLotSize = 0.3;
input double RRA_AUDUSD_MaxLotSize = 0.2;
input int RRA_AUDUSD_MaxSpread = 1000;
input int RRA_AUDUSD_MaxDuration = 340;
input bool RRA_AUDUSD_UseStopLoss = false;
@@ -334,6 +328,63 @@ input ENUM_TIMEFRAMES RRA_AUDUSD_TimeFrame = PERIOD_M15;
input int RRA_AUDUSD_MagicNumber = 30002;
input int RRA_AUDUSD_Slippage = 3;
input group "=== SuperEMA (EMA + CCI + MACD) ==="
input string SE_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES SE_Timeframe = PERIOD_M15;
input double SE_LotSize = 0.01;
input int SE_SlippagePoints = 55;
input int SE_MagicNumber = 940001;
input int SE_EmaFast = 40;
input int SE_EmaMid = 180;
input int SE_EmaSlow = 125;
input int SE_EmaTrendBars = 3;
input int SE_CciPeriod = 17;
input double SE_CciOverbought = 80.0;
input double SE_CciOversold = -140.0;
input int SE_PullbackCciLookback = 20;
input int SE_MacdFast = 14;
input int SE_MacdSlow = 38;
input int SE_MacdSignal = 9;
input ENUM_SE_ENTRY_STYLE SE_EntryStyle = SE_ENTRY_LAMBERT;
input bool SE_OneTradeOnly = true;
input bool SE_UseStructuralSL = false;
input double SE_SlBufferPoints = 110;
input bool SE_ExitOnTrendFlip = false;
input bool SE_ExitOnMacdFlip = false;
input bool SE_ExitOnCciZeroCross = true;
input int SE_MaxHoldingBars = 168;
input bool SE_ExitBelowMidEma = false;
input bool SE_DebugLogs = false;
input group "=== RSI Consolidation (ranging / mean-reversion) ==="
input string RCO_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RCO_SignalTF = PERIOD_M15;
input bool RCO_EntryOnNewBarOnly = true;
input int RCO_ADX_Period = 23;
input double RCO_ADX_Max = 29.0;
input bool RCO_UseATRRatioFilter = true;
input int RCO_ATR_Period = 8;
input int RCO_ATR_SMA_Period = 35;
input double RCO_ATR_Ratio_Max = 1.36;
input bool RCO_UseFlatEMAFilter = true;
input int RCO_EMA_Fast = 13;
input int RCO_EMA_Slow = 17;
input double RCO_EMA_Separation_MaxPct = 0.26;
input int RCO_RSI_Period = 8;
input ENUM_APPLIED_PRICE RCO_RSI_Price = PRICE_OPEN;
input double RCO_RSI_Oversold = 22.0;
input double RCO_RSI_Overbought = 63.0;
input bool RCO_UseRSI_MeanExit = true;
input double RCO_RSI_Exit_Long = 48.0;
input double RCO_RSI_Exit_Short = 52.0;
input double RCO_SL_ATR_Mult = 2.15;
input double RCO_TP_ATR_Mult = 2.40;
input int RCO_MaxBarsInTrade = 54;
input double RCO_Lots = 0.10;
input ulong RCO_MagicNumber = 20250420;
input int RCO_Slippage = 10;
input int RCO_MaxSpreadPoints = 28;
//+------------------------------------------------------------------+
//| Global Variables - DarvasBox |
//+------------------------------------------------------------------+
@@ -430,6 +481,8 @@ RSIScalpingData rsBTCUSDData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
SuperEMAData seData;
RSIConsolidationData rcoData;
//+------------------------------------------------------------------+
//| Global Variables - RSI Reversal Asian |
@@ -437,107 +490,6 @@ RSIScalpingData rsXAUUSDData;
RSIReversalAsianData rraEURUSDData;
RSIReversalAsianData rraAUDUSDData;
//+------------------------------------------------------------------+
//| Dynamic lot helpers |
//+------------------------------------------------------------------+
double DynClamp(const double v, const double lo, const double hi)
{
return MathMax(lo, MathMin(hi, v));
}
// Clamp scale factor (proportion or pow result). max<=0 = no upper clamp.
double ApplyDynamicScaleClamp(const double scaleRaw)
{
double s = scaleRaw;
if(InpDynamicMinMult > 0.0)
s = MathMax(s, InpDynamicMinMult);
if(InpDynamicMaxMult > 0.0)
s = MathMin(s, InpDynamicMaxMult);
return s;
}
// Reference for (equity/ref)^exp: manual deposit, or first-seen balance when input <= 0
double GetDynamicRefForRatio()
{
if(InpDynamicRefDeposit > 0.0)
return MathMax(InpDynamicRefDeposit, 1.0);
double capNow = InpDynamicUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
if(g_DynamicRefBaseline <= 0.0)
g_DynamicRefBaseline = MathMax(capNow, 1.0);
return MathMax(g_DynamicRefBaseline, 1.0);
}
// Broker hard cap: 最大量 = SYMBOL_VOLUME_MAX (e.g. 1000 on EURUSD.c / XAUUSD.c)
double NormalizeVolumeForSymbol(const string symbol, double lots)
{
double minL = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double maxL = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
if(step > 0.0)
lots = MathFloor(lots / step + 1e-12) * step;
if(lots < minL) lots = minL;
if(lots > maxL) lots = maxL;
return lots;
}
// Apply EA risk cap before broker min/step/max (InpMaxLotsPerOrder 0 = disabled)
double NormalizeVolumeForSymbolWithEACap(const string symbol, double lots)
{
if(InpMaxLotsPerOrder > 0.0)
lots = MathMin(lots, InpMaxLotsPerOrder);
return NormalizeVolumeForSymbol(symbol, lots);
}
// Scale factor for lots: baseLot * scale * InpLotSizeScale (then caps)
double GetDynamicLotScaleFactor()
{
if(!InpDynamicLotEnable)
return 1.0;
if(InpDynamicRefEqualsEquity)
return ApplyDynamicScaleClamp(1.0);
double cap = InpDynamicUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
double refv = GetDynamicRefForRatio();
if(cap <= 0.0)
cap = refv;
double ratio = cap / refv;
if(ratio <= 0.0)
ratio = 1.0;
double scaleRaw = ratio;
if(InpDynamicLotCurve == LOT_CURVE_POWER)
scaleRaw = MathPow(ratio, InpDynamicExponent);
return ApplyDynamicScaleClamp(scaleRaw);
}
// baseLot = size at reference deposit; optionalCap 0 = no extra ceiling (broker min/max still apply)
double DynamicLotForSymbol(const string symbol, const double baseLot, const double optionalCap = 0.0)
{
double scale = GetDynamicLotScaleFactor();
g_DynLotScaleLast = scale;
double sc = (InpLotSizeScale > 0.0 ? InpLotSizeScale : 1.0);
double v = baseLot * scale * sc;
if(optionalCap > 0.0 && v > optionalCap)
v = optionalCap;
return NormalizeVolumeForSymbolWithEACap(symbol, v);
}
void RefreshDynamicStrategyLots()
{
double sc = (InpLotSizeScale > 0.0 ? InpLotSizeScale : 1.0);
if(!InpDynamicLotEnable)
{
g_ES_LotSize = NormalizeVolumeForSymbolWithEACap(ES_Symbol, ES_LotGröße * sc);
g_RC_LotSize = NormalizeVolumeForSymbolWithEACap(RC_Symbol, RC_lotSize * sc);
g_RM_LotSize = NormalizeVolumeForSymbolWithEACap(RM_Symbol, RM_InpLotSize * sc);
g_DB_LotSize = NormalizeVolumeForSymbolWithEACap(DB_Symbol, DB_BaseLotSize * sc);
g_DynLotScaleLast = 1.0;
return;
}
g_ES_LotSize = DynamicLotForSymbol(ES_Symbol, ES_LotGröße);
g_RC_LotSize = DynamicLotForSymbol(RC_Symbol, RC_lotSize);
g_RM_LotSize = DynamicLotForSymbol(RM_Symbol, RM_InpLotSize);
g_DB_LotSize = DynamicLotForSymbol(DB_Symbol, DB_BaseLotSize);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
@@ -545,17 +497,10 @@ int OnInit()
{
int initResult = INIT_SUCCEEDED;
g_DynamicRefBaseline = 0.0;
RefreshDynamicStrategyLots();
string acctCur = AccountInfoString(ACCOUNT_CURRENCY);
double eq0 = AccountInfoDouble(ACCOUNT_EQUITY);
if(InpDynamicLotEnable && !InpDynamicRefEqualsEquity && InpDynamicRefDeposit > 1000.0 && eq0 > 0.0
&& eq0 <= InpDynamicRefDeposit / 25.0)
Print("United EA: equity ", DoubleToString(eq0, 2), " ", acctCur, " vs ref ", InpDynamicRefDeposit,
" — dynamic mult is tiny; set InpDynamicRefDeposit to your balance in ", acctCur,
" (e.g. 500 for USD) or enable InpDynamicRefEqualsEquity. Else lots stay at broker minimum.");
// Initialize global lot size variables
g_ES_LotSize = LOT_ES_EMASlopeDistance;
g_RC_LotSize = LOT_RC_RSICrossOver;
g_RM_LotSize = LOT_RM_RSIMidPointHijack;
// Initialize strategies - log warnings but don't fail entire EA if symbol unavailable
if(EnableDarvasBox)
@@ -589,11 +534,30 @@ int OnInit()
if(EnableRSIScalpingXAUUSD)
InitRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price, RS_XAUUSD_MagicNumber, RS_XAUUSD_Slippage);
if(EnableSuperEMA)
if(!InitSuperEMA(seData, SE_Symbol, SE_Timeframe, SE_SlippagePoints, SE_MagicNumber,
SE_EmaFast, SE_EmaMid, SE_EmaSlow, SE_EmaTrendBars,
SE_CciPeriod, SE_CciOverbought, SE_CciOversold, SE_PullbackCciLookback,
SE_MacdFast, SE_MacdSlow, SE_MacdSignal,
SE_EntryStyle, SE_OneTradeOnly, SE_UseStructuralSL, SE_SlBufferPoints,
SE_ExitOnTrendFlip, SE_ExitOnMacdFlip, SE_ExitOnCciZeroCross,
SE_MaxHoldingBars, SE_ExitBelowMidEma, SE_DebugLogs))
Print("Warning: SuperEMA failed to initialize for symbol '", SE_Symbol, "'");
if(EnableRSIConsolidation)
if(!InitRSIConsolidation(rcoData, RCO_Symbol, RCO_SignalTF, RCO_EntryOnNewBarOnly,
RCO_ADX_Period, RCO_ADX_Max, RCO_UseATRRatioFilter, RCO_ATR_Period, RCO_ATR_SMA_Period, RCO_ATR_Ratio_Max,
RCO_UseFlatEMAFilter, RCO_EMA_Fast, RCO_EMA_Slow, RCO_EMA_Separation_MaxPct,
RCO_RSI_Period, RCO_RSI_Price, RCO_RSI_Oversold, RCO_RSI_Overbought,
RCO_UseRSI_MeanExit, RCO_RSI_Exit_Long, RCO_RSI_Exit_Short, RCO_SL_ATR_Mult, RCO_TP_ATR_Mult,
RCO_MaxBarsInTrade, RCO_MagicNumber, RCO_Slippage, RCO_MaxSpreadPoints))
Print("Warning: RSIConsolidation failed to initialize for symbol '", RCO_Symbol, "'");
// Initialize RSI Reversal Asian strategies
if(EnableRSIReversalAsianEURUSD)
if(!InitRSIReversalAsian(rraEURUSDData, RRA_EURUSD_Symbol, RRA_EURUSD_RSIPeriod, RRA_EURUSD_OverboughtLevel, RRA_EURUSD_OversoldLevel,
RRA_EURUSD_TakeProfitPips, RRA_EURUSD_StopLossPips, RRA_EURUSD_MaxLotSize,
RRA_EURUSD_TakeProfitPips, RRA_EURUSD_StopLossPips, LOT_RRA_EURUSD,
RRA_EURUSD_MaxSpread, RRA_EURUSD_MaxDuration, RRA_EURUSD_UseStopLoss,
RRA_EURUSD_UseTakeProfit, RRA_EURUSD_UseRSIExit, RRA_EURUSD_RSIExitLevel,
RRA_EURUSD_CloseOutsideSession, RRA_EURUSD_TimeFrame, RRA_EURUSD_MagicNumber, RRA_EURUSD_Slippage))
@@ -601,24 +565,12 @@ int OnInit()
if(EnableRSIReversalAsianAUDUSD)
if(!InitRSIReversalAsian(rraAUDUSDData, RRA_AUDUSD_Symbol, RRA_AUDUSD_RSIPeriod, RRA_AUDUSD_OverboughtLevel, RRA_AUDUSD_OversoldLevel,
RRA_AUDUSD_TakeProfitPips, RRA_AUDUSD_StopLossPips, RRA_AUDUSD_MaxLotSize,
RRA_AUDUSD_TakeProfitPips, RRA_AUDUSD_StopLossPips, LOT_RRA_AUDUSD,
RRA_AUDUSD_MaxSpread, RRA_AUDUSD_MaxDuration, RRA_AUDUSD_UseStopLoss,
RRA_AUDUSD_UseTakeProfit, RRA_AUDUSD_UseRSIExit, RRA_AUDUSD_RSIExitLevel,
RRA_AUDUSD_CloseOutsideSession, RRA_AUDUSD_TimeFrame, RRA_AUDUSD_MagicNumber, RRA_AUDUSD_Slippage))
Print("Warning: RSIReversalAsianAUDUSD strategy failed to initialize for symbol '", RRA_AUDUSD_Symbol, "'");
double refEffInit = GetDynamicRefForRatio();
double capInit = InpDynamicUseEquity ? eq0 : AccountInfoDouble(ACCOUNT_BALANCE);
if(capInit <= 0.0)
capInit = refEffInit;
double ratioInit = capInit / refEffInit;
double powInit = MathPow(ratioInit, InpDynamicExponent);
string curveStr = (InpDynamicLotCurve == LOT_CURVE_POWER ? "POWER" : "PROP");
Print("United EA v1.10 ", acctCur, " curve=", curveStr, " equity=", DoubleToString(eq0, 2), " refEff=", DoubleToString(refEffInit, 2),
" (inpRef=", InpDynamicRefDeposit, " baseline=", DoubleToString(g_DynamicRefBaseline, 2), ") equity/ref=", DoubleToString(ratioInit, 6),
" pow^exp=", DoubleToString(powInit, 6), " scaleOut=", DoubleToString(g_DynLotScaleLast, 6),
" minS=", InpDynamicMinMult, " maxS=", InpDynamicMaxMult, " lotScale=", InpLotSizeScale, " maxLots=", InpMaxLotsPerOrder,
" lots ES=", g_ES_LotSize, " RC=", g_RC_LotSize, " RM=", g_RM_LotSize, " DB=", g_DB_LotSize);
Print("United EA initialized. Active strategies: ",
(EnableDarvasBox ? "DarvasBox " : ""),
(EnableEMASlopeDistance ? "EMASlope " : ""),
@@ -629,6 +581,8 @@ int OnInit()
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""),
(EnableSuperEMA ? "SuperEMA " : ""),
(EnableRSIConsolidation ? "RSIConsolidation " : ""),
(EnableRSIReversalAsianEURUSD ? "RSIReversalAsianEURUSD " : ""),
(EnableRSIReversalAsianAUDUSD ? "RSIReversalAsianAUDUSD " : ""));
@@ -666,6 +620,12 @@ void OnDeinit(const int reason)
if(EnableRSIScalpingXAUUSD)
DeinitRSIScalping(rsXAUUSDData);
if(EnableSuperEMA)
DeinitSuperEMA(seData);
if(EnableRSIConsolidation)
DeinitRSIConsolidation(rcoData);
if(EnableRSIReversalAsianEURUSD)
DeinitRSIReversalAsian(rraEURUSDData);
@@ -681,8 +641,6 @@ void OnDeinit(const int reason)
//+------------------------------------------------------------------+
void OnTick()
{
RefreshDynamicStrategyLots();
if(EnableDarvasBox)
ProcessDarvasBox(DB_Symbol);
@@ -698,39 +656,49 @@ void OnTick()
if(EnableRSIScalpingAPPL)
ProcessRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price,
RS_APPL_RSI_Overbought, RS_APPL_RSI_Oversold, RS_APPL_RSI_Target_Buy, RS_APPL_RSI_Target_Sell,
RS_APPL_BarsToWait,
DynamicLotForSymbol(RS_APPL_Symbol, RS_APPL_LotSize, InpDynamicStockLotCap),
RS_APPL_MagicNumber);
RS_APPL_BarsToWait, LOT_RS_APPL, RS_APPL_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingBTCUSD)
ProcessRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price,
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, DynamicLotForSymbol(RS_BTCUSD_Symbol, RS_BTCUSD_LotSize), RS_BTCUSD_MagicNumber);
RS_BTCUSD_BarsToWait, LOT_RS_BTCUSD, RS_BTCUSD_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
RS_NVDA_BarsToWait,
DynamicLotForSymbol(RS_NVDA_Symbol, RS_NVDA_LotSize, InpDynamicStockLotCap),
RS_NVDA_MagicNumber);
RS_NVDA_BarsToWait, LOT_RS_NVDA, RS_NVDA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingTSLA)
ProcessRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price,
RS_TSLA_RSI_Overbought, RS_TSLA_RSI_Oversold, RS_TSLA_RSI_Target_Buy, RS_TSLA_RSI_Target_Sell,
RS_TSLA_BarsToWait,
DynamicLotForSymbol(RS_TSLA_Symbol, RS_TSLA_LotSize, InpDynamicStockLotCap),
RS_TSLA_MagicNumber);
RS_TSLA_BarsToWait, LOT_RS_TSLA, RS_TSLA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingXAUUSD)
ProcessRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price,
RS_XAUUSD_RSI_Overbought, RS_XAUUSD_RSI_Oversold, RS_XAUUSD_RSI_Target_Buy, RS_XAUUSD_RSI_Target_Sell,
RS_XAUUSD_BarsToWait, DynamicLotForSymbol(RS_XAUUSD_Symbol, RS_XAUUSD_LotSize), RS_XAUUSD_MagicNumber);
RS_XAUUSD_BarsToWait, LOT_RS_XAUUSD, RS_XAUUSD_MagicNumber,
RS_UseReversalEscape, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIReversalAsianEURUSD)
ProcessRSIReversalAsian(rraEURUSDData, DynamicLotForSymbol(RRA_EURUSD_Symbol, RRA_EURUSD_MaxLotSize));
ProcessRSIReversalAsian(rraEURUSDData, LOT_RRA_EURUSD);
if(EnableRSIReversalAsianAUDUSD)
ProcessRSIReversalAsian(rraAUDUSDData, DynamicLotForSymbol(RRA_AUDUSD_Symbol, RRA_AUDUSD_MaxLotSize));
ProcessRSIReversalAsian(rraAUDUSDData, LOT_RRA_AUDUSD);
if(EnableSuperEMA)
ProcessSuperEMA(seData, LOT_SE_SuperEMA);
if(EnableRSIConsolidation)
ProcessRSIConsolidation(rcoData, LOT_RCO_RSIConsolidation);
}
//+------------------------------------------------------------------+

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

@@ -104,7 +104,7 @@ bool IsStockSymbol(string symbol)
// String-based checks (.US, NASDAQ:, NYSE:, common tickers) are sufficient
// Common stock tickers (without .US suffix)
string commonStocks[] = {"AAPL", "NVDA", "TSLA", "GOOGL", "AMZN", "META", "AMD", "NFLX"};
string commonStocks[] = {"AAPL", "MSFT", "NVDA", "TSLA", "GOOGL", "AMZN", "META", "NFLX"};
for(int i = 0; i < ArraySize(commonStocks); i++)
{
if(StringFind(symbol, commonStocks[i]) == 0) return true;
@@ -195,9 +195,9 @@ bool PlaceOrder(ENUM_ORDER_TYPE orderType, double price, double sl, double tp)
// Use market price (0) instead of explicit price - this ensures market order execution
// In backtesting, explicit price might fail if price has moved
if(orderType == ORDER_TYPE_BUY)
result = dbData.trade.Buy(g_DB_LotSize, dbData.symbol, 0, sl, tp, "Darvas Box Breakout");
result = dbData.trade.Buy(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakout");
else
result = dbData.trade.Sell(g_DB_LotSize, dbData.symbol, 0, sl, tp, "Darvas Box Breakdown");
result = dbData.trade.Sell(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakdown");
// Always log errors, success only if logging enabled
if(result)
@@ -0,0 +1,387 @@
//+------------------------------------------------------------------+
//| RSIConsolidationStrategy.mqh |
//| Ported from cluster-0/RSIConsolidation/RSIConsolidation.mq5 |
//+------------------------------------------------------------------+
#ifndef RSI_CONSOLIDATION_STRATEGY_MQH
#define RSI_CONSOLIDATION_STRATEGY_MQH
struct RSIConsolidationData
{
string symbol;
bool isInitialized;
CTrade trade;
ENUM_TIMEFRAMES signalTF;
bool entryOnNewBarOnly;
int adxPeriod;
double adxMax;
bool useATRRatioFilter;
int atrPeriod;
int atrSmaPeriod;
double atrRatioMax;
bool useFlatEMAFilter;
int emaFast;
int emaSlow;
double emaSeparationMaxPct;
int rsiPeriod;
ENUM_APPLIED_PRICE rsiPrice;
double rsiOversold;
double rsiOverbought;
bool useRSIMeanExit;
double rsiExitLong;
double rsiExitShort;
double slAtrMult;
double tpAtrMult;
int maxBarsInTrade;
ulong magic;
int slippage;
int maxSpreadPoints;
int h_rsi;
int h_adx;
int h_atr;
int h_ema_fast;
int h_ema_slow;
datetime lastBar;
};
bool RCO_Copy1(const int handle, double &v)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(handle, 0, 0, 1, b) < 1)
return false;
v = b[0];
return true;
}
bool RCO_RsiBuffers(RSIConsolidationData &d, double &cur, double &prev, double &twoAgo)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(d.h_rsi, 0, 0, 3, b) < 3)
return false;
cur = b[0];
prev = b[1];
twoAgo = b[2];
return true;
}
double RCO_NormalizeVolume(const string sym, double vol)
{
double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
if(step > 0.0)
vol = MathFloor(vol / step) * step;
if(vol < minLot)
vol = minLot;
if(vol > maxLot)
vol = maxLot;
return vol;
}
int RCO_CurrentSpreadPoints(const string sym)
{
long spread = 0;
if(!SymbolInfoInteger(sym, SYMBOL_SPREAD, spread))
return 999999;
return (int)spread;
}
double RCO_MinStopsDistancePrice(const string sym)
{
long lvl = 0;
if(!SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL, lvl))
return 0;
double pt = SymbolInfoDouble(sym, SYMBOL_POINT);
if(pt <= 0)
return 0;
return (double)lvl * pt;
}
bool RCO_RegimeIsConsolidation(RSIConsolidationData &d)
{
double adx = 0;
if(!RCO_Copy1(d.h_adx, adx))
return false;
if(adx >= d.adxMax)
return false;
if(d.useATRRatioFilter)
{
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, d.atrSmaPeriod + 1, atrArr) < d.atrSmaPeriod + 1)
return false;
double sum = 0;
for(int i = 1; i <= d.atrSmaPeriod; i++)
sum += atrArr[i];
double smaAtr = sum / (double)d.atrSmaPeriod;
if(smaAtr <= 0.0)
return false;
double ratio = atrArr[0] / smaAtr;
if(ratio > d.atrRatioMax)
return false;
}
if(d.useFlatEMAFilter)
{
double ef[], es[];
ArraySetAsSeries(ef, true);
ArraySetAsSeries(es, true);
if(CopyBuffer(d.h_ema_fast, 0, 0, 1, ef) < 1)
return false;
if(CopyBuffer(d.h_ema_slow, 0, 0, 1, es) < 1)
return false;
double c = SymbolInfoDouble(d.symbol, SYMBOL_BID);
if(c <= 0)
return false;
double sep = MathAbs(ef[0] - es[0]) / c * 100.0;
if(sep > d.emaSeparationMaxPct)
return false;
}
return true;
}
bool RCO_EntryBuyCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo <= d.rsiOversold && prev > d.rsiOversold);
}
bool RCO_EntrySellCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo >= d.rsiOverbought && prev < d.rsiOverbought);
}
void RCO_TryCloseByRSI(RSIConsolidationData &d, const ENUM_POSITION_TYPE typ, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
if(!d.useRSIMeanExit)
return;
if(typ == POSITION_TYPE_BUY && rsi >= d.rsiExitLong)
d.trade.PositionClose(tk);
else if(typ == POSITION_TYPE_SELL && rsi <= d.rsiExitShort)
d.trade.PositionClose(tk);
}
void RCO_ManageOpenPosition(RSIConsolidationData &d, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
ENUM_POSITION_TYPE typ = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openT = (datetime)PositionGetInteger(POSITION_TIME);
int barsAgo = iBarShift(d.symbol, d.signalTF, openT, false);
if(barsAgo >= 0 && barsAgo >= d.maxBarsInTrade)
{
d.trade.PositionClose(tk);
return;
}
RCO_TryCloseByRSI(d, typ, rsi);
}
bool InitRSIConsolidation(RSIConsolidationData &d,
const string inpSymbol,
const ENUM_TIMEFRAMES signalTF,
const bool entryOnNewBarOnly,
const int adxPeriod,
const double adxMax,
const bool useATRRatioFilter,
const int atrPeriod,
const int atrSmaPeriod,
const double atrRatioMax,
const bool useFlatEMAFilter,
const int emaFast,
const int emaSlow,
const double emaSeparationMaxPct,
const int rsiPeriod,
const ENUM_APPLIED_PRICE rsiPrice,
const double rsiOversold,
const double rsiOverbought,
const bool useRSIMeanExit,
const double rsiExitLong,
const double rsiExitShort,
const double slAtrMult,
const double tpAtrMult,
const int maxBarsInTrade,
const ulong magic,
const int slippage,
const int maxSpreadPoints)
{
d.isInitialized = false;
d.symbol = inpSymbol;
StringTrimLeft(d.symbol);
StringTrimRight(d.symbol);
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.signalTF = signalTF;
d.entryOnNewBarOnly = entryOnNewBarOnly;
d.adxPeriod = adxPeriod;
d.adxMax = adxMax;
d.useATRRatioFilter = useATRRatioFilter;
d.atrPeriod = atrPeriod;
d.atrSmaPeriod = atrSmaPeriod;
d.atrRatioMax = atrRatioMax;
d.useFlatEMAFilter = useFlatEMAFilter;
d.emaFast = emaFast;
d.emaSlow = emaSlow;
d.emaSeparationMaxPct = emaSeparationMaxPct;
d.rsiPeriod = rsiPeriod;
d.rsiPrice = rsiPrice;
d.rsiOversold = rsiOversold;
d.rsiOverbought = rsiOverbought;
d.useRSIMeanExit = useRSIMeanExit;
d.rsiExitLong = rsiExitLong;
d.rsiExitShort = rsiExitShort;
d.slAtrMult = slAtrMult;
d.tpAtrMult = tpAtrMult;
d.maxBarsInTrade = maxBarsInTrade;
d.magic = magic;
d.slippage = slippage;
d.maxSpreadPoints = maxSpreadPoints;
d.lastBar = 0;
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
if(!SymbolSelect(d.symbol, true))
{
Print("RSIConsolidation: SymbolSelect failed: ", d.symbol);
return false;
}
d.trade.SetExpertMagicNumber((long)d.magic);
d.trade.SetDeviationInPoints(d.slippage);
d.trade.SetTypeFillingBySymbol(d.symbol);
d.h_rsi = iRSI(d.symbol, d.signalTF, d.rsiPeriod, d.rsiPrice);
d.h_adx = iADX(d.symbol, d.signalTF, d.adxPeriod);
d.h_atr = iATR(d.symbol, d.signalTF, d.atrPeriod);
d.h_ema_fast = iMA(d.symbol, d.signalTF, d.emaFast, 0, MODE_EMA, PRICE_CLOSE);
d.h_ema_slow = iMA(d.symbol, d.signalTF, d.emaSlow, 0, MODE_EMA, PRICE_CLOSE);
if(d.h_rsi == INVALID_HANDLE || d.h_adx == INVALID_HANDLE || d.h_atr == INVALID_HANDLE
|| d.h_ema_fast == INVALID_HANDLE || d.h_ema_slow == INVALID_HANDLE)
{
Print("RSIConsolidation: indicator init failed");
DeinitRSIConsolidation(d);
return false;
}
d.isInitialized = true;
Print("RSIConsolidation: symbol=", d.symbol, " TF=", EnumToString(d.signalTF));
return true;
}
void DeinitRSIConsolidation(RSIConsolidationData &d)
{
if(d.h_rsi != INVALID_HANDLE)
IndicatorRelease(d.h_rsi);
if(d.h_adx != INVALID_HANDLE)
IndicatorRelease(d.h_adx);
if(d.h_atr != INVALID_HANDLE)
IndicatorRelease(d.h_atr);
if(d.h_ema_fast != INVALID_HANDLE)
IndicatorRelease(d.h_ema_fast);
if(d.h_ema_slow != INVALID_HANDLE)
IndicatorRelease(d.h_ema_slow);
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
}
bool RCO_EnoughHistory(RSIConsolidationData &d)
{
int need = MathMax(d.rsiPeriod + 3, MathMax(d.adxPeriod + 2, d.atrSmaPeriod + 3));
if(Bars(d.symbol, d.signalTF) < need)
return false;
return true;
}
void ProcessRSIConsolidation(RSIConsolidationData &d, const double lots)
{
if(!d.isInitialized)
return;
if(!RCO_EnoughHistory(d))
return;
if(d.maxSpreadPoints > 0 && RCO_CurrentSpreadPoints(d.symbol) > d.maxSpreadPoints)
return;
double rsi, rsiPrev, rsi2;
if(!RCO_RsiBuffers(d, rsi, rsiPrev, rsi2))
return;
datetime barTime = iTime(d.symbol, d.signalTF, 0);
bool isNew = (barTime != d.lastBar);
if(PositionExistsByMagic(d.symbol, d.magic))
{
RCO_ManageOpenPosition(d, rsi);
if(isNew)
d.lastBar = barTime;
return;
}
if(d.entryOnNewBarOnly && !isNew)
return;
d.lastBar = barTime;
if(!RCO_RegimeIsConsolidation(d))
return;
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, 1, atrArr) < 1)
return;
double atr = atrArr[0];
int dig = (int)SymbolInfoInteger(d.symbol, SYMBOL_DIGITS);
double slDist = atr * d.slAtrMult;
double tpDist = atr * d.tpAtrMult;
double minD = RCO_MinStopsDistancePrice(d.symbol);
if(slDist < minD)
slDist = minD;
if(tpDist < minD)
tpDist = minD;
double vol = RCO_NormalizeVolume(d.symbol, lots);
if(RCO_EntryBuyCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, true))
return;
double ask = SymbolInfoDouble(d.symbol, SYMBOL_ASK);
double sl = ask - slDist;
double tp = ask + tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Buy(vol, d.symbol, ask, sl, tp, "RSIConsolidation BUY"))
Print("RSIConsolidation BUY failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
else if(RCO_EntrySellCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, false))
return;
double bid = SymbolInfoDouble(d.symbol, SYMBOL_BID);
double sl = bid + slDist;
double tp = bid - tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Sell(vol, d.symbol, bid, sl, tp, "RSIConsolidation SELL"))
Print("RSIConsolidation SELL failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
}
#endif // RSI_CONSOLIDATION_STRATEGY_MQH
@@ -20,6 +20,23 @@ bool WeekDays_Check(datetime aTime)
return(rcData.WeekDays[stm.day_of_week]);
}
bool RC_HourInWindow(const int h, const int beginRaw, const int endRaw)
{
const int b = beginRaw % 24;
const int e = endRaw % 24;
if(b == e)
return false;
if(b < e)
return (h >= b && h < e);
return (h >= b || h < e);
}
bool RC_TradingHoursAllow(const int currentHour)
{
return RC_HourInWindow(currentHour, RC_tradingHourOneBegin, RC_tradingHourOneEnd)
|| RC_HourInWindow(currentHour, RC_tradingHourTwoBegin, RC_tradingHourTwoEnd);
}
int TimeHour(datetime when = 0)
{
if(when == 0) when = TimeCurrent();
@@ -151,8 +168,7 @@ void ProcessRSICrossOverReversal(string symbol)
return;
}
if(!((currentHour < RC_tradingHourOneEnd && currentHour > RC_tradingHourOneBegin) ||
(currentHour < RC_tradingHourTwoEnd && currentHour > RC_tradingHourTwoBegin)))
if(!RC_TradingHoursAllow(currentHour))
{
Close_Position_MN(RC_MagicNumber);
return;
@@ -173,7 +189,7 @@ void ProcessRSICrossOverReversal(string symbol)
double previousEMA = ema[1];
double emaSlope = (currentEMA - previousEMA) * 100;
double closeCurr = iClose(Symbol(), Period(), 0);
const double closeCurr = iClose(rcData.symbol, RC_TimeFrame1, 0);
double priceToEmaDistance = (closeCurr - currentEMA) * 10;
bool isBuyPosition = false;
@@ -211,10 +227,10 @@ void ProcessRSICrossOverReversal(string symbol)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
return;
}
if(currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
if(!isTrendStrong &&
currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
!isSellPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -223,8 +239,9 @@ void ProcessRSICrossOverReversal(string symbol)
rcData.lastTradeTime = currentTime;
}
}
if(currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
if(!isTrendStrong &&
currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
!isBuyPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -22,6 +22,104 @@ struct RSIScalpingData {
int bars_against_count;
};
void ClosePosition(RSIScalpingData& data, int MagicNumber);
double RS_ATRPriceOnTF(const string symbol, const ENUM_TIMEFRAMES tf, const int period)
{
if(period < 1)
return 0.0;
MqlRates rates[];
const int need = period + 2;
if(CopyRates(symbol, tf, 0, need, rates) < need)
return 0.0;
ArraySetAsSeries(rates, true);
double sum = 0.0;
for(int i = 1; i <= period; i++)
{
const double hl = rates[i].high - rates[i].low;
const double hc = MathAbs(rates[i].high - rates[i + 1].close);
const double lc = MathAbs(rates[i].low - rates[i + 1].close);
sum += MathMax(hl, MathMax(hc, lc));
}
return sum / (double)period;
}
int RS_CountReversalEscapeSigns(RSIScalpingData& data, const ENUM_TIMEFRAMES tf,
const ENUM_POSITION_TYPE ptype, const double atr,
const double adverseAtrMult, const double rsiVelocity,
const double bodyAtrMult)
{
if(atr <= 0.0)
return 0;
const double entry = PositionGetDouble(POSITION_PRICE_OPEN);
const double bid = SymbolInfoDouble(data.symbol, SYMBOL_BID);
const double ask = SymbolInfoDouble(data.symbol, SYMBOL_ASK);
int signs = 0;
if(ptype == POSITION_TYPE_BUY)
{
if(entry - bid >= adverseAtrMult * atr)
signs++;
if(data.rsi_prev - data.rsi_current >= rsiVelocity)
signs++;
}
else if(ptype == POSITION_TYPE_SELL)
{
if(ask - entry >= adverseAtrMult * atr)
signs++;
if(data.rsi_current - data.rsi_prev >= rsiVelocity)
signs++;
}
else
return 0;
MqlRates r[];
if(CopyRates(data.symbol, tf, 0, 4, r) >= 4)
{
ArraySetAsSeries(r, true);
const double body = MathAbs(r[1].close - r[1].open);
if(body >= bodyAtrMult * atr)
{
if(ptype == POSITION_TYPE_BUY && r[1].close < r[1].open)
signs++;
else if(ptype == POSITION_TYPE_SELL && r[1].close > r[1].open)
signs++;
}
if(ptype == POSITION_TYPE_BUY)
{
if(r[1].close < r[2].close && r[2].close < r[3].close)
signs++;
}
else
{
if(r[1].close > r[2].close && r[2].close > r[3].close)
signs++;
}
}
return signs;
}
void RS_TryReversalEscape(RSIScalpingData& data, const ENUM_TIMEFRAMES tf, const int MagicNumber,
const int atrPeriod, const double adverseAtrMult, const int signsRequired,
const double rsiVelocity, const double bodyAtrMult)
{
if(!PositionSelectByMagic(data.symbol, (ulong)MagicNumber))
return;
const ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
const double atr = RS_ATRPriceOnTF(data.symbol, tf, atrPeriod);
if(atr <= 0.0)
return;
const int n = RS_CountReversalEscapeSigns(data, tf, ptype, atr, adverseAtrMult, rsiVelocity, bodyAtrMult);
if(n < signsRequired)
return;
ClosePosition(data, MagicNumber);
Print("RSIScalping: reversal escape symbol=", data.symbol, " signs=", n, " need=", signsRequired,
" ATR=", DoubleToString(atr, (int)SymbolInfoInteger(data.symbol, SYMBOL_DIGITS)));
}
string ErrorDescription(int errorCode)
{
switch(errorCode)
@@ -420,7 +518,9 @@ void ClosePosition(RSIScalpingData& data, int MagicNumber)
void ProcessRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES TimeFrame, int RSI_Period,
ENUM_APPLIED_PRICE RSI_Applied_Price, double RSI_Overbought,
double RSI_Oversold, double RSI_Target_Buy, double RSI_Target_Sell,
int BarsToWait, double LotSize, int MagicNumber)
int BarsToWait, double LotSize, int MagicNumber,
bool UseReversalEscape, int ReversalATRPeriod, double ReversalAdverseAtrMult,
int ReversalSignsRequired, double ReversalRsiVelocity, double ReversalBodyAtrMult)
{
// Skip if not initialized (symbol not available)
if(!data.isInitialized)
@@ -429,16 +529,25 @@ void ProcessRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES Ti
data.symbol = symbol; // Update symbol in case it changed
if(Bars(data.symbol, TimeFrame) < RSI_Period + 2)
return;
datetime current_bar_time = iTime(data.symbol, TimeFrame, 0);
if(current_bar_time == data.last_bar_time)
const datetime current_bar_time = iTime(data.symbol, TimeFrame, 0);
const bool new_bar = (current_bar_time != data.last_bar_time);
const bool in_pos = data.position_open || PositionExistsByMagic(data.symbol, MagicNumber);
if(!in_pos && !new_bar)
return;
data.last_bar_time = current_bar_time;
if(!UpdateRSI(data))
return;
if(in_pos && UseReversalEscape)
RS_TryReversalEscape(data, TimeFrame, MagicNumber, ReversalATRPeriod, ReversalAdverseAtrMult,
ReversalSignsRequired, ReversalRsiVelocity, ReversalBodyAtrMult);
if(!new_bar)
return;
data.last_bar_time = current_bar_time;
CheckExistingPosition(data, TimeFrame, MagicNumber, RSI_Oversold, RSI_Overbought,
RSI_Target_Buy, RSI_Target_Sell, BarsToWait);
@@ -0,0 +1,495 @@
//+------------------------------------------------------------------+
//| SuperEMAStrategy.mqh — EMA + CCI + MACD (United EA module) |
//+------------------------------------------------------------------+
#ifndef SUPER_EMA_STRATEGY_MQH
#define SUPER_EMA_STRATEGY_MQH
#include <Trade/Trade.mqh>
enum ENUM_SE_ENTRY_STYLE
{
SE_ENTRY_CCIZERO_MACD = 0,
SE_ENTRY_LAMBERT = 1,
SE_ENTRY_PULLBACK = 2
};
struct SuperEMAData
{
string symbol;
ENUM_TIMEFRAMES tf;
datetime lastBarTime;
CTrade trade;
bool isInitialized;
int slippagePoints;
int magic;
int emaFast;
int emaMid;
int emaSlow;
int emaTrendBars;
int cciPeriod;
double cciOverbought;
double cciOversold;
int pullbackCciLookback;
int macdFast;
int macdSlow;
int macdSignal;
ENUM_SE_ENTRY_STYLE entryStyle;
bool oneTradeOnly;
bool useStructuralSL;
double slBufferPoints;
bool exitOnTrendFlip;
bool exitOnMacdFlip;
bool exitOnCciZeroCross;
int maxHoldingBars;
bool exitBelowMidEma;
bool debugLogs;
};
void SuperEMA_Log(SuperEMAData &d, const string s)
{
if(d.debugLogs)
Print("[SuperEMA] ", s);
}
bool SuperEMA_IsNewBar(SuperEMAData &d)
{
datetime t = iTime(d.symbol, d.tf, 0);
if(t <= 0 || t == d.lastBarTime)
return false;
d.lastBarTime = t;
return true;
}
double SuperEMA_EmaAt(SuperEMAData &d, const int period, const int shift)
{
int h = iMA(d.symbol, d.tf, period, 0, MODE_EMA, PRICE_CLOSE);
if(h == INVALID_HANDLE)
return 0.0;
double b[1];
if(CopyBuffer(h, 0, shift, 1, b) <= 0)
{
IndicatorRelease(h);
return 0.0;
}
IndicatorRelease(h);
return b[0];
}
double SuperEMA_CciAt(SuperEMAData &d, const int shift)
{
int h = iCCI(d.symbol, d.tf, d.cciPeriod, PRICE_TYPICAL);
if(h == INVALID_HANDLE)
return 0.0;
double b[1];
if(CopyBuffer(h, 0, shift, 1, b) <= 0)
{
IndicatorRelease(h);
return 0.0;
}
IndicatorRelease(h);
return b[0];
}
bool SuperEMA_MacdHistAt(SuperEMAData &d, const int shift, double &hist)
{
int h = iMACD(d.symbol, d.tf, d.macdFast, d.macdSlow, d.macdSignal, PRICE_CLOSE);
if(h == INVALID_HANDLE)
return false;
double mainLine[1], sigLine[1];
if(CopyBuffer(h, 0, shift, 1, mainLine) <= 0 || CopyBuffer(h, 1, shift, 1, sigLine) <= 0)
{
IndicatorRelease(h);
return false;
}
IndicatorRelease(h);
hist = mainLine[0] - sigLine[0];
return true;
}
bool SuperEMA_TrendUp(SuperEMAData &d, const int sh)
{
double c = iClose(d.symbol, d.tf, sh);
double emaS = SuperEMA_EmaAt(d, d.emaSlow, sh);
return (emaS > 0.0 && c > emaS);
}
bool SuperEMA_TrendDown(SuperEMAData &d, const int sh)
{
double c = iClose(d.symbol, d.tf, sh);
double emaS = SuperEMA_EmaAt(d, d.emaSlow, sh);
return (emaS > 0.0 && c < emaS);
}
bool SuperEMA_CciCrossAboveZero(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 <= 0.0 && c1 > 0.0);
}
bool SuperEMA_CciCrossBelowZero(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 >= 0.0 && c1 < 0.0);
}
bool SuperEMA_CciCrossAbove100(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 < d.cciOverbought && c1 > d.cciOverbought);
}
bool SuperEMA_CciCrossBelowMinus100(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 > d.cciOversold && c1 < d.cciOversold);
}
bool SuperEMA_HadCciOversoldRecently(SuperEMAData &d)
{
for(int i = 2; i <= d.pullbackCciLookback + 1; i++)
{
double v = SuperEMA_CciAt(d, i);
if(v <= d.cciOversold)
return true;
}
return false;
}
bool SuperEMA_HadCciOverboughtRecently(SuperEMAData &d)
{
for(int i = 2; i <= d.pullbackCciLookback + 1; i++)
{
double v = SuperEMA_CciAt(d, i);
if(v >= d.cciOverbought)
return true;
}
return false;
}
bool SuperEMA_PullbackNearFastEmaLong(SuperEMAData &d)
{
double emaF = SuperEMA_EmaAt(d, d.emaFast, 1);
double lo = iLow(d.symbol, d.tf, 1);
if(emaF <= 0.0)
return false;
return (lo <= emaF + d.slBufferPoints * _Point * 3.0);
}
bool SuperEMA_PullbackNearFastEmaShort(SuperEMAData &d)
{
double emaF = SuperEMA_EmaAt(d, d.emaFast, 1);
double hi = iHigh(d.symbol, d.tf, 1);
if(emaF <= 0.0)
return false;
return (hi >= emaF - d.slBufferPoints * _Point * 3.0);
}
int SuperEMA_PositionsByMagic(SuperEMAData &d)
{
int n = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t == 0)
continue;
if(PositionGetString(POSITION_SYMBOL) == d.symbol && (int)PositionGetInteger(POSITION_MAGIC) == d.magic)
n++;
}
return n;
}
void SuperEMA_ComputeSLTP(SuperEMAData &d, const bool isBuy, double &sl, double &tp)
{
sl = 0.0;
tp = 0.0;
if(!d.useStructuralSL)
return;
double emaM = SuperEMA_EmaAt(d, d.emaMid, d.emaTrendBars);
double buf = d.slBufferPoints * _Point;
if(isBuy)
sl = emaM - buf;
else
sl = emaM + buf;
}
int SuperEMA_BarsSinceOpen(SuperEMAData &d, const datetime openTime)
{
if(openTime <= 0)
return 0;
int sh = iBarShift(d.symbol, d.tf, openTime, false);
if(sh < 0)
return 999999;
return sh;
}
void SuperEMA_CloseTicket(SuperEMAData &d, const ulong ticket, const string reason)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
d.trade.SetExpertMagicNumber(d.magic);
if(d.trade.PositionClose(ticket))
SuperEMA_Log(d, "Close: " + reason);
}
void SuperEMA_ManageExits(SuperEMAData &d)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetString(POSITION_SYMBOL) != d.symbol)
continue;
if((int)PositionGetInteger(POSITION_MAGIC) != d.magic)
continue;
ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openTime = (datetime)PositionGetInteger(POSITION_TIME);
double h1 = 0.0;
if(!SuperEMA_MacdHistAt(d, 1, h1))
continue;
bool closeLong = false;
bool closeShort = false;
string reason = "";
if(d.maxHoldingBars > 0)
{
int held = SuperEMA_BarsSinceOpen(d, openTime);
if(held >= d.maxHoldingBars)
{
if(ptype == POSITION_TYPE_BUY)
closeLong = true;
else
closeShort = true;
reason = "time stop (max bars)";
}
}
if(ptype == POSITION_TYPE_BUY)
{
if(d.exitOnTrendFlip && SuperEMA_TrendDown(d, d.emaTrendBars))
{
closeLong = true;
reason = "trend flip (below slow EMA)";
}
if(d.exitOnMacdFlip && h1 < 0.0)
{
closeLong = true;
reason = "MACD histogram < 0";
}
if(d.exitOnCciZeroCross && SuperEMA_CciCrossBelowZero(d))
{
closeLong = true;
reason = "CCI crossed below zero";
}
if(d.exitBelowMidEma)
{
double c = iClose(d.symbol, d.tf, 1);
double emaM = SuperEMA_EmaAt(d, d.emaMid, 1);
if(emaM > 0.0 && c < emaM)
{
closeLong = true;
reason = "close below mid EMA";
}
}
if(closeLong)
SuperEMA_CloseTicket(d, ticket, reason);
}
else if(ptype == POSITION_TYPE_SELL)
{
if(d.exitOnTrendFlip && SuperEMA_TrendUp(d, d.emaTrendBars))
{
closeShort = true;
reason = "trend flip (above slow EMA)";
}
if(d.exitOnMacdFlip && h1 > 0.0)
{
closeShort = true;
reason = "MACD histogram > 0";
}
if(d.exitOnCciZeroCross && SuperEMA_CciCrossAboveZero(d))
{
closeShort = true;
reason = "CCI crossed above zero";
}
if(d.exitBelowMidEma)
{
double c = iClose(d.symbol, d.tf, 1);
double emaM = SuperEMA_EmaAt(d, d.emaMid, 1);
if(emaM > 0.0 && c > emaM)
{
closeShort = true;
reason = "close above mid EMA";
}
}
if(closeShort)
SuperEMA_CloseTicket(d, ticket, reason);
}
}
}
bool InitSuperEMA(SuperEMAData &d,
const string symbol,
const ENUM_TIMEFRAMES tf,
const int slippagePoints,
const int magic,
const int emaFast,
const int emaMid,
const int emaSlow,
const int emaTrendBars,
const int cciPeriod,
const double cciOverbought,
const double cciOversold,
const int pullbackCciLookback,
const int macdFast,
const int macdSlow,
const int macdSignal,
const ENUM_SE_ENTRY_STYLE entryStyle,
const bool oneTradeOnly,
const bool useStructuralSL,
const double slBufferPoints,
const bool exitOnTrendFlip,
const bool exitOnMacdFlip,
const bool exitOnCciZeroCross,
const int maxHoldingBars,
const bool exitBelowMidEma,
const bool debugLogs)
{
d.symbol = symbol;
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.tf = tf;
d.lastBarTime = 0;
d.isInitialized = false;
d.slippagePoints = slippagePoints;
d.magic = magic;
d.emaFast = emaFast;
d.emaMid = emaMid;
d.emaSlow = emaSlow;
d.emaTrendBars = emaTrendBars;
d.cciPeriod = cciPeriod;
d.cciOverbought = cciOverbought;
d.cciOversold = cciOversold;
d.pullbackCciLookback = pullbackCciLookback;
d.macdFast = macdFast;
d.macdSlow = macdSlow;
d.macdSignal = macdSignal;
d.entryStyle = entryStyle;
d.oneTradeOnly = oneTradeOnly;
d.useStructuralSL = useStructuralSL;
d.slBufferPoints = slBufferPoints;
d.exitOnTrendFlip = exitOnTrendFlip;
d.exitOnMacdFlip = exitOnMacdFlip;
d.exitOnCciZeroCross = exitOnCciZeroCross;
d.maxHoldingBars = maxHoldingBars;
d.exitBelowMidEma = exitBelowMidEma;
d.debugLogs = debugLogs;
if(!SymbolSelect(d.symbol, true))
{
Print("SuperEMA: symbol not available: ", d.symbol);
return false;
}
d.trade.SetExpertMagicNumber(d.magic);
d.trade.SetDeviationInPoints(d.slippagePoints);
d.isInitialized = true;
return true;
}
void ProcessSuperEMA(SuperEMAData &d, const double lots)
{
if(!d.isInitialized)
return;
if(!SuperEMA_IsNewBar(d))
return;
SuperEMA_ManageExits(d);
const int sh = d.emaTrendBars;
double h1 = 0.0, h2 = 0.0;
if(!SuperEMA_MacdHistAt(d, 1, h1) || !SuperEMA_MacdHistAt(d, 2, h2))
return;
bool up = SuperEMA_TrendUp(d, sh);
bool dn = SuperEMA_TrendDown(d, sh);
bool wantBuy = false;
bool wantSell = false;
switch(d.entryStyle)
{
case SE_ENTRY_CCIZERO_MACD:
if(up && SuperEMA_CciCrossAboveZero(d) && h1 > 0.0)
wantBuy = true;
if(dn && SuperEMA_CciCrossBelowZero(d) && h1 < 0.0)
wantSell = true;
break;
case SE_ENTRY_LAMBERT:
if(up && SuperEMA_CciCrossAbove100(d) && h1 > 0.0)
wantBuy = true;
if(dn && SuperEMA_CciCrossBelowMinus100(d) && h1 < 0.0)
wantSell = true;
break;
case SE_ENTRY_PULLBACK:
if(up && SuperEMA_HadCciOversoldRecently(d) && SuperEMA_CciCrossAboveZero(d) && h1 > 0.0 && SuperEMA_PullbackNearFastEmaLong(d))
wantBuy = true;
if(dn && SuperEMA_HadCciOverboughtRecently(d) && SuperEMA_CciCrossBelowZero(d) && h1 < 0.0 && SuperEMA_PullbackNearFastEmaShort(d))
wantSell = true;
break;
}
if(d.oneTradeOnly && SuperEMA_PositionsByMagic(d) > 0)
{
if(wantBuy && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, true))
wantBuy = false;
if(wantSell && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, false))
wantSell = false;
if(!wantBuy && !wantSell)
return;
}
MqlTick tick;
if(!SymbolInfoTick(d.symbol, tick))
return;
double sl = 0.0, tp = 0.0;
if(wantBuy && !wantSell)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, true, sl, tp);
#endif
if(d.trade.Buy(lots, d.symbol, tick.ask, sl, tp, "United SuperEMA long"))
SuperEMA_Log(d, StringFormat("BUY ask=%.5f sl=%.5f", tick.ask, sl));
}
else if(wantSell && !wantBuy)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, false, sl, tp);
#endif
if(d.trade.Sell(lots, d.symbol, tick.bid, sl, tp, "United SuperEMA short"))
SuperEMA_Log(d, StringFormat("SELL bid=%.5f sl=%.5f", tick.bid, sl));
}
}
void DeinitSuperEMA(SuperEMAData &d)
{
d.isInitialized = false;
}
#endif // SUPER_EMA_STRATEGY_MQH
@@ -0,0 +1,704 @@
//+------------------------------------------------------------------+
//| UnitedEA.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"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Indicators\Trend.mqh>
#include <Indicators\Volumes.mqh>
#include "MagicNumberHelpers.mqh"
// Include strategy implementations early so structs are available
#include "Strategies/DarvasBoxStrategy.mqh"
#include "Strategies/EMASlopeDistanceStrategy.mqh"
#include "Strategies/RSICrossOverReversalStrategy.mqh"
#include "Strategies/RSIMidPointHijackStrategy.mqh"
#include "Strategies/RSIScalpingStrategy.mqh"
#include "Strategies/SuperEMAStrategy.mqh"
#include "Strategies/RSIReversalAsianStrategy.mqh"
#include "Strategies/RSIConsolidationStrategy.mqh"
//+------------------------------------------------------------------+
//| Global Lot Size Variables (for dynamic lot sizing) |
//+------------------------------------------------------------------+
double g_ES_LotSize; // EMA Slope Distance lot size
double g_RC_LotSize; // RSI CrossOver Reversal lot size
double g_RM_LotSize; // RSI MidPoint Hijack lot size
bool United_MayOpenNewEntry(const string symbol, const ulong magic, const bool isBuy)
{
if(PositionExistsByMagic(symbol, magic))
return false;
return true;
}
//+------------------------------------------------------------------+
//| Strategy Enable/Disable Switches |
//+------------------------------------------------------------------+
input group "=== Strategy Enable/Disable ==="
input bool EnableDarvasBox = true;
input bool EnableEMASlopeDistance = true;
input bool EnableRSICrossOverReversal = true;
input bool EnableRSIMidPointHijack = true;
input bool EnableRSIScalpingAPPL = true;
input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
input bool EnableSuperEMA = true;
input bool EnableRSIConsolidation = true;
input bool EnableRSIReversalAsianEURUSD = true;
input bool EnableRSIReversalAsianAUDUSD = true;
input group "=== Centralized Lot Size (Granular Per Robot) ==="
input double LOT_ES_EMASlopeDistance = 0.05;
input double LOT_RC_RSICrossOver = 0.1;
input double LOT_RM_RSIMidPointHijack = 0.01;
input double LOT_RS_APPL = 100.0;
input double LOT_RS_BTCUSD = 0.15;
input double LOT_RS_NVDA = 60.0;
input double LOT_RS_TSLA = 20.0;
input double LOT_RS_XAUUSD = 0.02;
input double LOT_RRA_EURUSD = 0.01;
input double LOT_RRA_AUDUSD = 0.10;
input double LOT_SE_SuperEMA = 0.01;
input double LOT_RCO_RSIConsolidation = 0.04;
//+------------------------------------------------------------------+
//| Strategy 1: DarvasBoxXAUUSD |
//+------------------------------------------------------------------+
input group "=== DarvasBox Strategy ==="
input string DB_Symbol = "XAUUSD";
input int DB_BoxPeriod = 165;
input double DB_BoxDeviation = 30000; // Increased to allow larger ranges (was 25140)
input int DB_VolumeThreshold = 0; // Set to 0 to disable volume threshold check. Volume data from indicator used instead.
input double DB_StopLoss = 1665;
input double DB_TakeProfit = 3685;
input bool DB_EnableLogging = false;
input color DB_BoxColor = clrBlue;
input int DB_BoxWidth = 1;
input ENUM_TIMEFRAMES DB_TrendTimeframe = PERIOD_H2;
input int DB_MA_Period = 125;
input ENUM_MA_METHOD DB_MA_Method = MODE_EMA;
input ENUM_APPLIED_PRICE DB_MA_Price = PRICE_WEIGHTED;
input double DB_TrendThreshold = 4.94;
input int DB_VolumeMA_Period = 110;
input double DB_VolumeThresholdMultiplier = 1.5;
input int DB_MagicNumber = 135790;
//+------------------------------------------------------------------+
//| Strategy 2: EMASlopeDistanceCocktailXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== EMA Slope Distance Strategy ==="
input string ES_Symbol = "XAUUSD";
input int ES_EMA_Periode = 46;
input double ES_PreisSchwelle = 600.0;
input double ES_SteigungSchwelle = 80.0;
input int ES_ÜberwachungTimeout = 800;
input double ES_TrailingStop = 250.0;
input double ES_LotGröße = 0.03;
input int ES_MagicNumber = 12350;
input bool ES_UseSpreadAdjustment = true;
input ENUM_TIMEFRAMES ES_Timeframe = PERIOD_H1;
input bool ES_UseBarData = true;
input int ES_MaxTradesPerCrossover = 9;
input int ES_ProfitCheckBars = 18;
input bool ES_CloseUnprofitableTrades = true;
//+------------------------------------------------------------------+
//| Strategy 3: RSICrossOverReversalXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI CrossOver Reversal Strategy ==="
input string RC_Symbol = "XAUUSD";
input int RC_MagicNumber = 7;
input int RC_rsiPeriod = 19;
input int RC_overboughtLevel = 93;
input int RC_oversoldLevel = 22;
input double RC_entryRSIBuySpread = 0;
input double RC_entryRSISellSpread = 0;
input double RC_lotSize = 0.01;
input int RC_slippage = 3;
input int RC_cooldownSeconds = 209;
input ENUM_TIMEFRAMES RC_TimeFrame1 = PERIOD_M1;
input ENUM_TIMEFRAMES RC_TimeFrame2 = PERIOD_M1;
input ENUM_TIMEFRAMES RC_BarTimeFrame = PERIOD_M12;
input int RC_emaPeriod = 140;
input double RC_emaSlopeThreshold = 105;
input double RC_exitBuyRSI = 86;
input double RC_exitSellRSI = 10;
input double RC_TrailingStop = 295;
input double RC_emaDistanceThreshold = 165;
input int RC_tradingHourOneBegin = 24;
input int RC_tradingHourOneEnd = 22;
input int RC_tradingHourTwoBegin = 6;
input int RC_tradingHourTwoEnd = 19;
input bool RC_Sunday = false;
input bool RC_Monday = false;
input bool RC_Tuesday = true;
input bool RC_Wednesday = true;
input bool RC_Thursday = true;
input bool RC_Friday = false;
input bool RC_Saturday = false;
//+------------------------------------------------------------------+
//| Strategy 4: RSIMidPointHijackXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI MidPoint Hijack Strategy ==="
input string RM_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RM_InpTimeframe = PERIOD_H1;
input double RM_InpLotSize = 0.02;
input int RM_InpMagicNumberRSIFollow = 1001;
input int RM_InpMagicNumberRSIReverse = 1002;
input int RM_InpMagicNumberEMACross = 1003;
input bool RM_InpEnableRSIFollow = true;
input bool RM_InpEnableRSIReverse = true;
input bool RM_InpEnableEMACross = true;
input bool RM_InpEnableStrategyLock = false;
input double RM_InpLockProfitThreshold = 0.0;
input bool RM_InpCloseOppositeTrades = false;
input int RM_InpRSIPeriod = 32;
input int RM_InpRSIOverbought = 78;
input int RM_InpRSIOversold = 46;
input int RM_InpRSIExitLevel = 44;
input int RM_InpRSIFollowStartHour = 23;
input int RM_InpRSIFollowEndHour = 8;
input bool RM_InpRSIFollowCloseOutsideHours = false;
input int RM_InpRSIReversePeriod = 59;
input int RM_InpRSIReverseOverbought = 51;
input int RM_InpRSIReverseOversold = 49;
input int RM_InpRSIReverseCrossLevel = 53;
input int RM_InpRSIReverseExitLevel = 48;
input int RM_InpRSIReverseStartHour = 7;
input int RM_InpRSIReverseEndHour = 13;
input bool RM_InpRSIReverseCloseOutsideHours = false;
input int RM_InpRSIReverseCooldownBars = 15;
input bool RM_InpRSIReverseCooldownOnLoss = true;
input int RM_InpEMAPeriod = 120;
input int RM_InpEMACrossStartHour = 8;
input int RM_InpEMACrossEndHour = 14;
input bool RM_InpEMACrossCloseOutsideHours = true;
input bool RM_InpUseEMADistanceEntry = true;
input double RM_InpEMADistancePips = 160.0;
input int RM_InpEMADistancePeriod = 26;
//+------------------------------------------------------------------+
//| Strategy 5-10: RSI Scalping Strategies |
//| Each RSI Scalping strategy trades on its own symbol: |
//| - APPL: Apple stock (AAPL) |
//| - BTCUSD: Bitcoin/USD |
//| - NVDA: NVIDIA stock |
//| - TSLA: Tesla stock |
//| - XAUUSD: Gold/USD |
//| |
//| PEPPERSTONE US SYMBOL FORMATS: |
//| - Stocks may use: "AAPL.US", "NASDAQ:AAPL", or just "AAPL" |
//| - To find correct symbols: |
//| 1. Open Market Watch (Ctrl+M) |
//| 2. Right-click > Show All |
//| 3. Search for the stock name |
//| 4. Use the exact symbol name shown |
//+------------------------------------------------------------------+
input group "=== RSI Scalping APPL (AAPL) - Pepperstone US ==="
input string RS_APPL_Symbol = "AAPL.US"; // Try: "AAPL.US", "NASDAQ:AAPL", or "AAPL"
input ENUM_TIMEFRAMES RS_APPL_TimeFrame = PERIOD_M10;
input int RS_APPL_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_APPL_RSI_Applied_Price = PRICE_CLOSE;
input double RS_APPL_RSI_Overbought = 80;
input double RS_APPL_RSI_Oversold = 78;
input double RS_APPL_RSI_Target_Buy = 94;
input double RS_APPL_RSI_Target_Sell = 44;
input int RS_APPL_BarsToWait = 7;
input double RS_APPL_LotSize = 25;
input int RS_APPL_MagicNumber = 20001;
input int RS_APPL_Slippage = 3;
input group "=== RSI Scalping BTCUSD ==="
input string RS_BTCUSD_Symbol = "BTCUSD"; // Pepperstone may use: "BTCUSD", "BTC/USD", or "BTCUSD.c"
input ENUM_TIMEFRAMES RS_BTCUSD_TimeFrame = PERIOD_H1;
input int RS_BTCUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_BTCUSD_RSI_Applied_Price = PRICE_CLOSE;
input double RS_BTCUSD_RSI_Overbought = 90;
input double RS_BTCUSD_RSI_Oversold = 73;
input double RS_BTCUSD_RSI_Target_Buy = 88;
input double RS_BTCUSD_RSI_Target_Sell = 48;
input int RS_BTCUSD_BarsToWait = 6;
input double RS_BTCUSD_LotSize = 0.1;
input int RS_BTCUSD_MagicNumber = 123459123;
input int RS_BTCUSD_Slippage = 3;
input group "=== RSI Scalping NVDA - Pepperstone US ==="
input string RS_NVDA_Symbol = "NVDA.US"; // Try: "NVDA.US", "NASDAQ:NVDA", or "NVDA"
input ENUM_TIMEFRAMES RS_NVDA_TimeFrame = PERIOD_M15;
input int RS_NVDA_RSI_Period = 8;
input ENUM_APPLIED_PRICE RS_NVDA_RSI_Applied_Price = PRICE_CLOSE;
input double RS_NVDA_RSI_Overbought = 36;
input double RS_NVDA_RSI_Oversold = 38;
input double RS_NVDA_RSI_Target_Buy = 90;
input double RS_NVDA_RSI_Target_Sell = 70;
input int RS_NVDA_BarsToWait = 5;
input double RS_NVDA_LotSize = 50;
input int RS_NVDA_MagicNumber = 20003;
input int RS_NVDA_Slippage = 3;
input group "=== RSI Scalping TSLA - Pepperstone US ==="
input string RS_TSLA_Symbol = "TSLA.US"; // Try: "TSLA.US", "NASDAQ:TSLA", or "TSLA"
input ENUM_TIMEFRAMES RS_TSLA_TimeFrame = PERIOD_H1;
input int RS_TSLA_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_TSLA_RSI_Applied_Price = PRICE_CLOSE;
input double RS_TSLA_RSI_Overbought = 54;
input double RS_TSLA_RSI_Oversold = 73;
input double RS_TSLA_RSI_Target_Buy = 87;
input double RS_TSLA_RSI_Target_Sell = 33;
input int RS_TSLA_BarsToWait = 1;
input double RS_TSLA_LotSize = 50;
input int RS_TSLA_MagicNumber = 125421321;
input int RS_TSLA_Slippage = 3;
input group "=== RSI Scalping XAUUSD ==="
input string RS_XAUUSD_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RS_XAUUSD_TimeFrame = PERIOD_H1;
input int RS_XAUUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_XAUUSD_RSI_Applied_Price = PRICE_CLOSE;
input double RS_XAUUSD_RSI_Overbought = 71;
input double RS_XAUUSD_RSI_Oversold = 57;
input double RS_XAUUSD_RSI_Target_Buy = 80;
input double RS_XAUUSD_RSI_Target_Sell = 57;
input int RS_XAUUSD_BarsToWait = 4;
input double RS_XAUUSD_LotSize = 0.1;
input int RS_XAUUSD_MagicNumber = 129102315;
input int RS_XAUUSD_Slippage = 3;
input group "=== RSI Scalping Reversal Escape (XAUUSD only) ==="
input bool RS_UseReversalEscape = true;
input int RS_ReversalATRPeriod = 14;
input double RS_ReversalAdverseAtrMult = 5.25;
input int RS_ReversalSignsRequired = 2;
input double RS_ReversalRsiVelocity = 16.0;
input double RS_ReversalBodyAtrMult = 5.1;
//+------------------------------------------------------------------+
//| Strategy 11-12: RSI Reversal Asian Strategies |
//| Each RSI Reversal Asian strategy trades on its own symbol: |
//| - EURUSD: Euro/USD |
//| - AUDUSD: Australian Dollar/USD |
//+------------------------------------------------------------------+
input group "=== RSI Reversal Asian EURUSD ==="
input string RRA_EURUSD_Symbol = "EURUSD";
input int RRA_EURUSD_RSIPeriod = 28;
input double RRA_EURUSD_OverboughtLevel = 60;
input double RRA_EURUSD_OversoldLevel = 8;
input int RRA_EURUSD_TakeProfitPips = 175;
input int RRA_EURUSD_StopLossPips = 5;
input double RRA_EURUSD_MaxLotSize = 0.1;
input int RRA_EURUSD_MaxSpread = 1000;
input int RRA_EURUSD_MaxDuration = 270;
input bool RRA_EURUSD_UseStopLoss = false;
input bool RRA_EURUSD_UseTakeProfit = false;
input bool RRA_EURUSD_UseRSIExit = true;
input double RRA_EURUSD_RSIExitLevel = 55;
input bool RRA_EURUSD_CloseOutsideSession = false;
input ENUM_TIMEFRAMES RRA_EURUSD_TimeFrame = PERIOD_M15;
input int RRA_EURUSD_MagicNumber = 30001;
input int RRA_EURUSD_Slippage = 3;
input group "=== RSI Reversal Asian AUDUSD ==="
input string RRA_AUDUSD_Symbol = "AUDUSD";
input int RRA_AUDUSD_RSIPeriod = 28;
input double RRA_AUDUSD_OverboughtLevel = 68;
input double RRA_AUDUSD_OversoldLevel = 30;
input int RRA_AUDUSD_TakeProfitPips = 175;
input int RRA_AUDUSD_StopLossPips = 5;
input double RRA_AUDUSD_MaxLotSize = 0.2;
input int RRA_AUDUSD_MaxSpread = 1000;
input int RRA_AUDUSD_MaxDuration = 340;
input bool RRA_AUDUSD_UseStopLoss = false;
input bool RRA_AUDUSD_UseTakeProfit = false;
input bool RRA_AUDUSD_UseRSIExit = true;
input double RRA_AUDUSD_RSIExitLevel = 48;
input bool RRA_AUDUSD_CloseOutsideSession = true;
input ENUM_TIMEFRAMES RRA_AUDUSD_TimeFrame = PERIOD_M15;
input int RRA_AUDUSD_MagicNumber = 30002;
input int RRA_AUDUSD_Slippage = 3;
input group "=== SuperEMA (EMA + CCI + MACD) ==="
input string SE_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES SE_Timeframe = PERIOD_M15;
input double SE_LotSize = 0.01;
input int SE_SlippagePoints = 55;
input int SE_MagicNumber = 940001;
input int SE_EmaFast = 40;
input int SE_EmaMid = 180;
input int SE_EmaSlow = 125;
input int SE_EmaTrendBars = 3;
input int SE_CciPeriod = 17;
input double SE_CciOverbought = 80.0;
input double SE_CciOversold = -140.0;
input int SE_PullbackCciLookback = 20;
input int SE_MacdFast = 14;
input int SE_MacdSlow = 38;
input int SE_MacdSignal = 9;
input ENUM_SE_ENTRY_STYLE SE_EntryStyle = SE_ENTRY_LAMBERT;
input bool SE_OneTradeOnly = true;
input bool SE_UseStructuralSL = false;
input double SE_SlBufferPoints = 110;
input bool SE_ExitOnTrendFlip = false;
input bool SE_ExitOnMacdFlip = false;
input bool SE_ExitOnCciZeroCross = true;
input int SE_MaxHoldingBars = 168;
input bool SE_ExitBelowMidEma = false;
input bool SE_DebugLogs = false;
input group "=== RSI Consolidation (ranging / mean-reversion) ==="
input string RCO_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RCO_SignalTF = PERIOD_M15;
input bool RCO_EntryOnNewBarOnly = true;
input int RCO_ADX_Period = 23;
input double RCO_ADX_Max = 29.0;
input bool RCO_UseATRRatioFilter = true;
input int RCO_ATR_Period = 8;
input int RCO_ATR_SMA_Period = 35;
input double RCO_ATR_Ratio_Max = 1.36;
input bool RCO_UseFlatEMAFilter = true;
input int RCO_EMA_Fast = 13;
input int RCO_EMA_Slow = 17;
input double RCO_EMA_Separation_MaxPct = 0.26;
input int RCO_RSI_Period = 8;
input ENUM_APPLIED_PRICE RCO_RSI_Price = PRICE_OPEN;
input double RCO_RSI_Oversold = 22.0;
input double RCO_RSI_Overbought = 63.0;
input bool RCO_UseRSI_MeanExit = true;
input double RCO_RSI_Exit_Long = 48.0;
input double RCO_RSI_Exit_Short = 52.0;
input double RCO_SL_ATR_Mult = 2.15;
input double RCO_TP_ATR_Mult = 2.40;
input int RCO_MaxBarsInTrade = 54;
input double RCO_Lots = 0.10;
input ulong RCO_MagicNumber = 20250420;
input int RCO_Slippage = 10;
input int RCO_MaxSpreadPoints = 28;
//+------------------------------------------------------------------+
//| Global Variables - DarvasBox |
//+------------------------------------------------------------------+
struct DarvasBoxData {
string symbol;
bool isInitialized;
double boxHigh;
double boxLow;
bool boxFormed;
datetime lastBoxTime;
string boxName;
double minStopLevel;
double point;
CTrade trade;
int maHandle;
int volumeHandle;
datetime lastBarTime;
};
//+------------------------------------------------------------------+
//| Global Variables - EMA Slope Distance |
//+------------------------------------------------------------------+
struct EMASlopeData {
string symbol;
bool isInitialized;
int ema_handle;
double ema_array[];
datetime letzte_überwachung_zeit;
bool überwachung_aktiv;
bool preis_trigger_aktiv;
bool steigung_trigger_aktiv;
int ticket;
CTrade trade;
int trades_in_current_crossover;
bool crossover_detected;
datetime trade_open_time;
datetime last_bar_time;
};
//+------------------------------------------------------------------+
//| Global Variables - RSI CrossOver Reversal |
//+------------------------------------------------------------------+
struct RSICrossOverData {
string symbol;
bool isInitialized;
int rsiHandle;
int emaHandle;
double previousRSIDef;
CTrade trade;
datetime lastTradeTime;
datetime bartime;
bool WeekDays[7];
datetime lastBarTime;
};
//+------------------------------------------------------------------+
//| Global Variables - RSI MidPoint Hijack |
//+------------------------------------------------------------------+
struct RSIMidPointData {
string symbol;
bool isInitialized;
int rsiHandle;
int rsiReverseHandle;
int emaHandle;
bool rsiOverbought;
bool rsiOversold;
bool rsiReverseOverbought;
bool rsiReverseOversold;
CTrade trade;
CPositionInfo positionInfo;
bool emaCrossBuySignal;
bool emaCrossSellSignal;
int emaCrossSignalBar;
datetime lastBarTime;
datetime rsiReverseLastCloseTime;
bool rsiReverseInCooldown;
double lastBarRSI;
double lastBarRSIReverse;
double lastBarEMA;
double lastBarClose;
double lastBarEMAPrev;
double lastBarClosePrev;
};
//+------------------------------------------------------------------+
//| Global Strategy Instances |
//+------------------------------------------------------------------+
DarvasBoxData dbData;
EMASlopeData esData;
RSICrossOverData rcData;
RSIMidPointData rmData;
RSIScalpingData rsAPPLData;
RSIScalpingData rsBTCUSDData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
SuperEMAData seData;
RSIConsolidationData rcoData;
//+------------------------------------------------------------------+
//| Global Variables - RSI Reversal Asian |
//+------------------------------------------------------------------+
RSIReversalAsianData rraEURUSDData;
RSIReversalAsianData rraAUDUSDData;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
int initResult = INIT_SUCCEEDED;
// Initialize global lot size variables
g_ES_LotSize = LOT_ES_EMASlopeDistance;
g_RC_LotSize = LOT_RC_RSICrossOver;
g_RM_LotSize = LOT_RM_RSIMidPointHijack;
// Initialize strategies - log warnings but don't fail entire EA if symbol unavailable
if(EnableDarvasBox)
if(!InitDarvasBox(DB_Symbol))
Print("Warning: DarvasBox strategy failed to initialize for symbol '", DB_Symbol, "'");
if(EnableEMASlopeDistance)
if(!InitEMASlopeDistance(ES_Symbol))
Print("Warning: EMASlopeDistance strategy failed to initialize for symbol '", ES_Symbol, "'");
if(EnableRSICrossOverReversal)
if(!InitRSICrossOverReversal(RC_Symbol))
Print("Warning: RSICrossOverReversal strategy failed to initialize for symbol '", RC_Symbol, "'");
if(EnableRSIMidPointHijack)
if(!InitRSIMidPointHijack(RM_Symbol))
Print("Warning: RSIMidPointHijack strategy failed to initialize for symbol '", RM_Symbol, "'");
// Initialize RSI Scalping strategies - don't fail entire EA if symbol unavailable
if(EnableRSIScalpingAPPL)
InitRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price, RS_APPL_MagicNumber, RS_APPL_Slippage);
if(EnableRSIScalpingBTCUSD)
InitRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price, RS_BTCUSD_MagicNumber, RS_BTCUSD_Slippage);
if(EnableRSIScalpingNVDA)
InitRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price, RS_NVDA_MagicNumber, RS_NVDA_Slippage);
if(EnableRSIScalpingTSLA)
InitRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price, RS_TSLA_MagicNumber, RS_TSLA_Slippage);
if(EnableRSIScalpingXAUUSD)
InitRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price, RS_XAUUSD_MagicNumber, RS_XAUUSD_Slippage);
if(EnableSuperEMA)
if(!InitSuperEMA(seData, SE_Symbol, SE_Timeframe, SE_SlippagePoints, SE_MagicNumber,
SE_EmaFast, SE_EmaMid, SE_EmaSlow, SE_EmaTrendBars,
SE_CciPeriod, SE_CciOverbought, SE_CciOversold, SE_PullbackCciLookback,
SE_MacdFast, SE_MacdSlow, SE_MacdSignal,
SE_EntryStyle, SE_OneTradeOnly, SE_UseStructuralSL, SE_SlBufferPoints,
SE_ExitOnTrendFlip, SE_ExitOnMacdFlip, SE_ExitOnCciZeroCross,
SE_MaxHoldingBars, SE_ExitBelowMidEma, SE_DebugLogs))
Print("Warning: SuperEMA failed to initialize for symbol '", SE_Symbol, "'");
if(EnableRSIConsolidation)
if(!InitRSIConsolidation(rcoData, RCO_Symbol, RCO_SignalTF, RCO_EntryOnNewBarOnly,
RCO_ADX_Period, RCO_ADX_Max, RCO_UseATRRatioFilter, RCO_ATR_Period, RCO_ATR_SMA_Period, RCO_ATR_Ratio_Max,
RCO_UseFlatEMAFilter, RCO_EMA_Fast, RCO_EMA_Slow, RCO_EMA_Separation_MaxPct,
RCO_RSI_Period, RCO_RSI_Price, RCO_RSI_Oversold, RCO_RSI_Overbought,
RCO_UseRSI_MeanExit, RCO_RSI_Exit_Long, RCO_RSI_Exit_Short, RCO_SL_ATR_Mult, RCO_TP_ATR_Mult,
RCO_MaxBarsInTrade, RCO_MagicNumber, RCO_Slippage, RCO_MaxSpreadPoints))
Print("Warning: RSIConsolidation failed to initialize for symbol '", RCO_Symbol, "'");
// Initialize RSI Reversal Asian strategies
if(EnableRSIReversalAsianEURUSD)
if(!InitRSIReversalAsian(rraEURUSDData, RRA_EURUSD_Symbol, RRA_EURUSD_RSIPeriod, RRA_EURUSD_OverboughtLevel, RRA_EURUSD_OversoldLevel,
RRA_EURUSD_TakeProfitPips, RRA_EURUSD_StopLossPips, LOT_RRA_EURUSD,
RRA_EURUSD_MaxSpread, RRA_EURUSD_MaxDuration, RRA_EURUSD_UseStopLoss,
RRA_EURUSD_UseTakeProfit, RRA_EURUSD_UseRSIExit, RRA_EURUSD_RSIExitLevel,
RRA_EURUSD_CloseOutsideSession, RRA_EURUSD_TimeFrame, RRA_EURUSD_MagicNumber, RRA_EURUSD_Slippage))
Print("Warning: RSIReversalAsianEURUSD strategy failed to initialize for symbol '", RRA_EURUSD_Symbol, "'");
if(EnableRSIReversalAsianAUDUSD)
if(!InitRSIReversalAsian(rraAUDUSDData, RRA_AUDUSD_Symbol, RRA_AUDUSD_RSIPeriod, RRA_AUDUSD_OverboughtLevel, RRA_AUDUSD_OversoldLevel,
RRA_AUDUSD_TakeProfitPips, RRA_AUDUSD_StopLossPips, LOT_RRA_AUDUSD,
RRA_AUDUSD_MaxSpread, RRA_AUDUSD_MaxDuration, RRA_AUDUSD_UseStopLoss,
RRA_AUDUSD_UseTakeProfit, RRA_AUDUSD_UseRSIExit, RRA_AUDUSD_RSIExitLevel,
RRA_AUDUSD_CloseOutsideSession, RRA_AUDUSD_TimeFrame, RRA_AUDUSD_MagicNumber, RRA_AUDUSD_Slippage))
Print("Warning: RSIReversalAsianAUDUSD strategy failed to initialize for symbol '", RRA_AUDUSD_Symbol, "'");
Print("United EA initialized. Active strategies: ",
(EnableDarvasBox ? "DarvasBox " : ""),
(EnableEMASlopeDistance ? "EMASlope " : ""),
(EnableRSICrossOverReversal ? "RSICrossOver " : ""),
(EnableRSIMidPointHijack ? "RSIMidPoint " : ""),
(EnableRSIScalpingAPPL ? "RSIScalpingAPPL " : ""),
(EnableRSIScalpingBTCUSD ? "RSIScalpingBTCUSD " : ""),
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""),
(EnableSuperEMA ? "SuperEMA " : ""),
(EnableRSIConsolidation ? "RSIConsolidation " : ""),
(EnableRSIReversalAsianEURUSD ? "RSIReversalAsianEURUSD " : ""),
(EnableRSIReversalAsianAUDUSD ? "RSIReversalAsianAUDUSD " : ""));
return initResult;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(EnableDarvasBox)
DeinitDarvasBox();
if(EnableEMASlopeDistance)
DeinitEMASlopeDistance();
if(EnableRSICrossOverReversal)
DeinitRSICrossOverReversal();
if(EnableRSIMidPointHijack)
DeinitRSIMidPointHijack();
if(EnableRSIScalpingAPPL)
DeinitRSIScalping(rsAPPLData);
if(EnableRSIScalpingBTCUSD)
DeinitRSIScalping(rsBTCUSDData);
if(EnableRSIScalpingNVDA)
DeinitRSIScalping(rsNVDAData);
if(EnableRSIScalpingTSLA)
DeinitRSIScalping(rsTSLAData);
if(EnableRSIScalpingXAUUSD)
DeinitRSIScalping(rsXAUUSDData);
if(EnableSuperEMA)
DeinitSuperEMA(seData);
if(EnableRSIConsolidation)
DeinitRSIConsolidation(rcoData);
if(EnableRSIReversalAsianEURUSD)
DeinitRSIReversalAsian(rraEURUSDData);
if(EnableRSIReversalAsianAUDUSD)
DeinitRSIReversalAsian(rraAUDUSDData);
Print("United EA deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(EnableDarvasBox)
ProcessDarvasBox(DB_Symbol);
if(EnableEMASlopeDistance)
ProcessEMASlopeDistance(ES_Symbol);
if(EnableRSICrossOverReversal)
ProcessRSICrossOverReversal(RC_Symbol);
if(EnableRSIMidPointHijack)
ProcessRSIMidPointHijack(RM_Symbol);
if(EnableRSIScalpingAPPL)
ProcessRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price,
RS_APPL_RSI_Overbought, RS_APPL_RSI_Oversold, RS_APPL_RSI_Target_Buy, RS_APPL_RSI_Target_Sell,
RS_APPL_BarsToWait, LOT_RS_APPL, RS_APPL_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingBTCUSD)
ProcessRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price,
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, LOT_RS_BTCUSD, RS_BTCUSD_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
RS_NVDA_BarsToWait, LOT_RS_NVDA, RS_NVDA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingTSLA)
ProcessRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price,
RS_TSLA_RSI_Overbought, RS_TSLA_RSI_Oversold, RS_TSLA_RSI_Target_Buy, RS_TSLA_RSI_Target_Sell,
RS_TSLA_BarsToWait, LOT_RS_TSLA, RS_TSLA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingXAUUSD)
ProcessRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price,
RS_XAUUSD_RSI_Overbought, RS_XAUUSD_RSI_Oversold, RS_XAUUSD_RSI_Target_Buy, RS_XAUUSD_RSI_Target_Sell,
RS_XAUUSD_BarsToWait, LOT_RS_XAUUSD, RS_XAUUSD_MagicNumber,
RS_UseReversalEscape, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIReversalAsianEURUSD)
ProcessRSIReversalAsian(rraEURUSDData, LOT_RRA_EURUSD);
if(EnableRSIReversalAsianAUDUSD)
ProcessRSIReversalAsian(rraAUDUSDData, LOT_RRA_AUDUSD);
if(EnableSuperEMA)
ProcessSuperEMA(seData, LOT_SE_SuperEMA);
if(EnableRSIConsolidation)
ProcessRSIConsolidation(rcoData, LOT_RCO_RSIConsolidation);
}
//+------------------------------------------------------------------+

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

@@ -25,6 +25,7 @@ input bool EnableRSICrossOverReversal = true;
input bool EnableRSIMidPointHijack = true;
input bool EnableRSIScalpingAPPL = true;
input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingMSFT = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
@@ -154,6 +155,7 @@ input int RM_InpEMADistancePeriod = 26;
//| Each RSI Scalping strategy trades on its own symbol: |
//| - APPL: Apple stock (AAPL) |
//| - BTCUSD: Bitcoin/USD |
//| - MSFT: Microsoft stock |
//| - NVDA: NVIDIA stock |
//| - TSLA: Tesla stock |
//| - XAUUSD: Gold/USD |
@@ -194,6 +196,20 @@ input double RS_BTCUSD_LotSize = 0.1;
input int RS_BTCUSD_MagicNumber = 123459123;
input int RS_BTCUSD_Slippage = 3;
input group "=== RSI Scalping MSFT - Pepperstone US ==="
input string RS_MSFT_Symbol = "MSFT.US"; // Try: "MSFT.US", "NASDAQ:MSFT", or "MSFT"
input ENUM_TIMEFRAMES RS_MSFT_TimeFrame = PERIOD_H3;
input int RS_MSFT_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_MSFT_RSI_Applied_Price = PRICE_CLOSE;
input double RS_MSFT_RSI_Overbought = 19;
input double RS_MSFT_RSI_Oversold = 50;
input double RS_MSFT_RSI_Target_Buy = 71;
input double RS_MSFT_RSI_Target_Sell = 70;
input int RS_MSFT_BarsToWait = 1;
input double RS_MSFT_LotSize = 50;
input int RS_MSFT_MagicNumber = 20002;
input int RS_MSFT_Slippage = 3;
input group "=== RSI Scalping NVDA - Pepperstone US ==="
input string RS_NVDA_Symbol = "NVDA.US"; // Try: "NVDA.US", "NASDAQ:NVDA", or "NVDA"
input ENUM_TIMEFRAMES RS_NVDA_TimeFrame = PERIOD_M15;
@@ -349,6 +365,7 @@ RSICrossOverData rcData;
RSIMidPointData rmData;
RSIScalpingData rsAPPLData;
RSIScalpingData rsBTCUSDData;
RSIScalpingData rsMSFTData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
@@ -363,6 +380,7 @@ double g_RC_LotSize = 0.01; // RSI CrossOver Reversal - start with minimum
double g_RM_LotSize = 0.01; // RSI MidPoint Hijack - start with minimum
double g_RS_APPL_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_BTCUSD_LotSize = 0.01; // Crypto - start with forex minimum (0.01)
double g_RS_MSFT_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_NVDA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_TSLA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_XAUUSD_LotSize = 0.01; // Forex - start with forex minimum (0.01)
@@ -446,6 +464,15 @@ int OnInit()
g_RS_BTCUSD_LotSize = minLot;
}
if(EnableRSIScalpingMSFT)
{
InitRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price, RS_MSFT_MagicNumber, RS_MSFT_Slippage);
RegisterStrategy("RSIScalpingMSFT", RS_MSFT_MagicNumber, RS_MSFT_LotSize, RS_MSFT_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_MSFT_Symbol);
g_RS_MSFT_LotSize = minLot;
}
if(EnableRSIScalpingNVDA)
{
InitRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price, RS_NVDA_MagicNumber, RS_NVDA_Slippage);
@@ -492,6 +519,9 @@ int OnInit()
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
@@ -509,6 +539,7 @@ int OnInit()
(EnableRSIMidPointHijack ? "RSIMidPoint " : ""),
(EnableRSIScalpingAPPL ? "RSIScalpingAPPL " : ""),
(EnableRSIScalpingBTCUSD ? "RSIScalpingBTCUSD " : ""),
(EnableRSIScalpingMSFT ? "RSIScalpingMSFT " : ""),
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""));
@@ -542,6 +573,9 @@ void OnDeinit(const int reason)
if(EnableRSIScalpingBTCUSD)
DeinitRSIScalping(rsBTCUSDData);
if(EnableRSIScalpingMSFT)
DeinitRSIScalping(rsMSFTData);
if(EnableRSIScalpingNVDA)
DeinitRSIScalping(rsNVDAData);
@@ -581,6 +615,9 @@ void OnTick()
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
@@ -613,6 +650,11 @@ void OnTick()
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, g_RS_BTCUSD_LotSize, RS_BTCUSD_MagicNumber);
if(EnableRSIScalpingMSFT)
ProcessRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price,
RS_MSFT_RSI_Overbought, RS_MSFT_RSI_Oversold, RS_MSFT_RSI_Target_Buy, RS_MSFT_RSI_Target_Sell,
RS_MSFT_BarsToWait, g_RS_MSFT_LotSize, RS_MSFT_MagicNumber);
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
@@ -104,7 +104,7 @@ bool IsStockSymbol(string symbol)
// String-based checks (.US, NASDAQ:, NYSE:, common tickers) are sufficient
// Common stock tickers (without .US suffix)
string commonStocks[] = {"AAPL", "NVDA", "TSLA", "GOOGL", "AMZN", "META", "AMD", "NFLX"};
string commonStocks[] = {"AAPL", "MSFT", "NVDA", "TSLA", "GOOGL", "AMZN", "META", "NFLX"};
for(int i = 0; i < ArraySize(commonStocks); i++)
{
if(StringFind(symbol, commonStocks[i]) == 0) return true;
@@ -195,9 +195,9 @@ bool PlaceOrder(ENUM_ORDER_TYPE orderType, double price, double sl, double tp)
// Use market price (0) instead of explicit price - this ensures market order execution
// In backtesting, explicit price might fail if price has moved
if(orderType == ORDER_TYPE_BUY)
result = dbData.trade.Buy(g_DB_LotSize, dbData.symbol, 0, sl, tp, "Darvas Box Breakout");
result = dbData.trade.Buy(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakout");
else
result = dbData.trade.Sell(g_DB_LotSize, dbData.symbol, 0, sl, tp, "Darvas Box Breakdown");
result = dbData.trade.Sell(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakdown");
// Always log errors, success only if logging enabled
if(result)
@@ -0,0 +1,387 @@
//+------------------------------------------------------------------+
//| RSIConsolidationStrategy.mqh |
//| Ported from cluster-0/RSIConsolidation/RSIConsolidation.mq5 |
//+------------------------------------------------------------------+
#ifndef RSI_CONSOLIDATION_STRATEGY_MQH
#define RSI_CONSOLIDATION_STRATEGY_MQH
struct RSIConsolidationData
{
string symbol;
bool isInitialized;
CTrade trade;
ENUM_TIMEFRAMES signalTF;
bool entryOnNewBarOnly;
int adxPeriod;
double adxMax;
bool useATRRatioFilter;
int atrPeriod;
int atrSmaPeriod;
double atrRatioMax;
bool useFlatEMAFilter;
int emaFast;
int emaSlow;
double emaSeparationMaxPct;
int rsiPeriod;
ENUM_APPLIED_PRICE rsiPrice;
double rsiOversold;
double rsiOverbought;
bool useRSIMeanExit;
double rsiExitLong;
double rsiExitShort;
double slAtrMult;
double tpAtrMult;
int maxBarsInTrade;
ulong magic;
int slippage;
int maxSpreadPoints;
int h_rsi;
int h_adx;
int h_atr;
int h_ema_fast;
int h_ema_slow;
datetime lastBar;
};
bool RCO_Copy1(const int handle, double &v)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(handle, 0, 0, 1, b) < 1)
return false;
v = b[0];
return true;
}
bool RCO_RsiBuffers(RSIConsolidationData &d, double &cur, double &prev, double &twoAgo)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(d.h_rsi, 0, 0, 3, b) < 3)
return false;
cur = b[0];
prev = b[1];
twoAgo = b[2];
return true;
}
double RCO_NormalizeVolume(const string sym, double vol)
{
double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
if(step > 0.0)
vol = MathFloor(vol / step) * step;
if(vol < minLot)
vol = minLot;
if(vol > maxLot)
vol = maxLot;
return vol;
}
int RCO_CurrentSpreadPoints(const string sym)
{
long spread = 0;
if(!SymbolInfoInteger(sym, SYMBOL_SPREAD, spread))
return 999999;
return (int)spread;
}
double RCO_MinStopsDistancePrice(const string sym)
{
long lvl = 0;
if(!SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL, lvl))
return 0;
double pt = SymbolInfoDouble(sym, SYMBOL_POINT);
if(pt <= 0)
return 0;
return (double)lvl * pt;
}
bool RCO_RegimeIsConsolidation(RSIConsolidationData &d)
{
double adx = 0;
if(!RCO_Copy1(d.h_adx, adx))
return false;
if(adx >= d.adxMax)
return false;
if(d.useATRRatioFilter)
{
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, d.atrSmaPeriod + 1, atrArr) < d.atrSmaPeriod + 1)
return false;
double sum = 0;
for(int i = 1; i <= d.atrSmaPeriod; i++)
sum += atrArr[i];
double smaAtr = sum / (double)d.atrSmaPeriod;
if(smaAtr <= 0.0)
return false;
double ratio = atrArr[0] / smaAtr;
if(ratio > d.atrRatioMax)
return false;
}
if(d.useFlatEMAFilter)
{
double ef[], es[];
ArraySetAsSeries(ef, true);
ArraySetAsSeries(es, true);
if(CopyBuffer(d.h_ema_fast, 0, 0, 1, ef) < 1)
return false;
if(CopyBuffer(d.h_ema_slow, 0, 0, 1, es) < 1)
return false;
double c = SymbolInfoDouble(d.symbol, SYMBOL_BID);
if(c <= 0)
return false;
double sep = MathAbs(ef[0] - es[0]) / c * 100.0;
if(sep > d.emaSeparationMaxPct)
return false;
}
return true;
}
bool RCO_EntryBuyCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo <= d.rsiOversold && prev > d.rsiOversold);
}
bool RCO_EntrySellCross(RSIConsolidationData &d, const double twoAgo, const double prev)
{
return (twoAgo >= d.rsiOverbought && prev < d.rsiOverbought);
}
void RCO_TryCloseByRSI(RSIConsolidationData &d, const ENUM_POSITION_TYPE typ, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
if(!d.useRSIMeanExit)
return;
if(typ == POSITION_TYPE_BUY && rsi >= d.rsiExitLong)
d.trade.PositionClose(tk);
else if(typ == POSITION_TYPE_SELL && rsi <= d.rsiExitShort)
d.trade.PositionClose(tk);
}
void RCO_ManageOpenPosition(RSIConsolidationData &d, const double rsi)
{
ulong tk = GetPositionTicketByMagic(d.symbol, d.magic);
if(tk == 0 || !PositionSelectByTicketSymbolAndMagic(tk, d.symbol, d.magic))
return;
ENUM_POSITION_TYPE typ = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openT = (datetime)PositionGetInteger(POSITION_TIME);
int barsAgo = iBarShift(d.symbol, d.signalTF, openT, false);
if(barsAgo >= 0 && barsAgo >= d.maxBarsInTrade)
{
d.trade.PositionClose(tk);
return;
}
RCO_TryCloseByRSI(d, typ, rsi);
}
bool InitRSIConsolidation(RSIConsolidationData &d,
const string inpSymbol,
const ENUM_TIMEFRAMES signalTF,
const bool entryOnNewBarOnly,
const int adxPeriod,
const double adxMax,
const bool useATRRatioFilter,
const int atrPeriod,
const int atrSmaPeriod,
const double atrRatioMax,
const bool useFlatEMAFilter,
const int emaFast,
const int emaSlow,
const double emaSeparationMaxPct,
const int rsiPeriod,
const ENUM_APPLIED_PRICE rsiPrice,
const double rsiOversold,
const double rsiOverbought,
const bool useRSIMeanExit,
const double rsiExitLong,
const double rsiExitShort,
const double slAtrMult,
const double tpAtrMult,
const int maxBarsInTrade,
const ulong magic,
const int slippage,
const int maxSpreadPoints)
{
d.isInitialized = false;
d.symbol = inpSymbol;
StringTrimLeft(d.symbol);
StringTrimRight(d.symbol);
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.signalTF = signalTF;
d.entryOnNewBarOnly = entryOnNewBarOnly;
d.adxPeriod = adxPeriod;
d.adxMax = adxMax;
d.useATRRatioFilter = useATRRatioFilter;
d.atrPeriod = atrPeriod;
d.atrSmaPeriod = atrSmaPeriod;
d.atrRatioMax = atrRatioMax;
d.useFlatEMAFilter = useFlatEMAFilter;
d.emaFast = emaFast;
d.emaSlow = emaSlow;
d.emaSeparationMaxPct = emaSeparationMaxPct;
d.rsiPeriod = rsiPeriod;
d.rsiPrice = rsiPrice;
d.rsiOversold = rsiOversold;
d.rsiOverbought = rsiOverbought;
d.useRSIMeanExit = useRSIMeanExit;
d.rsiExitLong = rsiExitLong;
d.rsiExitShort = rsiExitShort;
d.slAtrMult = slAtrMult;
d.tpAtrMult = tpAtrMult;
d.maxBarsInTrade = maxBarsInTrade;
d.magic = magic;
d.slippage = slippage;
d.maxSpreadPoints = maxSpreadPoints;
d.lastBar = 0;
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
if(!SymbolSelect(d.symbol, true))
{
Print("RSIConsolidation: SymbolSelect failed: ", d.symbol);
return false;
}
d.trade.SetExpertMagicNumber((long)d.magic);
d.trade.SetDeviationInPoints(d.slippage);
d.trade.SetTypeFillingBySymbol(d.symbol);
d.h_rsi = iRSI(d.symbol, d.signalTF, d.rsiPeriod, d.rsiPrice);
d.h_adx = iADX(d.symbol, d.signalTF, d.adxPeriod);
d.h_atr = iATR(d.symbol, d.signalTF, d.atrPeriod);
d.h_ema_fast = iMA(d.symbol, d.signalTF, d.emaFast, 0, MODE_EMA, PRICE_CLOSE);
d.h_ema_slow = iMA(d.symbol, d.signalTF, d.emaSlow, 0, MODE_EMA, PRICE_CLOSE);
if(d.h_rsi == INVALID_HANDLE || d.h_adx == INVALID_HANDLE || d.h_atr == INVALID_HANDLE
|| d.h_ema_fast == INVALID_HANDLE || d.h_ema_slow == INVALID_HANDLE)
{
Print("RSIConsolidation: indicator init failed");
DeinitRSIConsolidation(d);
return false;
}
d.isInitialized = true;
Print("RSIConsolidation: symbol=", d.symbol, " TF=", EnumToString(d.signalTF));
return true;
}
void DeinitRSIConsolidation(RSIConsolidationData &d)
{
if(d.h_rsi != INVALID_HANDLE)
IndicatorRelease(d.h_rsi);
if(d.h_adx != INVALID_HANDLE)
IndicatorRelease(d.h_adx);
if(d.h_atr != INVALID_HANDLE)
IndicatorRelease(d.h_atr);
if(d.h_ema_fast != INVALID_HANDLE)
IndicatorRelease(d.h_ema_fast);
if(d.h_ema_slow != INVALID_HANDLE)
IndicatorRelease(d.h_ema_slow);
d.h_rsi = INVALID_HANDLE;
d.h_adx = INVALID_HANDLE;
d.h_atr = INVALID_HANDLE;
d.h_ema_fast = INVALID_HANDLE;
d.h_ema_slow = INVALID_HANDLE;
d.isInitialized = false;
}
bool RCO_EnoughHistory(RSIConsolidationData &d)
{
int need = MathMax(d.rsiPeriod + 3, MathMax(d.adxPeriod + 2, d.atrSmaPeriod + 3));
if(Bars(d.symbol, d.signalTF) < need)
return false;
return true;
}
void ProcessRSIConsolidation(RSIConsolidationData &d, const double lots)
{
if(!d.isInitialized)
return;
if(!RCO_EnoughHistory(d))
return;
if(d.maxSpreadPoints > 0 && RCO_CurrentSpreadPoints(d.symbol) > d.maxSpreadPoints)
return;
double rsi, rsiPrev, rsi2;
if(!RCO_RsiBuffers(d, rsi, rsiPrev, rsi2))
return;
datetime barTime = iTime(d.symbol, d.signalTF, 0);
bool isNew = (barTime != d.lastBar);
if(PositionExistsByMagic(d.symbol, d.magic))
{
RCO_ManageOpenPosition(d, rsi);
if(isNew)
d.lastBar = barTime;
return;
}
if(d.entryOnNewBarOnly && !isNew)
return;
d.lastBar = barTime;
if(!RCO_RegimeIsConsolidation(d))
return;
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(d.h_atr, 0, 0, 1, atrArr) < 1)
return;
double atr = atrArr[0];
int dig = (int)SymbolInfoInteger(d.symbol, SYMBOL_DIGITS);
double slDist = atr * d.slAtrMult;
double tpDist = atr * d.tpAtrMult;
double minD = RCO_MinStopsDistancePrice(d.symbol);
if(slDist < minD)
slDist = minD;
if(tpDist < minD)
tpDist = minD;
double vol = RCO_NormalizeVolume(d.symbol, lots);
if(RCO_EntryBuyCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, true))
return;
double ask = SymbolInfoDouble(d.symbol, SYMBOL_ASK);
double sl = ask - slDist;
double tp = ask + tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Buy(vol, d.symbol, ask, sl, tp, "RSIConsolidation BUY"))
Print("RSIConsolidation BUY failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
else if(RCO_EntrySellCross(d, rsi2, rsiPrev))
{
if(!United_MayOpenNewEntry(d.symbol, d.magic, false))
return;
double bid = SymbolInfoDouble(d.symbol, SYMBOL_BID);
double sl = bid + slDist;
double tp = bid - tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
if(!d.trade.Sell(vol, d.symbol, bid, sl, tp, "RSIConsolidation SELL"))
Print("RSIConsolidation SELL failed | retcode=", d.trade.ResultRetcode(), " ", d.trade.ResultRetcodeDescription());
}
}
#endif // RSI_CONSOLIDATION_STRATEGY_MQH
@@ -20,6 +20,23 @@ bool WeekDays_Check(datetime aTime)
return(rcData.WeekDays[stm.day_of_week]);
}
bool RC_HourInWindow(const int h, const int beginRaw, const int endRaw)
{
const int b = beginRaw % 24;
const int e = endRaw % 24;
if(b == e)
return false;
if(b < e)
return (h >= b && h < e);
return (h >= b || h < e);
}
bool RC_TradingHoursAllow(const int currentHour)
{
return RC_HourInWindow(currentHour, RC_tradingHourOneBegin, RC_tradingHourOneEnd)
|| RC_HourInWindow(currentHour, RC_tradingHourTwoBegin, RC_tradingHourTwoEnd);
}
int TimeHour(datetime when = 0)
{
if(when == 0) when = TimeCurrent();
@@ -151,8 +168,7 @@ void ProcessRSICrossOverReversal(string symbol)
return;
}
if(!((currentHour < RC_tradingHourOneEnd && currentHour > RC_tradingHourOneBegin) ||
(currentHour < RC_tradingHourTwoEnd && currentHour > RC_tradingHourTwoBegin)))
if(!RC_TradingHoursAllow(currentHour))
{
Close_Position_MN(RC_MagicNumber);
return;
@@ -173,7 +189,7 @@ void ProcessRSICrossOverReversal(string symbol)
double previousEMA = ema[1];
double emaSlope = (currentEMA - previousEMA) * 100;
double closeCurr = iClose(Symbol(), Period(), 0);
const double closeCurr = iClose(rcData.symbol, RC_TimeFrame1, 0);
double priceToEmaDistance = (closeCurr - currentEMA) * 10;
bool isBuyPosition = false;
@@ -211,10 +227,10 @@ void ProcessRSICrossOverReversal(string symbol)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
return;
}
if(currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
if(!isTrendStrong &&
currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
!isSellPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -223,8 +239,9 @@ void ProcessRSICrossOverReversal(string symbol)
rcData.lastTradeTime = currentTime;
}
}
if(currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
if(!isTrendStrong &&
currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
!isBuyPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
@@ -0,0 +1,560 @@
//+------------------------------------------------------------------+
//| RSIScalpingStrategy.mqh |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| RSI Scalping Strategy Data Structure |
//+------------------------------------------------------------------+
struct RSIScalpingData {
string symbol;
bool isInitialized;
CTrade trade;
int rsi_handle;
double rsi_buffer[];
double rsi_prev;
double rsi_current;
double rsi_two_bars_ago;
bool position_open;
ulong position_ticket;
ENUM_POSITION_TYPE current_position_type;
datetime last_bar_time;
bool rsi_against_position;
int bars_against_count;
};
void ClosePosition(RSIScalpingData& data, int MagicNumber);
double RS_ATRPriceOnTF(const string symbol, const ENUM_TIMEFRAMES tf, const int period)
{
if(period < 1)
return 0.0;
MqlRates rates[];
const int need = period + 2;
if(CopyRates(symbol, tf, 0, need, rates) < need)
return 0.0;
ArraySetAsSeries(rates, true);
double sum = 0.0;
for(int i = 1; i <= period; i++)
{
const double hl = rates[i].high - rates[i].low;
const double hc = MathAbs(rates[i].high - rates[i + 1].close);
const double lc = MathAbs(rates[i].low - rates[i + 1].close);
sum += MathMax(hl, MathMax(hc, lc));
}
return sum / (double)period;
}
int RS_CountReversalEscapeSigns(RSIScalpingData& data, const ENUM_TIMEFRAMES tf,
const ENUM_POSITION_TYPE ptype, const double atr,
const double adverseAtrMult, const double rsiVelocity,
const double bodyAtrMult)
{
if(atr <= 0.0)
return 0;
const double entry = PositionGetDouble(POSITION_PRICE_OPEN);
const double bid = SymbolInfoDouble(data.symbol, SYMBOL_BID);
const double ask = SymbolInfoDouble(data.symbol, SYMBOL_ASK);
int signs = 0;
if(ptype == POSITION_TYPE_BUY)
{
if(entry - bid >= adverseAtrMult * atr)
signs++;
if(data.rsi_prev - data.rsi_current >= rsiVelocity)
signs++;
}
else if(ptype == POSITION_TYPE_SELL)
{
if(ask - entry >= adverseAtrMult * atr)
signs++;
if(data.rsi_current - data.rsi_prev >= rsiVelocity)
signs++;
}
else
return 0;
MqlRates r[];
if(CopyRates(data.symbol, tf, 0, 4, r) >= 4)
{
ArraySetAsSeries(r, true);
const double body = MathAbs(r[1].close - r[1].open);
if(body >= bodyAtrMult * atr)
{
if(ptype == POSITION_TYPE_BUY && r[1].close < r[1].open)
signs++;
else if(ptype == POSITION_TYPE_SELL && r[1].close > r[1].open)
signs++;
}
if(ptype == POSITION_TYPE_BUY)
{
if(r[1].close < r[2].close && r[2].close < r[3].close)
signs++;
}
else
{
if(r[1].close > r[2].close && r[2].close > r[3].close)
signs++;
}
}
return signs;
}
void RS_TryReversalEscape(RSIScalpingData& data, const ENUM_TIMEFRAMES tf, const int MagicNumber,
const int atrPeriod, const double adverseAtrMult, const int signsRequired,
const double rsiVelocity, const double bodyAtrMult)
{
if(!PositionSelectByMagic(data.symbol, (ulong)MagicNumber))
return;
const ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
const double atr = RS_ATRPriceOnTF(data.symbol, tf, atrPeriod);
if(atr <= 0.0)
return;
const int n = RS_CountReversalEscapeSigns(data, tf, ptype, atr, adverseAtrMult, rsiVelocity, bodyAtrMult);
if(n < signsRequired)
return;
ClosePosition(data, MagicNumber);
Print("RSIScalping: reversal escape symbol=", data.symbol, " signs=", n, " need=", signsRequired,
" ATR=", DoubleToString(atr, (int)SymbolInfoInteger(data.symbol, SYMBOL_DIGITS)));
}
string ErrorDescription(int errorCode)
{
switch(errorCode)
{
case 4801: return "Symbol not found";
case 4802: return "Symbol not selected";
case 4803: return "Symbol not visible";
case 4804: return "Symbol not available";
case 4805: return "Cannot load indicator - insufficient history data";
default: return "Unknown error " + IntegerToString(errorCode);
}
}
bool InitRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES TimeFrame, int RSI_Period,
ENUM_APPLIED_PRICE RSI_Applied_Price, int MagicNumber, int Slippage)
{
data.symbol = symbol;
data.isInitialized = false;
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("RSIScalping: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false; // Return false but don't fail entire EA
}
// Wait a bit for symbol to be ready
Sleep(100);
// Try to create RSI indicator with retry logic (for insufficient history in backtesting)
data.rsi_handle = INVALID_HANDLE;
int retryCount = 0;
int maxRetries = 5;
while(retryCount < maxRetries && data.rsi_handle == INVALID_HANDLE)
{
data.rsi_handle = iRSI(symbol, TimeFrame, RSI_Period, RSI_Applied_Price);
if(data.rsi_handle == INVALID_HANDLE)
{
int error = GetLastError();
// Error 4805 = insufficient history - wait longer and retry
if(error == 4805 && retryCount < maxRetries - 1)
{
Sleep(1000); // Wait 1 second for history to load
retryCount++;
continue;
}
Print("RSIScalping: Error creating RSI indicator for '", symbol, "' - Error: ", error, " (", ErrorDescription(error), ")");
return false; // Return false but don't fail entire EA
}
}
if(data.rsi_handle == INVALID_HANDLE)
{
Print("RSIScalping: Failed to create RSI indicator for '", symbol, "' after ", maxRetries, " retries");
return false;
}
data.trade.SetExpertMagicNumber(MagicNumber);
data.trade.SetDeviationInPoints(Slippage);
data.trade.SetTypeFilling(ORDER_FILLING_FOK);
ArraySetAsSeries(data.rsi_buffer, true);
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
data.isInitialized = true;
Print("RSIScalping: Successfully initialized for symbol '", symbol, "'");
return true;
}
void DeinitRSIScalping(RSIScalpingData& data)
{
if(data.rsi_handle != INVALID_HANDLE)
IndicatorRelease(data.rsi_handle);
}
bool UpdateRSI(RSIScalpingData& data)
{
if(CopyBuffer(data.rsi_handle, 0, 0, 3, data.rsi_buffer) < 3)
return false;
data.rsi_current = data.rsi_buffer[0];
data.rsi_prev = data.rsi_buffer[1];
data.rsi_two_bars_ago = data.rsi_buffer[2];
return true;
}
void CheckExistingPosition(RSIScalpingData& data, ENUM_TIMEFRAMES TimeFrame, int MagicNumber,
double RSI_Oversold, double RSI_Overbought, double RSI_Target_Buy,
double RSI_Target_Sell, int BarsToWait)
{
// Always check if position exists, even if tracking says it doesn't
bool positionExists = PositionExistsByMagic(data.symbol, MagicNumber);
if(!positionExists && data.position_open)
{
// Position was closed externally, reset tracking
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
return;
}
if(!positionExists)
return;
// Update tracking if we have a position but tracking was lost
if(!data.position_open && positionExists)
{
ulong ticket = GetPositionTicketByMagic(data.symbol, MagicNumber);
if(ticket > 0 && PositionSelectByTicketSymbolAndMagic(ticket, data.symbol, MagicNumber))
{
data.position_ticket = ticket;
data.position_open = true;
data.current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
}
// Verify our tracked position still exists
if(data.position_open && data.position_ticket > 0)
{
if(!PositionSelectByTicketSymbolAndMagic(data.position_ticket, data.symbol, MagicNumber))
{
// Try to find the position again
ulong ticket = GetPositionTicketByMagic(data.symbol, MagicNumber);
if(ticket > 0 && PositionSelectByTicketSymbolAndMagic(ticket, data.symbol, MagicNumber))
{
data.position_ticket = ticket;
data.current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
else
{
// Position doesn't exist, reset tracking
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
return;
}
}
else
{
// Update position type in case it changed (shouldn't happen, but be safe)
data.current_position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
}
if(data.current_position_type == POSITION_TYPE_BUY)
{
if(data.rsi_current < RSI_Oversold)
{
if(!data.rsi_against_position)
{
data.rsi_against_position = true;
data.bars_against_count = 1;
}
else
{
data.bars_against_count++;
}
if(data.bars_against_count >= BarsToWait)
{
ClosePosition(data, MagicNumber);
return;
}
}
else
{
if(data.rsi_against_position)
{
data.rsi_against_position = false;
data.bars_against_count = 0;
}
if(data.rsi_current >= RSI_Target_Buy)
{
ClosePosition(data, MagicNumber);
}
}
}
else if(data.current_position_type == POSITION_TYPE_SELL)
{
if(data.rsi_current > RSI_Overbought)
{
if(!data.rsi_against_position)
{
data.rsi_against_position = true;
data.bars_against_count = 1;
}
else
{
data.bars_against_count++;
}
if(data.bars_against_count >= BarsToWait)
{
ClosePosition(data, MagicNumber);
return;
}
}
else
{
if(data.rsi_against_position)
{
data.rsi_against_position = false;
data.bars_against_count = 0;
}
if(data.rsi_current <= RSI_Target_Sell)
{
ClosePosition(data, MagicNumber);
}
}
}
}
void CheckEntrySignals(RSIScalpingData& data, ENUM_TIMEFRAMES TimeFrame, int MagicNumber,
double RSI_Oversold, double RSI_Overbought, double LotSize)
{
if(data.rsi_two_bars_ago <= RSI_Oversold && data.rsi_prev > RSI_Oversold)
{
OpenBuyPosition(data, MagicNumber, LotSize);
}
if(data.rsi_two_bars_ago >= RSI_Overbought && data.rsi_prev < RSI_Overbought)
{
OpenSellPosition(data, MagicNumber, LotSize);
}
}
//+------------------------------------------------------------------+
//| Normalize Lot Size According to Symbol Properties |
//+------------------------------------------------------------------+
double NormalizeLotSize(string symbol, double lotSize)
{
double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
// Round to lot step
if(lotStep > 0)
lotSize = MathFloor(lotSize / lotStep) * lotStep;
// Apply min/max constraints
if(lotSize < minLot)
lotSize = minLot;
if(lotSize > maxLot)
lotSize = maxLot;
return lotSize;
}
void OpenBuyPosition(RSIScalpingData& data, int MagicNumber, double LotSize)
{
if(PositionExistsByMagic(data.symbol, MagicNumber))
return;
// Normalize lot size according to symbol properties
double normalizedLot = NormalizeLotSize(data.symbol, LotSize);
double ask = SymbolInfoDouble(data.symbol, SYMBOL_ASK);
if(data.trade.Buy(normalizedLot, data.symbol, ask, 0, 0, "RSI Scalping Buy"))
{
ulong new_ticket = data.trade.ResultOrder();
if(new_ticket > 0)
{
if(PositionSelectByTicketSymbolAndMagic(new_ticket, data.symbol, MagicNumber))
{
data.position_ticket = new_ticket;
data.position_open = true;
data.current_position_type = POSITION_TYPE_BUY;
}
}
}
}
void OpenSellPosition(RSIScalpingData& data, int MagicNumber, double LotSize)
{
if(PositionExistsByMagic(data.symbol, MagicNumber))
return;
// Normalize lot size according to symbol properties
double normalizedLot = NormalizeLotSize(data.symbol, LotSize);
double bid = SymbolInfoDouble(data.symbol, SYMBOL_BID);
if(data.trade.Sell(normalizedLot, data.symbol, bid, 0, 0, "RSI Scalping Sell"))
{
ulong new_ticket = data.trade.ResultOrder();
if(new_ticket > 0)
{
if(PositionSelectByTicketSymbolAndMagic(new_ticket, data.symbol, MagicNumber))
{
data.position_ticket = new_ticket;
data.position_open = true;
data.current_position_type = POSITION_TYPE_SELL;
}
}
}
}
void ClosePosition(RSIScalpingData& data, int MagicNumber)
{
// First verify position still exists
if(!PositionExistsByMagic(data.symbol, MagicNumber))
{
// Position doesn't exist, reset tracking
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
return;
}
// Try to close by ticket first (more reliable)
bool closed = false;
if(data.position_ticket > 0)
{
if(PositionSelectByTicket(data.position_ticket))
{
// Verify it's our position
if(PositionGetString(POSITION_SYMBOL) == data.symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
closed = data.trade.PositionClose(data.position_ticket);
if(!closed)
{
Print("RSIScalping: Failed to close position by ticket ", data.position_ticket,
" - Error: ", data.trade.ResultRetcode(), " (", data.trade.ResultRetcodeDescription(), ")");
}
}
}
}
// If ticket method failed, try magic number method
if(!closed)
{
closed = ClosePositionByMagic(data.trade, data.symbol, MagicNumber);
if(!closed)
{
Print("RSIScalping: Failed to close position by magic number for '", data.symbol,
"' - Error: ", data.trade.ResultRetcode(), " (", data.trade.ResultRetcodeDescription(), ")");
}
}
// Verify position is actually closed
if(closed)
{
// Wait a moment and verify
Sleep(50);
if(!PositionExistsByMagic(data.symbol, MagicNumber))
{
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
Print("RSIScalping: Position successfully closed for '", data.symbol, "'");
}
else
{
Print("RSIScalping: Warning - Close returned success but position still exists for '", data.symbol, "'");
// Try one more time
Sleep(100);
if(PositionExistsByMagic(data.symbol, MagicNumber))
{
ClosePositionByMagic(data.trade, data.symbol, MagicNumber);
}
// Reset tracking anyway to prevent getting stuck
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
}
}
else
{
// Close failed, but reset tracking to prevent getting stuck
// The position might have been closed externally
data.position_open = false;
data.position_ticket = 0;
data.rsi_against_position = false;
data.bars_against_count = 0;
}
}
void ProcessRSIScalping(RSIScalpingData& data, string symbol, ENUM_TIMEFRAMES TimeFrame, int RSI_Period,
ENUM_APPLIED_PRICE RSI_Applied_Price, double RSI_Overbought,
double RSI_Oversold, double RSI_Target_Buy, double RSI_Target_Sell,
int BarsToWait, double LotSize, int MagicNumber,
bool UseReversalEscape, int ReversalATRPeriod, double ReversalAdverseAtrMult,
int ReversalSignsRequired, double ReversalRsiVelocity, double ReversalBodyAtrMult)
{
// Skip if not initialized (symbol not available)
if(!data.isInitialized)
return;
data.symbol = symbol; // Update symbol in case it changed
if(Bars(data.symbol, TimeFrame) < RSI_Period + 2)
return;
const datetime current_bar_time = iTime(data.symbol, TimeFrame, 0);
const bool new_bar = (current_bar_time != data.last_bar_time);
const bool in_pos = data.position_open || PositionExistsByMagic(data.symbol, MagicNumber);
if(!in_pos && !new_bar)
return;
if(!UpdateRSI(data))
return;
if(in_pos && UseReversalEscape)
RS_TryReversalEscape(data, TimeFrame, MagicNumber, ReversalATRPeriod, ReversalAdverseAtrMult,
ReversalSignsRequired, ReversalRsiVelocity, ReversalBodyAtrMult);
if(!new_bar)
return;
data.last_bar_time = current_bar_time;
CheckExistingPosition(data, TimeFrame, MagicNumber, RSI_Oversold, RSI_Overbought,
RSI_Target_Buy, RSI_Target_Sell, BarsToWait);
if(!data.position_open && !PositionExistsByMagic(data.symbol, MagicNumber))
{
CheckEntrySignals(data, TimeFrame, MagicNumber, RSI_Oversold, RSI_Overbought, LotSize);
}
}
//+------------------------------------------------------------------+
@@ -0,0 +1,495 @@
//+------------------------------------------------------------------+
//| SuperEMAStrategy.mqh — EMA + CCI + MACD (United EA module) |
//+------------------------------------------------------------------+
#ifndef SUPER_EMA_STRATEGY_MQH
#define SUPER_EMA_STRATEGY_MQH
#include <Trade/Trade.mqh>
enum ENUM_SE_ENTRY_STYLE
{
SE_ENTRY_CCIZERO_MACD = 0,
SE_ENTRY_LAMBERT = 1,
SE_ENTRY_PULLBACK = 2
};
struct SuperEMAData
{
string symbol;
ENUM_TIMEFRAMES tf;
datetime lastBarTime;
CTrade trade;
bool isInitialized;
int slippagePoints;
int magic;
int emaFast;
int emaMid;
int emaSlow;
int emaTrendBars;
int cciPeriod;
double cciOverbought;
double cciOversold;
int pullbackCciLookback;
int macdFast;
int macdSlow;
int macdSignal;
ENUM_SE_ENTRY_STYLE entryStyle;
bool oneTradeOnly;
bool useStructuralSL;
double slBufferPoints;
bool exitOnTrendFlip;
bool exitOnMacdFlip;
bool exitOnCciZeroCross;
int maxHoldingBars;
bool exitBelowMidEma;
bool debugLogs;
};
void SuperEMA_Log(SuperEMAData &d, const string s)
{
if(d.debugLogs)
Print("[SuperEMA] ", s);
}
bool SuperEMA_IsNewBar(SuperEMAData &d)
{
datetime t = iTime(d.symbol, d.tf, 0);
if(t <= 0 || t == d.lastBarTime)
return false;
d.lastBarTime = t;
return true;
}
double SuperEMA_EmaAt(SuperEMAData &d, const int period, const int shift)
{
int h = iMA(d.symbol, d.tf, period, 0, MODE_EMA, PRICE_CLOSE);
if(h == INVALID_HANDLE)
return 0.0;
double b[1];
if(CopyBuffer(h, 0, shift, 1, b) <= 0)
{
IndicatorRelease(h);
return 0.0;
}
IndicatorRelease(h);
return b[0];
}
double SuperEMA_CciAt(SuperEMAData &d, const int shift)
{
int h = iCCI(d.symbol, d.tf, d.cciPeriod, PRICE_TYPICAL);
if(h == INVALID_HANDLE)
return 0.0;
double b[1];
if(CopyBuffer(h, 0, shift, 1, b) <= 0)
{
IndicatorRelease(h);
return 0.0;
}
IndicatorRelease(h);
return b[0];
}
bool SuperEMA_MacdHistAt(SuperEMAData &d, const int shift, double &hist)
{
int h = iMACD(d.symbol, d.tf, d.macdFast, d.macdSlow, d.macdSignal, PRICE_CLOSE);
if(h == INVALID_HANDLE)
return false;
double mainLine[1], sigLine[1];
if(CopyBuffer(h, 0, shift, 1, mainLine) <= 0 || CopyBuffer(h, 1, shift, 1, sigLine) <= 0)
{
IndicatorRelease(h);
return false;
}
IndicatorRelease(h);
hist = mainLine[0] - sigLine[0];
return true;
}
bool SuperEMA_TrendUp(SuperEMAData &d, const int sh)
{
double c = iClose(d.symbol, d.tf, sh);
double emaS = SuperEMA_EmaAt(d, d.emaSlow, sh);
return (emaS > 0.0 && c > emaS);
}
bool SuperEMA_TrendDown(SuperEMAData &d, const int sh)
{
double c = iClose(d.symbol, d.tf, sh);
double emaS = SuperEMA_EmaAt(d, d.emaSlow, sh);
return (emaS > 0.0 && c < emaS);
}
bool SuperEMA_CciCrossAboveZero(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 <= 0.0 && c1 > 0.0);
}
bool SuperEMA_CciCrossBelowZero(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 >= 0.0 && c1 < 0.0);
}
bool SuperEMA_CciCrossAbove100(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 < d.cciOverbought && c1 > d.cciOverbought);
}
bool SuperEMA_CciCrossBelowMinus100(SuperEMAData &d)
{
double c1 = SuperEMA_CciAt(d, 1);
double c2 = SuperEMA_CciAt(d, 2);
return (c2 > d.cciOversold && c1 < d.cciOversold);
}
bool SuperEMA_HadCciOversoldRecently(SuperEMAData &d)
{
for(int i = 2; i <= d.pullbackCciLookback + 1; i++)
{
double v = SuperEMA_CciAt(d, i);
if(v <= d.cciOversold)
return true;
}
return false;
}
bool SuperEMA_HadCciOverboughtRecently(SuperEMAData &d)
{
for(int i = 2; i <= d.pullbackCciLookback + 1; i++)
{
double v = SuperEMA_CciAt(d, i);
if(v >= d.cciOverbought)
return true;
}
return false;
}
bool SuperEMA_PullbackNearFastEmaLong(SuperEMAData &d)
{
double emaF = SuperEMA_EmaAt(d, d.emaFast, 1);
double lo = iLow(d.symbol, d.tf, 1);
if(emaF <= 0.0)
return false;
return (lo <= emaF + d.slBufferPoints * _Point * 3.0);
}
bool SuperEMA_PullbackNearFastEmaShort(SuperEMAData &d)
{
double emaF = SuperEMA_EmaAt(d, d.emaFast, 1);
double hi = iHigh(d.symbol, d.tf, 1);
if(emaF <= 0.0)
return false;
return (hi >= emaF - d.slBufferPoints * _Point * 3.0);
}
int SuperEMA_PositionsByMagic(SuperEMAData &d)
{
int n = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t == 0)
continue;
if(PositionGetString(POSITION_SYMBOL) == d.symbol && (int)PositionGetInteger(POSITION_MAGIC) == d.magic)
n++;
}
return n;
}
void SuperEMA_ComputeSLTP(SuperEMAData &d, const bool isBuy, double &sl, double &tp)
{
sl = 0.0;
tp = 0.0;
if(!d.useStructuralSL)
return;
double emaM = SuperEMA_EmaAt(d, d.emaMid, d.emaTrendBars);
double buf = d.slBufferPoints * _Point;
if(isBuy)
sl = emaM - buf;
else
sl = emaM + buf;
}
int SuperEMA_BarsSinceOpen(SuperEMAData &d, const datetime openTime)
{
if(openTime <= 0)
return 0;
int sh = iBarShift(d.symbol, d.tf, openTime, false);
if(sh < 0)
return 999999;
return sh;
}
void SuperEMA_CloseTicket(SuperEMAData &d, const ulong ticket, const string reason)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
d.trade.SetExpertMagicNumber(d.magic);
if(d.trade.PositionClose(ticket))
SuperEMA_Log(d, "Close: " + reason);
}
void SuperEMA_ManageExits(SuperEMAData &d)
{
#ifdef UNITED_MARTINGALE_NO_SELF_CLOSE
return;
#endif
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetString(POSITION_SYMBOL) != d.symbol)
continue;
if((int)PositionGetInteger(POSITION_MAGIC) != d.magic)
continue;
ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openTime = (datetime)PositionGetInteger(POSITION_TIME);
double h1 = 0.0;
if(!SuperEMA_MacdHistAt(d, 1, h1))
continue;
bool closeLong = false;
bool closeShort = false;
string reason = "";
if(d.maxHoldingBars > 0)
{
int held = SuperEMA_BarsSinceOpen(d, openTime);
if(held >= d.maxHoldingBars)
{
if(ptype == POSITION_TYPE_BUY)
closeLong = true;
else
closeShort = true;
reason = "time stop (max bars)";
}
}
if(ptype == POSITION_TYPE_BUY)
{
if(d.exitOnTrendFlip && SuperEMA_TrendDown(d, d.emaTrendBars))
{
closeLong = true;
reason = "trend flip (below slow EMA)";
}
if(d.exitOnMacdFlip && h1 < 0.0)
{
closeLong = true;
reason = "MACD histogram < 0";
}
if(d.exitOnCciZeroCross && SuperEMA_CciCrossBelowZero(d))
{
closeLong = true;
reason = "CCI crossed below zero";
}
if(d.exitBelowMidEma)
{
double c = iClose(d.symbol, d.tf, 1);
double emaM = SuperEMA_EmaAt(d, d.emaMid, 1);
if(emaM > 0.0 && c < emaM)
{
closeLong = true;
reason = "close below mid EMA";
}
}
if(closeLong)
SuperEMA_CloseTicket(d, ticket, reason);
}
else if(ptype == POSITION_TYPE_SELL)
{
if(d.exitOnTrendFlip && SuperEMA_TrendUp(d, d.emaTrendBars))
{
closeShort = true;
reason = "trend flip (above slow EMA)";
}
if(d.exitOnMacdFlip && h1 > 0.0)
{
closeShort = true;
reason = "MACD histogram > 0";
}
if(d.exitOnCciZeroCross && SuperEMA_CciCrossAboveZero(d))
{
closeShort = true;
reason = "CCI crossed above zero";
}
if(d.exitBelowMidEma)
{
double c = iClose(d.symbol, d.tf, 1);
double emaM = SuperEMA_EmaAt(d, d.emaMid, 1);
if(emaM > 0.0 && c > emaM)
{
closeShort = true;
reason = "close above mid EMA";
}
}
if(closeShort)
SuperEMA_CloseTicket(d, ticket, reason);
}
}
}
bool InitSuperEMA(SuperEMAData &d,
const string symbol,
const ENUM_TIMEFRAMES tf,
const int slippagePoints,
const int magic,
const int emaFast,
const int emaMid,
const int emaSlow,
const int emaTrendBars,
const int cciPeriod,
const double cciOverbought,
const double cciOversold,
const int pullbackCciLookback,
const int macdFast,
const int macdSlow,
const int macdSignal,
const ENUM_SE_ENTRY_STYLE entryStyle,
const bool oneTradeOnly,
const bool useStructuralSL,
const double slBufferPoints,
const bool exitOnTrendFlip,
const bool exitOnMacdFlip,
const bool exitOnCciZeroCross,
const int maxHoldingBars,
const bool exitBelowMidEma,
const bool debugLogs)
{
d.symbol = symbol;
if(StringLen(d.symbol) == 0)
d.symbol = _Symbol;
d.tf = tf;
d.lastBarTime = 0;
d.isInitialized = false;
d.slippagePoints = slippagePoints;
d.magic = magic;
d.emaFast = emaFast;
d.emaMid = emaMid;
d.emaSlow = emaSlow;
d.emaTrendBars = emaTrendBars;
d.cciPeriod = cciPeriod;
d.cciOverbought = cciOverbought;
d.cciOversold = cciOversold;
d.pullbackCciLookback = pullbackCciLookback;
d.macdFast = macdFast;
d.macdSlow = macdSlow;
d.macdSignal = macdSignal;
d.entryStyle = entryStyle;
d.oneTradeOnly = oneTradeOnly;
d.useStructuralSL = useStructuralSL;
d.slBufferPoints = slBufferPoints;
d.exitOnTrendFlip = exitOnTrendFlip;
d.exitOnMacdFlip = exitOnMacdFlip;
d.exitOnCciZeroCross = exitOnCciZeroCross;
d.maxHoldingBars = maxHoldingBars;
d.exitBelowMidEma = exitBelowMidEma;
d.debugLogs = debugLogs;
if(!SymbolSelect(d.symbol, true))
{
Print("SuperEMA: symbol not available: ", d.symbol);
return false;
}
d.trade.SetExpertMagicNumber(d.magic);
d.trade.SetDeviationInPoints(d.slippagePoints);
d.isInitialized = true;
return true;
}
void ProcessSuperEMA(SuperEMAData &d, const double lots)
{
if(!d.isInitialized)
return;
if(!SuperEMA_IsNewBar(d))
return;
SuperEMA_ManageExits(d);
const int sh = d.emaTrendBars;
double h1 = 0.0, h2 = 0.0;
if(!SuperEMA_MacdHistAt(d, 1, h1) || !SuperEMA_MacdHistAt(d, 2, h2))
return;
bool up = SuperEMA_TrendUp(d, sh);
bool dn = SuperEMA_TrendDown(d, sh);
bool wantBuy = false;
bool wantSell = false;
switch(d.entryStyle)
{
case SE_ENTRY_CCIZERO_MACD:
if(up && SuperEMA_CciCrossAboveZero(d) && h1 > 0.0)
wantBuy = true;
if(dn && SuperEMA_CciCrossBelowZero(d) && h1 < 0.0)
wantSell = true;
break;
case SE_ENTRY_LAMBERT:
if(up && SuperEMA_CciCrossAbove100(d) && h1 > 0.0)
wantBuy = true;
if(dn && SuperEMA_CciCrossBelowMinus100(d) && h1 < 0.0)
wantSell = true;
break;
case SE_ENTRY_PULLBACK:
if(up && SuperEMA_HadCciOversoldRecently(d) && SuperEMA_CciCrossAboveZero(d) && h1 > 0.0 && SuperEMA_PullbackNearFastEmaLong(d))
wantBuy = true;
if(dn && SuperEMA_HadCciOverboughtRecently(d) && SuperEMA_CciCrossBelowZero(d) && h1 < 0.0 && SuperEMA_PullbackNearFastEmaShort(d))
wantSell = true;
break;
}
if(d.oneTradeOnly && SuperEMA_PositionsByMagic(d) > 0)
{
if(wantBuy && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, true))
wantBuy = false;
if(wantSell && !United_MayOpenNewEntry(d.symbol, (ulong)d.magic, false))
wantSell = false;
if(!wantBuy && !wantSell)
return;
}
MqlTick tick;
if(!SymbolInfoTick(d.symbol, tick))
return;
double sl = 0.0, tp = 0.0;
if(wantBuy && !wantSell)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, true, sl, tp);
#endif
if(d.trade.Buy(lots, d.symbol, tick.ask, sl, tp, "United SuperEMA long"))
SuperEMA_Log(d, StringFormat("BUY ask=%.5f sl=%.5f", tick.ask, sl));
}
else if(wantSell && !wantBuy)
{
#ifndef UNITED_MARTINGALE_NO_SELF_CLOSE
SuperEMA_ComputeSLTP(d, false, sl, tp);
#endif
if(d.trade.Sell(lots, d.symbol, tick.bid, sl, tp, "United SuperEMA short"))
SuperEMA_Log(d, StringFormat("SELL bid=%.5f sl=%.5f", tick.bid, sl));
}
}
void DeinitSuperEMA(SuperEMAData &d)
{
d.isInitialized = false;
}
#endif // SUPER_EMA_STRATEGY_MQH
@@ -5,7 +5,7 @@
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.17"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
@@ -13,25 +13,33 @@
#include <Indicators\Trend.mqh>
#include <Indicators\Volumes.mqh>
#include "MagicNumberHelpers.mqh"
// Lot globals must exist before strategy .mqh (Darvas uses g_DB_LotSize; EMA/RC/RM use g_ES/g_RC/g_RM)
double g_ES_LotSize;
double g_RC_LotSize;
double g_RM_LotSize;
double g_DB_LotSize;
double g_DynMultLast = 1.0;
double g_equityPeakHighWater = 0.0; // for drawdown lot cap (updated each tick via Refresh)
datetime g_ddLotCapAnchorTime = 0; // tester/attach start — grace period before DD cap may apply
// Include strategy implementations early so structs are available
#include "Strategies/DarvasBoxStrategy.mqh"
#include "Strategies/EMASlopeDistanceStrategy.mqh"
#include "Strategies/RSICrossOverReversalStrategy.mqh"
#include "Strategies/RSIMidPointHijackStrategy.mqh"
#include "Strategies/RSIScalpingStrategy.mqh"
#include "Strategies/RSIReversalAsianStrategy.mqh"
#include "Strategies/RSISecretSauceStrategy.mqh"
#include "Strategies/SuperEMAStrategy.mqh"
#include "Strategies/RSIReversalAsianStrategy.mqh"
#include "Strategies/RSIConsolidationStrategy.mqh"
//+------------------------------------------------------------------+
//| Global Lot Size Variables (for dynamic lot sizing) |
//+------------------------------------------------------------------+
double g_ES_LotSize; // EMA Slope Distance lot size
double g_RC_LotSize; // RSI CrossOver Reversal lot size
double g_RM_LotSize; // RSI MidPoint Hijack lot size
double g_LotScaleGrowth = 1.0;
double g_LotScaleMargin = 1.0;
double g_LotScaleFinal = 1.0;
datetime g_LastScaleLogTime = 0;
bool United_MayOpenNewEntry(const string symbol, const ulong magic, const bool isBuy)
{
if(PositionExistsByMagic(symbol, magic))
return false;
return true;
}
//+------------------------------------------------------------------+
//| Strategy Enable/Disable Switches |
@@ -46,69 +54,143 @@ input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
input bool EnableRSIReversalEURUSD = true; // RSI Reversal Asian session (EURUSD)
input bool EnableRSIReversalAUDUSD = true; // RSI Reversal Asian session (AUDUSD)
input bool EnableRSISecretSauceXAUUSD = true;
input bool EnableSuperEMA = true;
input bool EnableRSIConsolidation = true;
input bool EnableRSIReversalAsianEURUSD = true;
input bool EnableRSIReversalAsianAUDUSD = true;
//+------------------------------------------------------------------+
//| SuperEMA — EMA + CCI + MACD (XAUUSD default) |
//+------------------------------------------------------------------+
input group "=== SuperEMA (EMA + CCI + MACD) ==="
input string SE_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES SE_Timeframe = PERIOD_M15;
input double SE_LotSize = 0.01;
input int SE_SlippagePoints = 55;
input int SE_MagicNumber = 940001;
input int SE_EmaFast = 40;
input int SE_EmaMid = 180;
input int SE_EmaSlow = 125;
input int SE_EmaTrendBars = 3;
input int SE_CciPeriod = 17;
input double SE_CciOverbought = 80.0;
input double SE_CciOversold = -140.0;
input int SE_PullbackCciLookback = 20;
input int SE_MacdFast = 14;
input int SE_MacdSlow = 38;
input int SE_MacdSignal = 9;
input ENUM_SE_ENTRY_STYLE SE_EntryStyle = SE_ENTRY_LAMBERT;
input bool SE_OneTradeOnly = true;
input bool SE_UseStructuralSL = false;
input double SE_SlBufferPoints = 110;
input bool SE_ExitOnTrendFlip = false;
input bool SE_ExitOnMacdFlip = false;
input bool SE_ExitOnCciZeroCross = true;
input int SE_MaxHoldingBars = 168;
input bool SE_ExitBelowMidEma = false;
input bool SE_DebugLogs = false;
input group "=== Centralized Lot Size (Granular Per Robot) ==="
input double LOT_ES_EMASlopeDistance = 0.05;
input double LOT_RC_RSICrossOver = 0.1;
input double LOT_RM_RSIMidPointHijack = 0.01;
input double LOT_RS_APPL = 100.0;
input double LOT_RS_BTCUSD = 0.15;
input double LOT_RS_NVDA = 60.0;
input double LOT_RS_TSLA = 20.0;
input double LOT_RS_XAUUSD = 0.02;
input double LOT_RRA_EURUSD = 0.01;
input double LOT_RRA_AUDUSD = 0.10;
input double LOT_SE_SuperEMA = 0.01;
input double LOT_RCO_RSIConsolidation = 0.04;
//+------------------------------------------------------------------+
//| Dynamic lot sizing — scale base lots vs reference deposit |
//| mult=(equity/ref)^exp; maxMult<=0 上不封顶; minMult<=0 不锁下限 |
//+------------------------------------------------------------------+
input group "=== Dynamic lot sizing (动态手数) ==="
input bool InpDynamicLotEnable = true; // Enable balance/equity-based scaling
input double InpDynamicRefDeposit = 3000.0; // Reference balance (match Tester initial deposit)
input double InpDynamicExponent = 1.15; // 1.0=linear; >1 faster growth; <1 conservative
input double InpDynamicMinMult = 0.0; // <=0 不锁下限; >0 例如0.25 为最低倍数
input double InpDynamicMaxMult = 0.0; // <=0 动态倍数不封顶; >0 上限封顶
input bool InpDynamicUseEquity = true; // true=ACCOUNT_EQUITY, false=ACCOUNT_BALANCE
input double InpDynamicStockLotCap = 0.0; // Extra cap for stock CFDs (0 = none)
input group "=== Auto Lot Scaling (Equity/Balance + Margin Guard) ==="
input bool EnableAutoLotScaling = true;
input double ScalingReferenceBalanceUSD = 1000.0;
input double ScalingCurveExponent = 0.70; // 1.0=linear, <1 smoother, >1 aggressive
input double ScaleMinMultiplier = 0.50;
input double ScaleMaxMultiplier = 3.00;
input bool EnableMarginGuard = true;
input double MarginSafeLevelPercent = 420.0; // >= safe: no reduction
input double MarginCriticalLevelPercent = 170.0;
input double MarginGuardMinMultiplier = 0.20;
input int ScaleLogIntervalSeconds = 300;
input bool ShowScaleStatusOnChart = true;
//+------------------------------------------------------------------+
//| Lot cap: optional account-wide DD from peak, and/or per-strategy |
//| (last *closed* calendar month losing for that magic). |
//+------------------------------------------------------------------+
input group "=== Drawdown / loser lot cap ==="
input bool InpDdLotCapEnable = true; // master: allow clamping when a mode below triggers
input bool InpDdLotCapGlobalEquityEnable = false; // cap *all* robots when equity DD from peak >= X% (after grace)
input bool InpDdLotCapPerStratEnable = true; // cap only robots whose last closed month was red (by magic)
input bool InpDdLotCapUseEquity = true; // true=ACCOUNT_EQUITY, false=BALANCE (global mode + peak tracking)
input double InpDdLotCapFromPeakPercent = 7.0; // global: trigger if (peak-equity)/peak*100 >= this
input double InpDdLotCapMaxLots = 0.01; // max volume per order while that mode is triggered
input int InpDdLotCapGraceDays = 90; // global only: wait N days from attach before DD cap can apply (0=immediate)
input double InpDdLotCapStratLossThreshold = 0.0; // per-strat: month P/L < -this counts as losing (0 = any loss)
input int InpDdLotCapUpdateSeconds = 3600; // min 60; refresh last-month P/L when adaptive monthly is off
input group "=== Minimum Balance Recommendation ==="
input bool PrintMinimumBalanceRecommendation = true;
input double MinBalPerLot_ES = 1200.0;
input double MinBalPerLot_RC = 900.0;
input double MinBalPerLot_RM = 900.0;
input double MinBalPerLot_RS_APPL = 8.0;
input double MinBalPerLot_RS_BTCUSD = 2500.0;
input double MinBalPerLot_RS_NVDA = 8.0;
input double MinBalPerLot_RS_TSLA = 8.0;
input double MinBalPerLot_RS_XAUUSD = 3000.0;
input double MinBalPerLot_RRA_EURUSD = 1200.0;
input double MinBalPerLot_RRA_AUDUSD = 1200.0;
input double MinBalPerLot_SE = 1500.0;
input double MinBalPerLot_RCO = 1800.0;
input double MinBalanceSafetyBufferPercent = 25.0;
input double MinAbsoluteRecommendedBalance = 300.0;
double ClampValue(const double v, const double minV, const double maxV)
{
if(v < minV) return minV;
if(v > maxV) return maxV;
return v;
}
double GetAutoScaledLot(const double baseLot)
{
const double scaled = baseLot * g_LotScaleFinal;
if(scaled <= 0.0)
return 0.0;
return scaled;
}
double ComputeRecommendedMinBalance()
{
double required = 0.0;
required += LOT_ES_EMASlopeDistance * MinBalPerLot_ES;
required += LOT_RC_RSICrossOver * MinBalPerLot_RC;
required += LOT_RM_RSIMidPointHijack * MinBalPerLot_RM;
required += LOT_RS_APPL * MinBalPerLot_RS_APPL;
required += LOT_RS_BTCUSD * MinBalPerLot_RS_BTCUSD;
required += LOT_RS_NVDA * MinBalPerLot_RS_NVDA;
required += LOT_RS_TSLA * MinBalPerLot_RS_TSLA;
required += LOT_RS_XAUUSD * MinBalPerLot_RS_XAUUSD;
required += LOT_RRA_EURUSD * MinBalPerLot_RRA_EURUSD;
required += LOT_RRA_AUDUSD * MinBalPerLot_RRA_AUDUSD;
required += LOT_SE_SuperEMA * MinBalPerLot_SE;
required += LOT_RCO_RSIConsolidation * MinBalPerLot_RCO;
required *= (1.0 + MinBalanceSafetyBufferPercent / 100.0);
if(required < MinAbsoluteRecommendedBalance)
required = MinAbsoluteRecommendedBalance;
return required;
}
void UpdateAutoLotScaling()
{
if(!EnableAutoLotScaling)
{
g_LotScaleGrowth = 1.0;
g_LotScaleMargin = 1.0;
g_LotScaleFinal = 1.0;
return;
}
double refBalance = ScalingReferenceBalanceUSD;
if(refBalance < 1.0)
refBalance = 1.0;
const double balance = AccountInfoDouble(ACCOUNT_BALANCE);
const double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double base = MathMax(balance, equity);
if(base < 1.0)
base = 1.0;
const double growthRatio = base / refBalance;
g_LotScaleGrowth = MathPow(growthRatio, ScalingCurveExponent);
g_LotScaleGrowth = ClampValue(g_LotScaleGrowth, ScaleMinMultiplier, ScaleMaxMultiplier);
g_LotScaleMargin = 1.0;
if(EnableMarginGuard)
{
const double ml = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
if(ml <= 0.0 || ml != ml)
{
g_LotScaleMargin = 1.0;
}
else if(ml >= MarginSafeLevelPercent)
{
g_LotScaleMargin = 1.0;
}
else if(ml <= MarginCriticalLevelPercent)
{
g_LotScaleMargin = MarginGuardMinMultiplier;
}
else
{
const double span = MarginSafeLevelPercent - MarginCriticalLevelPercent;
const double t = (span > 0.0) ? (ml - MarginCriticalLevelPercent) / span : 0.0;
g_LotScaleMargin = MarginGuardMinMultiplier + t * (1.0 - MarginGuardMinMultiplier);
}
g_LotScaleMargin = ClampValue(g_LotScaleMargin, MarginGuardMinMultiplier, 1.0);
}
g_LotScaleFinal = g_LotScaleGrowth * g_LotScaleMargin;
g_LotScaleFinal = ClampValue(g_LotScaleFinal, ScaleMinMultiplier, ScaleMaxMultiplier);
}
//+------------------------------------------------------------------+
//| Strategy 1: DarvasBoxXAUUSD |
@@ -131,7 +213,6 @@ input double DB_TrendThreshold = 4.94;
input int DB_VolumeMA_Period = 110;
input double DB_VolumeThresholdMultiplier = 1.5;
input int DB_MagicNumber = 135790;
input double DB_BaseLotSize = 0.01; // Base lot at InpDynamicRefDeposit (Darvas)
//+------------------------------------------------------------------+
//| Strategy 2: EMASlopeDistanceCocktailXAUUSD |
@@ -318,35 +399,21 @@ input double RS_XAUUSD_LotSize = 0.1;
input int RS_XAUUSD_MagicNumber = 129102315;
input int RS_XAUUSD_Slippage = 3;
//+------------------------------------------------------------------+
//| Strategy: RSI Secret Sauce XAUUSD (leave zone → re-entry peak/bottom) |
//| Defaults match secret_sauce.set except symbol stays XAUUSD here. |
//+------------------------------------------------------------------+
input group "=== RSI Secret Sauce XAUUSD ==="
input string RSS_XAUUSD_Symbol = "XAUUSD"; // not BTCUSD — gold chart / portfolio default
input double RSS_XAUUSD_LotSize = 0.1;
input int RSS_XAUUSD_MagicNumber = 789012;
input int RSS_XAUUSD_Slippage = 10;
input ENUM_TIMEFRAMES RSS_XAUUSD_Timeframe = PERIOD_M30;
input int RSS_XAUUSD_RSIPeriod = 16;
input double RSS_XAUUSD_RSIOverbought = 72.5;
input double RSS_XAUUSD_RSIOversold = 32.5;
input int RSS_XAUUSD_RSILookback = 60;
input int RSS_XAUUSD_PeakBars = 2;
input bool RSS_XAUUSD_RequireDivergence = false;
input double RSS_XAUUSD_StopLossATR = 2.75;
input double RSS_XAUUSD_TakeProfitATR = 5.0;
input int RSS_XAUUSD_ATRPeriod = 14;
input bool RSS_XAUUSD_UseSwingStopLoss = false;
input int RSS_XAUUSD_SwingLookback = 30;
input int RSS_XAUUSD_MaxPositions = 1;
input int RSS_XAUUSD_MinBarsBetweenTrades = 7;
input group "=== RSI Scalping Reversal Escape (XAUUSD only) ==="
input bool RS_UseReversalEscape = true;
input int RS_ReversalATRPeriod = 14;
input double RS_ReversalAdverseAtrMult = 5.25;
input int RS_ReversalSignsRequired = 2;
input double RS_ReversalRsiVelocity = 16.0;
input double RS_ReversalBodyAtrMult = 5.1;
//+------------------------------------------------------------------+
//| Strategy 11-12: RSI Reversal (Asian session) EURUSD & AUDUSD |
//| Same logic as RSIReversalAsianEURUSD / RSIReversalAsianAUDUSD EAs |
//| Strategy 11-12: RSI Reversal Asian Strategies |
//| Each RSI Reversal Asian strategy trades on its own symbol: |
//| - EURUSD: Euro/USD |
//| - AUDUSD: Australian Dollar/USD |
//+------------------------------------------------------------------+
input group "=== RSI Reversal EURUSD (Asian session) ==="
input group "=== RSI Reversal Asian EURUSD ==="
input string RRA_EURUSD_Symbol = "EURUSD";
input int RRA_EURUSD_RSIPeriod = 28;
input double RRA_EURUSD_OverboughtLevel = 60;
@@ -365,7 +432,7 @@ input ENUM_TIMEFRAMES RRA_EURUSD_TimeFrame = PERIOD_M15;
input int RRA_EURUSD_MagicNumber = 30001;
input int RRA_EURUSD_Slippage = 3;
input group "=== RSI Reversal AUDUSD (Asian session) ==="
input group "=== RSI Reversal Asian AUDUSD ==="
input string RRA_AUDUSD_Symbol = "AUDUSD";
input int RRA_AUDUSD_RSIPeriod = 28;
input double RRA_AUDUSD_OverboughtLevel = 68;
@@ -384,45 +451,62 @@ input ENUM_TIMEFRAMES RRA_AUDUSD_TimeFrame = PERIOD_M15;
input int RRA_AUDUSD_MagicNumber = 30002;
input int RRA_AUDUSD_Slippage = 3;
//+------------------------------------------------------------------+
//| Chart panel: closed-deal P&L by strategy (magic) + optional open |
//+------------------------------------------------------------------+
input group "=== Chart profit panel (by magic) ==="
input bool UnitedPanel_Enable = false; // OBJ_LABEL + background on chart
input int UnitedPanel_Seconds = 60; // refresh interval (min 5); history scan once per tick
input int UnitedPanel_Corner = 0; // ENUM_BASE_CORNER e.g. 0=left upper
input int UnitedPanel_X = 8;
input int UnitedPanel_Y = 24;
input int UnitedPanel_Width = 360;
input int UnitedPanel_FontSize = 9;
input int UnitedPanel_XMargin = 6;
input int UnitedPanel_YMargin = 6;
input bool UnitedPanel_ShowFloating = false; // open P/L+swap per magic
input group "=== SuperEMA (EMA + CCI + MACD) ==="
input string SE_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES SE_Timeframe = PERIOD_M15;
input double SE_LotSize = 0.01;
input int SE_SlippagePoints = 55;
input int SE_MagicNumber = 940001;
input int SE_EmaFast = 40;
input int SE_EmaMid = 180;
input int SE_EmaSlow = 125;
input int SE_EmaTrendBars = 3;
input int SE_CciPeriod = 17;
input double SE_CciOverbought = 80.0;
input double SE_CciOversold = -140.0;
input int SE_PullbackCciLookback = 20;
input int SE_MacdFast = 14;
input int SE_MacdSlow = 38;
input int SE_MacdSignal = 9;
input ENUM_SE_ENTRY_STYLE SE_EntryStyle = SE_ENTRY_LAMBERT;
input bool SE_OneTradeOnly = true;
input bool SE_UseStructuralSL = false;
input double SE_SlBufferPoints = 110;
input bool SE_ExitOnTrendFlip = false;
input bool SE_ExitOnMacdFlip = false;
input bool SE_ExitOnCciZeroCross = true;
input int SE_MaxHoldingBars = 168;
input bool SE_ExitBelowMidEma = false;
input bool SE_DebugLogs = false;
enum ENUM_ADAPTIVE_STREAK_UNIT
{
ADAPTIVE_STREAK_BY_MONTH = 0, // consecutive closed calendar months
ADAPTIVE_STREAK_BY_DAY = 1 // consecutive closed calendar days (server time)
};
//+------------------------------------------------------------------+
//| Pause strategies after consecutive losing periods (month or day)|
//+------------------------------------------------------------------+
input group "=== Adaptive regime (per robot / magic) ==="
input bool InpAdaptiveEnable = true; // If false, every other InpAdaptive* input is ignored (no streak / canary / pause). Set true to optimize or use adaptive regime.
input ENUM_ADAPTIVE_STREAK_UNIT InpAdaptiveStreakUnit = ADAPTIVE_STREAK_BY_DAY;
input int InpAdaptiveRedStreak = 5; // consecutive red months OR red days (see streak unit)
input double InpAdaptiveRedThreshold = 0.0; // period P/L < -threshold counts red (0 = any loss)
input int InpAdaptiveLookbackMonths = 14; // if unit=MONTH: history depth in months (>= streak+1)
input int InpAdaptiveLookbackDays = 36; // if unit=DAY: closed days of history (>= streak+1)
input int InpAdaptiveUpdateSeconds = 3600; // min 60; how often to recompute
input double InpAdaptiveCanaryLotMult = 0.07; // probation: scale lots (0 = hard pause on streak, no canary)
input int InpAdaptiveHardRetryMonths = 3; // if unit=MONTH: 0=no auto retry; else retry after N months
input int InpAdaptiveHardRetryDays = 32; // if unit=DAY: 0=no auto retry; else retry after N days
input int InpAdaptivePostCanaryCooldownDays = 37; // after successful canary, block re-arming another canary (days)
#include "UnitedProfitPanel.mqh"
#include "AdaptiveMonthlyRegime.mqh"
input group "=== RSI Consolidation (ranging / mean-reversion) ==="
input string RCO_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RCO_SignalTF = PERIOD_M15;
input bool RCO_EntryOnNewBarOnly = true;
input int RCO_ADX_Period = 23;
input double RCO_ADX_Max = 29.0;
input bool RCO_UseATRRatioFilter = true;
input int RCO_ATR_Period = 8;
input int RCO_ATR_SMA_Period = 35;
input double RCO_ATR_Ratio_Max = 1.36;
input bool RCO_UseFlatEMAFilter = true;
input int RCO_EMA_Fast = 13;
input int RCO_EMA_Slow = 17;
input double RCO_EMA_Separation_MaxPct = 0.26;
input int RCO_RSI_Period = 8;
input ENUM_APPLIED_PRICE RCO_RSI_Price = PRICE_OPEN;
input double RCO_RSI_Oversold = 22.0;
input double RCO_RSI_Overbought = 63.0;
input bool RCO_UseRSI_MeanExit = true;
input double RCO_RSI_Exit_Long = 48.0;
input double RCO_RSI_Exit_Short = 52.0;
input double RCO_SL_ATR_Mult = 2.15;
input double RCO_TP_ATR_Mult = 2.40;
input int RCO_MaxBarsInTrade = 54;
input double RCO_Lots = 0.10;
input ulong RCO_MagicNumber = 20250420;
input int RCO_Slippage = 10;
input int RCO_MaxSpreadPoints = 28;
//+------------------------------------------------------------------+
//| Global Variables - DarvasBox |
@@ -520,137 +604,14 @@ RSIScalpingData rsBTCUSDData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
SuperEMAData seData;
RSIConsolidationData rcoData;
//+------------------------------------------------------------------+
//| Global Variables - RSI Reversal Asian |
//+------------------------------------------------------------------+
RSIReversalAsianData rraEURUSDData;
RSIReversalAsianData rraAUDUSDData;
RSISecretSauceData rsSecretSauceXAUUSDData;
SuperEMAData seData;
//+------------------------------------------------------------------+
//| Dynamic lot helpers |
//+------------------------------------------------------------------+
double DynClamp(const double v, const double lo, const double hi)
{
return MathMax(lo, MathMin(hi, v));
}
// maxMult<=0: no ceiling. minMult<=0: no floor on raw (equity/ref)^exp.
double ApplyDynamicMultClamp(const double mult)
{
double m = mult;
if(InpDynamicMinMult > 0.0)
m = MathMax(m, InpDynamicMinMult);
if(InpDynamicMaxMult > 0.0)
m = MathMin(m, InpDynamicMaxMult);
return m;
}
double NormalizeVolumeForSymbol(const string symbol, double lots)
{
double minL = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double maxL = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
if(step > 0.0)
lots = MathFloor(lots / step + 1e-12) * step;
if(lots < minL) lots = minL;
if(lots > maxL) lots = maxL;
return lots;
}
void UpdateEquityPeakForDdCap()
{
if(!InpDdLotCapEnable || !InpDdLotCapGlobalEquityEnable)
return;
const double cur = InpDdLotCapUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
if(cur > g_equityPeakHighWater)
g_equityPeakHighWater = cur;
}
// After dynamic sizing: global equity DD and/or per-strategy last-month loser -> clamp to InpDdLotCapMaxLots.
double LotsAfterDrawdownCap(const string symbol, const double lotsRaw, const int ddStratId = -1)
{
double lots = NormalizeVolumeForSymbol(symbol, lotsRaw);
if(!InpDdLotCapEnable)
return lots;
bool needCap = false;
if(InpDdLotCapGlobalEquityEnable)
{
bool globalCheck = true;
if(InpDdLotCapGraceDays > 0 && g_ddLotCapAnchorTime > 0)
{
const long needSec = (long)InpDdLotCapGraceDays * 86400L;
if((long)(TimeCurrent() - g_ddLotCapAnchorTime) < needSec)
globalCheck = false;
}
if(globalCheck && g_equityPeakHighWater > 0.0)
{
const double cur = InpDdLotCapUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
if(cur < g_equityPeakHighWater)
{
const double ddPct = 100.0 * (g_equityPeakHighWater - cur) / g_equityPeakHighWater;
if(ddPct >= InpDdLotCapFromPeakPercent)
needCap = true;
}
}
}
if(InpDdLotCapPerStratEnable && ddStratId >= 0 && UnitedAdaptive_StratLastMonthIsLosing(ddStratId))
needCap = true;
if(!needCap)
return lots;
return NormalizeVolumeForSymbol(symbol, MathMin(lots, InpDdLotCapMaxLots));
}
double GetDynamicMultiplier()
{
if(!InpDynamicLotEnable)
return 1.0;
double cap = InpDynamicUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
if(cap <= 0.0)
cap = InpDynamicRefDeposit;
double refv = MathMax(InpDynamicRefDeposit, 1.0);
double ratio = cap / refv;
if(ratio <= 0.0)
ratio = 1.0;
double mult = MathPow(ratio, InpDynamicExponent);
return ApplyDynamicMultClamp(mult);
}
// baseLot = size at reference deposit; optionalCap 0 = no extra ceiling (broker min/max still apply)
double DynamicLotForSymbol(const string symbol, const double baseLot, const double optionalCap = 0.0, const int ddStratId = -1)
{
double mult = GetDynamicMultiplier();
g_DynMultLast = mult;
double v = baseLot * mult;
if(optionalCap > 0.0 && v > optionalCap)
v = optionalCap;
return LotsAfterDrawdownCap(symbol, v, ddStratId);
}
void RefreshDynamicStrategyLots()
{
UpdateEquityPeakForDdCap();
if(!InpDynamicLotEnable)
{
g_ES_LotSize = LotsAfterDrawdownCap(ES_Symbol, ES_LotGröße * UnitedAdaptive_GetLotMult(UNITED_AD_ES), UNITED_AD_ES);
g_RC_LotSize = LotsAfterDrawdownCap(RC_Symbol, RC_lotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RC), UNITED_AD_RC);
g_RM_LotSize = LotsAfterDrawdownCap(RM_Symbol, RM_InpLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RM), UNITED_AD_RM);
g_DB_LotSize = LotsAfterDrawdownCap(DB_Symbol, DB_BaseLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_DARVAS), UNITED_AD_DARVAS);
g_DynMultLast = 1.0;
return;
}
g_ES_LotSize = DynamicLotForSymbol(ES_Symbol, ES_LotGröße * UnitedAdaptive_GetLotMult(UNITED_AD_ES), 0.0, UNITED_AD_ES);
g_RC_LotSize = DynamicLotForSymbol(RC_Symbol, RC_lotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RC), 0.0, UNITED_AD_RC);
g_RM_LotSize = DynamicLotForSymbol(RM_Symbol, RM_InpLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RM), 0.0, UNITED_AD_RM);
g_DB_LotSize = DynamicLotForSymbol(DB_Symbol, DB_BaseLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_DARVAS), 0.0, UNITED_AD_DARVAS);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
@@ -659,16 +620,21 @@ int OnInit()
{
int initResult = INIT_SUCCEEDED;
UnitedAdaptive_Init();
UpdateAutoLotScaling();
// Initialize global lot size variables
g_ES_LotSize = GetAutoScaledLot(LOT_ES_EMASlopeDistance);
g_RC_LotSize = GetAutoScaledLot(LOT_RC_RSICrossOver);
g_RM_LotSize = GetAutoScaledLot(LOT_RM_RSIMidPointHijack);
g_equityPeakHighWater = InpDdLotCapUseEquity ? AccountInfoDouble(ACCOUNT_EQUITY) : AccountInfoDouble(ACCOUNT_BALANCE);
if(g_equityPeakHighWater <= 0.0)
g_equityPeakHighWater = MathMax(InpDynamicRefDeposit, 1.0);
g_ddLotCapAnchorTime = TimeCurrent();
UnitedAdaptive_UpdateIfDue();
RefreshDynamicStrategyLots();
if(PrintMinimumBalanceRecommendation)
{
const double minBalance = ComputeRecommendedMinBalance();
Print("Lot scaling initialized | scale=", DoubleToString(g_LotScaleFinal, 3),
" (growth=", DoubleToString(g_LotScaleGrowth, 3),
", margin=", DoubleToString(g_LotScaleMargin, 3), ")",
" | recommended minimum balance=", DoubleToString(minBalance, 2));
}
// Initialize strategies - log warnings but don't fail entire EA if symbol unavailable
if(EnableDarvasBox)
@@ -702,31 +668,6 @@ int OnInit()
if(EnableRSIScalpingXAUUSD)
InitRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price, RS_XAUUSD_MagicNumber, RS_XAUUSD_Slippage);
// Initialize RSI Reversal Asian strategies
if(EnableRSIReversalEURUSD)
if(!InitRSIReversalAsian(rraEURUSDData, RRA_EURUSD_Symbol, RRA_EURUSD_RSIPeriod, RRA_EURUSD_OverboughtLevel, RRA_EURUSD_OversoldLevel,
RRA_EURUSD_TakeProfitPips, RRA_EURUSD_StopLossPips, RRA_EURUSD_MaxLotSize,
RRA_EURUSD_MaxSpread, RRA_EURUSD_MaxDuration, RRA_EURUSD_UseStopLoss,
RRA_EURUSD_UseTakeProfit, RRA_EURUSD_UseRSIExit, RRA_EURUSD_RSIExitLevel,
RRA_EURUSD_CloseOutsideSession, RRA_EURUSD_TimeFrame, RRA_EURUSD_MagicNumber, RRA_EURUSD_Slippage))
Print("Warning: RSIReversalEURUSD strategy failed to initialize for symbol '", RRA_EURUSD_Symbol, "'");
if(EnableRSIReversalAUDUSD)
if(!InitRSIReversalAsian(rraAUDUSDData, RRA_AUDUSD_Symbol, RRA_AUDUSD_RSIPeriod, RRA_AUDUSD_OverboughtLevel, RRA_AUDUSD_OversoldLevel,
RRA_AUDUSD_TakeProfitPips, RRA_AUDUSD_StopLossPips, RRA_AUDUSD_MaxLotSize,
RRA_AUDUSD_MaxSpread, RRA_AUDUSD_MaxDuration, RRA_AUDUSD_UseStopLoss,
RRA_AUDUSD_UseTakeProfit, RRA_AUDUSD_UseRSIExit, RRA_AUDUSD_RSIExitLevel,
RRA_AUDUSD_CloseOutsideSession, RRA_AUDUSD_TimeFrame, RRA_AUDUSD_MagicNumber, RRA_AUDUSD_Slippage))
Print("Warning: RSIReversalAUDUSD strategy failed to initialize for symbol '", RRA_AUDUSD_Symbol, "'");
if(EnableRSISecretSauceXAUUSD)
if(!InitRSISecretSauce(rsSecretSauceXAUUSDData, RSS_XAUUSD_Symbol, RSS_XAUUSD_Timeframe, RSS_XAUUSD_RSIPeriod,
RSS_XAUUSD_RSIOverbought, RSS_XAUUSD_RSIOversold, RSS_XAUUSD_RSILookback, RSS_XAUUSD_PeakBars,
RSS_XAUUSD_RequireDivergence, RSS_XAUUSD_StopLossATR, RSS_XAUUSD_TakeProfitATR, RSS_XAUUSD_ATRPeriod,
RSS_XAUUSD_UseSwingStopLoss, RSS_XAUUSD_SwingLookback, RSS_XAUUSD_MaxPositions,
RSS_XAUUSD_MinBarsBetweenTrades, RSS_XAUUSD_MagicNumber, RSS_XAUUSD_Slippage))
Print("Warning: RSISecretSauceXAUUSD failed to initialize for symbol '", RSS_XAUUSD_Symbol, "'");
if(EnableSuperEMA)
if(!InitSuperEMA(seData, SE_Symbol, SE_Timeframe, SE_SlippagePoints, SE_MagicNumber,
@@ -737,19 +678,33 @@ int OnInit()
SE_ExitOnTrendFlip, SE_ExitOnMacdFlip, SE_ExitOnCciZeroCross,
SE_MaxHoldingBars, SE_ExitBelowMidEma, SE_DebugLogs))
Print("Warning: SuperEMA failed to initialize for symbol '", SE_Symbol, "'");
if(EnableRSIConsolidation)
if(!InitRSIConsolidation(rcoData, RCO_Symbol, RCO_SignalTF, RCO_EntryOnNewBarOnly,
RCO_ADX_Period, RCO_ADX_Max, RCO_UseATRRatioFilter, RCO_ATR_Period, RCO_ATR_SMA_Period, RCO_ATR_Ratio_Max,
RCO_UseFlatEMAFilter, RCO_EMA_Fast, RCO_EMA_Slow, RCO_EMA_Separation_MaxPct,
RCO_RSI_Period, RCO_RSI_Price, RCO_RSI_Oversold, RCO_RSI_Overbought,
RCO_UseRSI_MeanExit, RCO_RSI_Exit_Long, RCO_RSI_Exit_Short, RCO_SL_ATR_Mult, RCO_TP_ATR_Mult,
RCO_MaxBarsInTrade, RCO_MagicNumber, RCO_Slippage, RCO_MaxSpreadPoints))
Print("Warning: RSIConsolidation failed to initialize for symbol '", RCO_Symbol, "'");
// Initialize RSI Reversal Asian strategies
if(EnableRSIReversalAsianEURUSD)
if(!InitRSIReversalAsian(rraEURUSDData, RRA_EURUSD_Symbol, RRA_EURUSD_RSIPeriod, RRA_EURUSD_OverboughtLevel, RRA_EURUSD_OversoldLevel,
RRA_EURUSD_TakeProfitPips, RRA_EURUSD_StopLossPips, LOT_RRA_EURUSD,
RRA_EURUSD_MaxSpread, RRA_EURUSD_MaxDuration, RRA_EURUSD_UseStopLoss,
RRA_EURUSD_UseTakeProfit, RRA_EURUSD_UseRSIExit, RRA_EURUSD_RSIExitLevel,
RRA_EURUSD_CloseOutsideSession, RRA_EURUSD_TimeFrame, RRA_EURUSD_MagicNumber, RRA_EURUSD_Slippage))
Print("Warning: RSIReversalAsianEURUSD strategy failed to initialize for symbol '", RRA_EURUSD_Symbol, "'");
if(EnableRSIReversalAsianAUDUSD)
if(!InitRSIReversalAsian(rraAUDUSDData, RRA_AUDUSD_Symbol, RRA_AUDUSD_RSIPeriod, RRA_AUDUSD_OverboughtLevel, RRA_AUDUSD_OversoldLevel,
RRA_AUDUSD_TakeProfitPips, RRA_AUDUSD_StopLossPips, LOT_RRA_AUDUSD,
RRA_AUDUSD_MaxSpread, RRA_AUDUSD_MaxDuration, RRA_AUDUSD_UseStopLoss,
RRA_AUDUSD_UseTakeProfit, RRA_AUDUSD_UseRSIExit, RRA_AUDUSD_RSIExitLevel,
RRA_AUDUSD_CloseOutsideSession, RRA_AUDUSD_TimeFrame, RRA_AUDUSD_MagicNumber, RRA_AUDUSD_Slippage))
Print("Warning: RSIReversalAsianAUDUSD strategy failed to initialize for symbol '", RRA_AUDUSD_Symbol, "'");
string acctCur = AccountInfoString(ACCOUNT_CURRENCY);
double eq0 = AccountInfoDouble(ACCOUNT_EQUITY);
double refvInit = MathMax(InpDynamicRefDeposit, 1.0);
double capInit = InpDynamicUseEquity ? eq0 : AccountInfoDouble(ACCOUNT_BALANCE);
if(capInit <= 0.0)
capInit = refvInit;
double ratioInit = capInit / refvInit;
double rawPowInit = MathPow(ratioInit, InpDynamicExponent);
Print("United EA v1.17 ", acctCur, " equity=", DoubleToString(eq0, 2), " equity/ref=", DoubleToString(ratioInit, 6),
" raw^exp=", DoubleToString(rawPowInit, 6), " multOut=", DoubleToString(g_DynMultLast, 6),
" minM=", InpDynamicMinMult, " maxM=", InpDynamicMaxMult, " ref=", InpDynamicRefDeposit, " exp=", InpDynamicExponent,
" lots ES=", g_ES_LotSize, " RC=", g_RC_LotSize, " RM=", g_RM_LotSize, " DB=", g_DB_LotSize);
Print("United EA initialized. Active strategies: ",
(EnableDarvasBox ? "DarvasBox " : ""),
(EnableEMASlopeDistance ? "EMASlope " : ""),
@@ -760,29 +715,11 @@ int OnInit()
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""),
(EnableRSIReversalEURUSD ? "RSIReversalEURUSD " : ""),
(EnableRSIReversalAUDUSD ? "RSIReversalAUDUSD " : ""),
(EnableRSISecretSauceXAUUSD ? "RSISecretSauceXAUUSD " : ""),
(EnableSuperEMA ? "SuperEMA " : ""));
EventSetTimer(0);
int timerSec = 0;
if(UnitedPanel_Enable)
timerSec = MathMax(5, UnitedPanel_Seconds);
if(InpAdaptiveEnable)
{
const int adSec = MathMax(60, InpAdaptiveUpdateSeconds);
timerSec = (timerSec == 0) ? adSec : MathMin(timerSec, adSec);
}
if(InpDdLotCapEnable && InpDdLotCapPerStratEnable && !InpAdaptiveEnable)
{
const int ddSec = MathMax(60, InpDdLotCapUpdateSeconds);
timerSec = (timerSec == 0) ? ddSec : MathMin(timerSec, ddSec);
}
if(timerSec > 0)
EventSetTimer(timerSec);
UnitedProfitPanelInit();
(EnableSuperEMA ? "SuperEMA " : ""),
(EnableRSIConsolidation ? "RSIConsolidation " : ""),
(EnableRSIReversalAsianEURUSD ? "RSIReversalAsianEURUSD " : ""),
(EnableRSIReversalAsianAUDUSD ? "RSIReversalAsianAUDUSD " : ""));
return initResult;
}
@@ -791,9 +728,6 @@ int OnInit()
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
EventSetTimer(0);
UnitedProfitPanelDeinit();
if(EnableDarvasBox)
DeinitDarvasBox();
@@ -820,18 +754,18 @@ void OnDeinit(const int reason)
if(EnableRSIScalpingXAUUSD)
DeinitRSIScalping(rsXAUUSDData);
if(EnableRSIReversalEURUSD)
DeinitRSIReversalAsian(rraEURUSDData);
if(EnableRSIReversalAUDUSD)
DeinitRSIReversalAsian(rraAUDUSDData);
if(EnableRSISecretSauceXAUUSD)
DeinitRSISecretSauce(rsSecretSauceXAUUSDData);
if(EnableSuperEMA)
DeinitSuperEMA(seData);
if(EnableRSIConsolidation)
DeinitRSIConsolidation(rcoData);
if(EnableRSIReversalAsianEURUSD)
DeinitRSIReversalAsian(rraEURUSDData);
if(EnableRSIReversalAsianAUDUSD)
DeinitRSIReversalAsian(rraAUDUSDData);
Print("United EA deinitialized. Reason: ", reason);
}
@@ -841,84 +775,94 @@ void OnDeinit(const int reason)
//+------------------------------------------------------------------+
void OnTick()
{
UnitedAdaptive_ProcessCanaryTransitions();
RefreshDynamicStrategyLots();
if(EnableDarvasBox && UnitedAdaptive_StrategyActive(UNITED_AD_DARVAS))
UpdateAutoLotScaling();
g_ES_LotSize = GetAutoScaledLot(LOT_ES_EMASlopeDistance);
g_RC_LotSize = GetAutoScaledLot(LOT_RC_RSICrossOver);
g_RM_LotSize = GetAutoScaledLot(LOT_RM_RSIMidPointHijack);
if(ScaleLogIntervalSeconds > 0)
{
const datetime now = TimeCurrent();
if(g_LastScaleLogTime == 0 || (now - g_LastScaleLogTime) >= ScaleLogIntervalSeconds)
{
g_LastScaleLogTime = now;
Print("Lot scale update | final=", DoubleToString(g_LotScaleFinal, 3),
" growth=", DoubleToString(g_LotScaleGrowth, 3),
" margin=", DoubleToString(g_LotScaleMargin, 3),
" ml=", DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL), 1),
" eq=", DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2),
" bal=", DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2));
}
}
if(ShowScaleStatusOnChart)
{
const double minBalance = ComputeRecommendedMinBalance();
Comment("Scale=", DoubleToString(g_LotScaleFinal, 3),
" (growth=", DoubleToString(g_LotScaleGrowth, 3),
", margin=", DoubleToString(g_LotScaleMargin, 3), ")",
" | Rec.Min.Balance=", DoubleToString(minBalance, 2),
" | MarginLevel=", DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL), 1), "%");
}
if(EnableDarvasBox)
ProcessDarvasBox(DB_Symbol);
if(EnableEMASlopeDistance && UnitedAdaptive_StrategyActive(UNITED_AD_ES))
if(EnableEMASlopeDistance)
ProcessEMASlopeDistance(ES_Symbol);
if(EnableRSICrossOverReversal && UnitedAdaptive_StrategyActive(UNITED_AD_RC))
if(EnableRSICrossOverReversal)
ProcessRSICrossOverReversal(RC_Symbol);
if(EnableRSIMidPointHijack && UnitedAdaptive_StrategyActive(UNITED_AD_RM))
if(EnableRSIMidPointHijack)
ProcessRSIMidPointHijack(RM_Symbol);
if(EnableRSIScalpingAPPL && UnitedAdaptive_StrategyActive(UNITED_AD_RS_APPL))
if(EnableRSIScalpingAPPL)
ProcessRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price,
RS_APPL_RSI_Overbought, RS_APPL_RSI_Oversold, RS_APPL_RSI_Target_Buy, RS_APPL_RSI_Target_Sell,
RS_APPL_BarsToWait,
DynamicLotForSymbol(RS_APPL_Symbol, RS_APPL_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RS_APPL), InpDynamicStockLotCap, UNITED_AD_RS_APPL),
RS_APPL_MagicNumber);
RS_APPL_BarsToWait, GetAutoScaledLot(LOT_RS_APPL), RS_APPL_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingBTCUSD && UnitedAdaptive_StrategyActive(UNITED_AD_RS_BTC))
if(EnableRSIScalpingBTCUSD)
ProcessRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price,
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, DynamicLotForSymbol(RS_BTCUSD_Symbol, RS_BTCUSD_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RS_BTC), 0.0, UNITED_AD_RS_BTC), RS_BTCUSD_MagicNumber);
RS_BTCUSD_BarsToWait, GetAutoScaledLot(LOT_RS_BTCUSD), RS_BTCUSD_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingNVDA && UnitedAdaptive_StrategyActive(UNITED_AD_RS_NVDA))
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
RS_NVDA_BarsToWait,
DynamicLotForSymbol(RS_NVDA_Symbol, RS_NVDA_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RS_NVDA), InpDynamicStockLotCap, UNITED_AD_RS_NVDA),
RS_NVDA_MagicNumber);
RS_NVDA_BarsToWait, GetAutoScaledLot(LOT_RS_NVDA), RS_NVDA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingTSLA && UnitedAdaptive_StrategyActive(UNITED_AD_RS_TSLA))
if(EnableRSIScalpingTSLA)
ProcessRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price,
RS_TSLA_RSI_Overbought, RS_TSLA_RSI_Oversold, RS_TSLA_RSI_Target_Buy, RS_TSLA_RSI_Target_Sell,
RS_TSLA_BarsToWait,
DynamicLotForSymbol(RS_TSLA_Symbol, RS_TSLA_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RS_TSLA), InpDynamicStockLotCap, UNITED_AD_RS_TSLA),
RS_TSLA_MagicNumber);
RS_TSLA_BarsToWait, GetAutoScaledLot(LOT_RS_TSLA), RS_TSLA_MagicNumber,
false, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIScalpingXAUUSD && UnitedAdaptive_StrategyActive(UNITED_AD_RS_XAU))
if(EnableRSIScalpingXAUUSD)
ProcessRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price,
RS_XAUUSD_RSI_Overbought, RS_XAUUSD_RSI_Oversold, RS_XAUUSD_RSI_Target_Buy, RS_XAUUSD_RSI_Target_Sell,
RS_XAUUSD_BarsToWait, DynamicLotForSymbol(RS_XAUUSD_Symbol, RS_XAUUSD_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RS_XAU), 0.0, UNITED_AD_RS_XAU), RS_XAUUSD_MagicNumber);
RS_XAUUSD_BarsToWait, GetAutoScaledLot(LOT_RS_XAUUSD), RS_XAUUSD_MagicNumber,
RS_UseReversalEscape, RS_ReversalATRPeriod, RS_ReversalAdverseAtrMult, RS_ReversalSignsRequired,
RS_ReversalRsiVelocity, RS_ReversalBodyAtrMult);
if(EnableRSIReversalEURUSD && UnitedAdaptive_StrategyActive(UNITED_AD_RRA_EUR))
ProcessRSIReversalAsian(rraEURUSDData, DynamicLotForSymbol(RRA_EURUSD_Symbol, RRA_EURUSD_MaxLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RRA_EUR), 0.0, UNITED_AD_RRA_EUR));
if(EnableRSIReversalAsianEURUSD)
ProcessRSIReversalAsian(rraEURUSDData, GetAutoScaledLot(LOT_RRA_EURUSD));
if(EnableRSIReversalAUDUSD && UnitedAdaptive_StrategyActive(UNITED_AD_RRA_AUD))
ProcessRSIReversalAsian(rraAUDUSDData, DynamicLotForSymbol(RRA_AUDUSD_Symbol, RRA_AUDUSD_MaxLotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RRA_AUD), 0.0, UNITED_AD_RRA_AUD));
if(EnableRSIReversalAsianAUDUSD)
ProcessRSIReversalAsian(rraAUDUSDData, GetAutoScaledLot(LOT_RRA_AUDUSD));
if(EnableRSISecretSauceXAUUSD && UnitedAdaptive_StrategyActive(UNITED_AD_RSS))
ProcessRSISecretSauce(rsSecretSauceXAUUSDData, DynamicLotForSymbol(RSS_XAUUSD_Symbol, RSS_XAUUSD_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_RSS), 0.0, UNITED_AD_RSS));
if(EnableSuperEMA)
ProcessSuperEMA(seData, GetAutoScaledLot(LOT_SE_SuperEMA));
if(EnableSuperEMA && UnitedAdaptive_StrategyActive(UNITED_AD_SUPEREMA))
ProcessSuperEMA(seData, DynamicLotForSymbol(SE_Symbol, SE_LotSize * UnitedAdaptive_GetLotMult(UNITED_AD_SUPEREMA), 0.0, UNITED_AD_SUPEREMA));
}
//+------------------------------------------------------------------+
//| Timer — refresh profit panel (history scan) |
//+------------------------------------------------------------------+
void OnTimer()
{
if(InpAdaptiveEnable)
UnitedAdaptive_ProcessCanaryTransitions();
if(InpAdaptiveEnable || (InpDdLotCapEnable && InpDdLotCapPerStratEnable))
UnitedAdaptive_UpdateIfDue();
if(UnitedPanel_Enable)
UnitedProfitPanelRefresh();
}
//+------------------------------------------------------------------+
//| Chart events — panel layout on resize |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
UnitedProfitPanelOnChartEvent(id);
if(EnableRSIConsolidation)
ProcessRSIConsolidation(rcoData, GetAutoScaledLot(LOT_RCO_RSIConsolidation));
}
//+------------------------------------------------------------------+

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

@@ -25,6 +25,7 @@ input bool EnableRSICrossOverReversal = true;
input bool EnableRSIMidPointHijack = true;
input bool EnableRSIScalpingAPPL = true;
input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingMSFT = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
@@ -154,6 +155,7 @@ input int RM_InpEMADistancePeriod = 26;
//| Each RSI Scalping strategy trades on its own symbol: |
//| - APPL: Apple stock (AAPL) |
//| - BTCUSD: Bitcoin/USD |
//| - MSFT: Microsoft stock |
//| - NVDA: NVIDIA stock |
//| - TSLA: Tesla stock |
//| - XAUUSD: Gold/USD |
@@ -194,6 +196,20 @@ input double RS_BTCUSD_LotSize = 0.1;
input int RS_BTCUSD_MagicNumber = 123459123;
input int RS_BTCUSD_Slippage = 3;
input group "=== RSI Scalping MSFT - Pepperstone US ==="
input string RS_MSFT_Symbol = "MSFT.US"; // Try: "MSFT.US", "NASDAQ:MSFT", or "MSFT"
input ENUM_TIMEFRAMES RS_MSFT_TimeFrame = PERIOD_H3;
input int RS_MSFT_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_MSFT_RSI_Applied_Price = PRICE_CLOSE;
input double RS_MSFT_RSI_Overbought = 19;
input double RS_MSFT_RSI_Oversold = 50;
input double RS_MSFT_RSI_Target_Buy = 71;
input double RS_MSFT_RSI_Target_Sell = 70;
input int RS_MSFT_BarsToWait = 1;
input double RS_MSFT_LotSize = 50;
input int RS_MSFT_MagicNumber = 20002;
input int RS_MSFT_Slippage = 3;
input group "=== RSI Scalping NVDA - Pepperstone US ==="
input string RS_NVDA_Symbol = "NVDA.US"; // Try: "NVDA.US", "NASDAQ:NVDA", or "NVDA"
input ENUM_TIMEFRAMES RS_NVDA_TimeFrame = PERIOD_M15;
@@ -349,6 +365,7 @@ RSICrossOverData rcData;
RSIMidPointData rmData;
RSIScalpingData rsAPPLData;
RSIScalpingData rsBTCUSDData;
RSIScalpingData rsMSFTData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
@@ -363,6 +380,7 @@ double g_RC_LotSize = 0.01; // RSI CrossOver Reversal - start with minimum
double g_RM_LotSize = 0.01; // RSI MidPoint Hijack - start with minimum
double g_RS_APPL_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_BTCUSD_LotSize = 0.01; // Crypto - start with forex minimum (0.01)
double g_RS_MSFT_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_NVDA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_TSLA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_XAUUSD_LotSize = 0.01; // Forex - start with forex minimum (0.01)
@@ -446,6 +464,15 @@ int OnInit()
g_RS_BTCUSD_LotSize = minLot;
}
if(EnableRSIScalpingMSFT)
{
InitRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price, RS_MSFT_MagicNumber, RS_MSFT_Slippage);
RegisterStrategy("RSIScalpingMSFT", RS_MSFT_MagicNumber, RS_MSFT_LotSize, RS_MSFT_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_MSFT_Symbol);
g_RS_MSFT_LotSize = minLot;
}
if(EnableRSIScalpingNVDA)
{
InitRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price, RS_NVDA_MagicNumber, RS_NVDA_Slippage);
@@ -492,6 +519,9 @@ int OnInit()
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
@@ -509,6 +539,7 @@ int OnInit()
(EnableRSIMidPointHijack ? "RSIMidPoint " : ""),
(EnableRSIScalpingAPPL ? "RSIScalpingAPPL " : ""),
(EnableRSIScalpingBTCUSD ? "RSIScalpingBTCUSD " : ""),
(EnableRSIScalpingMSFT ? "RSIScalpingMSFT " : ""),
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""));
@@ -542,6 +573,9 @@ void OnDeinit(const int reason)
if(EnableRSIScalpingBTCUSD)
DeinitRSIScalping(rsBTCUSDData);
if(EnableRSIScalpingMSFT)
DeinitRSIScalping(rsMSFTData);
if(EnableRSIScalpingNVDA)
DeinitRSIScalping(rsNVDAData);
@@ -581,6 +615,9 @@ void OnTick()
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
@@ -613,6 +650,11 @@ void OnTick()
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, g_RS_BTCUSD_LotSize, RS_BTCUSD_MagicNumber);
if(EnableRSIScalpingMSFT)
ProcessRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price,
RS_MSFT_RSI_Overbought, RS_MSFT_RSI_Oversold, RS_MSFT_RSI_Target_Buy, RS_MSFT_RSI_Target_Sell,
RS_MSFT_BarsToWait, g_RS_MSFT_LotSize, RS_MSFT_MagicNumber);
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
@@ -1,28 +1,30 @@
//+------------------------------------------------------------------+
//| MagicNumberHelpers.mqh |
//| 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>
//+------------------------------------------------------------------+
//| Select position by symbol and magic number |
//+------------------------------------------------------------------+
bool PositionSelectByMagic(string symbol, ulong magic_number)
{
// First try to find position by symbol
if(!PositionSelect(symbol))
return false;
// Check if the selected position has the correct magic number
if(PositionGetInteger(POSITION_MAGIC) != magic_number)
{
// Position exists but wrong magic number, search all positions
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionGetTicket(i) > 0)
{
if(PositionGetString(POSITION_SYMBOL) == symbol &&
if(PositionGetString(POSITION_SYMBOL) == symbol &&
PositionGetInteger(POSITION_MAGIC) == magic_number)
{
return true;
@@ -31,7 +33,7 @@ bool PositionSelectByMagic(string symbol, ulong magic_number)
}
return false;
}
return true;
}
@@ -42,7 +44,7 @@ bool PositionSelectByTicketAndMagic(ulong ticket, ulong magic_number)
{
if(!PositionSelectByTicket(ticket))
return false;
return (PositionGetInteger(POSITION_MAGIC) == magic_number);
}
@@ -53,8 +55,8 @@ bool PositionSelectByTicketSymbolAndMagic(ulong ticket, string symbol, ulong mag
{
if(!PositionSelectByTicket(ticket))
return false;
return (PositionGetString(POSITION_SYMBOL) == symbol &&
return (PositionGetString(POSITION_SYMBOL) == symbol &&
PositionGetInteger(POSITION_MAGIC) == magic_number);
}
@@ -76,7 +78,7 @@ ulong GetPositionTicketByMagic(string symbol, ulong magic_number)
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
if(PositionGetString(POSITION_SYMBOL) == symbol &&
if(PositionGetString(POSITION_SYMBOL) == symbol &&
PositionGetInteger(POSITION_MAGIC) == magic_number)
{
return ticket;
@@ -94,20 +96,20 @@ bool ClosePositionByMagic(CTrade &trade_obj, string symbol, ulong magic_number)
ulong ticket = GetPositionTicketByMagic(symbol, magic_number);
if(ticket == 0)
return false;
return trade_obj.PositionClose(ticket);
}
//+------------------------------------------------------------------+
//| Modify position by symbol and magic number |
//+------------------------------------------------------------------+
bool ModifyPositionByMagic(CTrade &trade_obj, string symbol, ulong magic_number,
double sl, double tp)
bool ModifyPositionByMagic(CTrade &trade_obj, string symbol, ulong magic_number,
double sl, double tp)
{
ulong ticket = GetPositionTicketByMagic(symbol, magic_number);
if(ticket == 0)
return false;
return trade_obj.PositionModify(ticket, sl, tp);
}
@@ -118,7 +120,7 @@ double GetPositionProfitByMagic(string symbol, ulong magic_number)
{
if(!PositionSelectByMagic(symbol, magic_number))
return 0.0;
return PositionGetDouble(POSITION_PROFIT);
}
@@ -129,7 +131,7 @@ ENUM_POSITION_TYPE GetPositionTypeByMagic(string symbol, ulong magic_number)
{
if(!PositionSelectByMagic(symbol, magic_number))
return WRONG_VALUE;
return (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
}
@@ -144,7 +146,7 @@ int CountPositionsByMagic(string symbol, ulong magic_number)
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
if(PositionGetString(POSITION_SYMBOL) == symbol &&
if(PositionGetString(POSITION_SYMBOL) == symbol &&
PositionGetInteger(POSITION_MAGIC) == magic_number)
{
count++;
@@ -0,0 +1,607 @@
//+------------------------------------------------------------------+
//| PerformanceEvaluator.mqh |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Performance Metrics Structure |
//+------------------------------------------------------------------+
struct StrategyPerformance {
string strategyName;
string symbol; // Store symbol to determine if it's a stock
int magicNumber;
double initialLotSize;
double currentLotSize;
double quarterProfit;
double quarterTrades;
double quarterWins;
double quarterLosses;
double maxDrawdown;
double winRate;
datetime quarterStart;
datetime quarterEnd;
bool isActive;
bool inPenaltyMode; // True if strategy is in penalty (worst performer)
double lotSizeBeforePenalty; // Store lot size before penalty
datetime penaltyStartTime; // When penalty started
};
//+------------------------------------------------------------------+
//| Global Performance Tracking |
//+------------------------------------------------------------------+
StrategyPerformance strategyPerformances[];
int totalStrategies = 0;
datetime lastMonthCheck = 0;
datetime currentMonthStart = 0;
datetime currentMonthEnd = 0;
//+------------------------------------------------------------------+
//| Performance Adjustment Parameters |
//+------------------------------------------------------------------+
input group "=== Performance Evaluation Settings ==="
input bool PE_EnableAutoAdjustment = true; // Enable automatic lot size adjustment
input double PE_LotSizeIncreasePercent = 10.0; // % increase for top-ranked strategies
input double PE_LotSizeDecreasePercent = 10.0; // % decrease for bottom-ranked strategies
input double PE_MinLotSize = 0.01; // Minimum lot size for forex/crypto
input double PE_MinLotSizeStocks = 5.0; // Minimum lot size for stocks (5-10 range)
input double PE_MaxLotSize = 100.0; // Maximum lot size after adjustment
input int PE_TopPerformersCount = 3; // Number of top strategies to increase lot size
input int PE_BottomPerformersCount = 3; // Number of bottom strategies to decrease lot size
input bool PE_UseWinRateWeight = true; // Consider win rate in ranking (50% profit, 50% win rate)
input bool PE_EnableBlitzPlay = true; // Enable blitz play: worst performer gets minimum lot size penalty
input bool PE_EnableLogging = true; // Enable performance logging
//+------------------------------------------------------------------+
//| Initialize Performance Tracking |
//+------------------------------------------------------------------+
void InitPerformanceTracking()
{
// Calculate current month dates
MqlDateTime dt;
TimeToStruct(TimeCurrent(), dt);
// Determine month start (first day of current month)
dt.day = 1;
dt.hour = 0;
dt.min = 0;
dt.sec = 0;
currentMonthStart = StructToTime(dt);
// Calculate month end (first day of next month - 1 second)
dt.mon += 1;
if(dt.mon > 12)
{
dt.mon = 1;
dt.year++;
}
currentMonthEnd = StructToTime(dt) - 1; // End of last day of month
lastMonthCheck = TimeCurrent();
if(PE_EnableLogging)
{
Print("Performance Evaluator: Initialized");
Print("Current Month Start: ", TimeToString(currentMonthStart));
Print("Current Month End: ", TimeToString(currentMonthEnd));
}
}
//+------------------------------------------------------------------+
//| Check if Symbol is a Stock |
//+------------------------------------------------------------------+
bool IsStockSymbol(string symbol)
{
// Check if symbol contains common stock indicators
if(StringFind(symbol, ".US") >= 0) return true;
if(StringFind(symbol, "NASDAQ:") >= 0) return true;
if(StringFind(symbol, "NYSE:") >= 0) return true;
// Note: Symbol category check removed to avoid enum conversion issues
// String-based checks (.US, NASDAQ:, NYSE:, common tickers) are sufficient
// Common stock tickers (without .US suffix)
string commonStocks[] = {"AAPL", "MSFT", "NVDA", "TSLA", "GOOGL", "AMZN", "META", "NFLX"};
for(int i = 0; i < ArraySize(commonStocks); i++)
{
if(StringFind(symbol, commonStocks[i]) == 0) return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Get Minimum Lot Size for Symbol |
//+------------------------------------------------------------------+
double GetMinLotSizeForSymbol(string symbol)
{
if(IsStockSymbol(symbol))
return PE_MinLotSizeStocks;
else
return PE_MinLotSize;
}
//+------------------------------------------------------------------+
//| Register Strategy for Performance Tracking |
//+------------------------------------------------------------------+
void RegisterStrategy(string strategyName, int magicNumber, double initialLotSize, string symbol = "")
{
// Check if strategy already registered
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].strategyName == strategyName &&
strategyPerformances[i].magicNumber == magicNumber)
{
if(PE_EnableLogging)
Print("Performance Evaluator: Strategy '", strategyName, "' already registered");
return;
}
}
// Add new strategy
int newSize = ArraySize(strategyPerformances) + 1;
ArrayResize(strategyPerformances, newSize);
strategyPerformances[newSize - 1].strategyName = strategyName;
strategyPerformances[newSize - 1].symbol = symbol;
strategyPerformances[newSize - 1].magicNumber = magicNumber;
strategyPerformances[newSize - 1].initialLotSize = initialLotSize;
// Start with minimum lot size for safety (symbol-specific minimum)
double minLot = GetMinLotSizeForSymbol(symbol);
strategyPerformances[newSize - 1].currentLotSize = minLot;
strategyPerformances[newSize - 1].quarterProfit = 0.0;
strategyPerformances[newSize - 1].quarterTrades = 0;
strategyPerformances[newSize - 1].quarterWins = 0;
strategyPerformances[newSize - 1].quarterLosses = 0;
strategyPerformances[newSize - 1].maxDrawdown = 0.0;
strategyPerformances[newSize - 1].winRate = 0.0;
strategyPerformances[newSize - 1].quarterStart = currentMonthStart;
strategyPerformances[newSize - 1].quarterEnd = currentMonthEnd;
strategyPerformances[newSize - 1].isActive = true;
strategyPerformances[newSize - 1].inPenaltyMode = false;
strategyPerformances[newSize - 1].lotSizeBeforePenalty = initialLotSize;
strategyPerformances[newSize - 1].penaltyStartTime = 0;
totalStrategies = newSize;
if(PE_EnableLogging)
Print("Performance Evaluator: Registered strategy '", strategyName,
"' (Magic: ", magicNumber, ", Initial Lot: ", initialLotSize, ")");
}
//+------------------------------------------------------------------+
//| Update Strategy Performance Metrics |
//+------------------------------------------------------------------+
void UpdateStrategyPerformance(string strategyName, int magicNumber)
{
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].strategyName == strategyName &&
strategyPerformances[i].magicNumber == magicNumber &&
strategyPerformances[i].isActive)
{
// Calculate performance for current quarter
double totalProfit = 0.0;
int totalTrades = 0;
int wins = 0;
int losses = 0;
double maxDD = 0.0;
double peakBalance = 0.0;
// Scan all closed deals in current quarter
datetime quarterStart = strategyPerformances[i].quarterStart;
datetime quarterEnd = strategyPerformances[i].quarterEnd;
// Select history for the quarter
if(HistorySelect(quarterStart, quarterEnd))
{
int totalDeals = HistoryDealsTotal();
for(int j = 0; j < totalDeals; j++)
{
ulong ticket = HistoryDealGetTicket(j);
if(ticket > 0)
{
long dealMagic = HistoryDealGetInteger(ticket, DEAL_MAGIC);
if(dealMagic == magicNumber)
{
double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT);
double swap = HistoryDealGetDouble(ticket, DEAL_SWAP);
double commission = HistoryDealGetDouble(ticket, DEAL_COMMISSION);
double totalDealProfit = profit + swap + commission;
totalProfit += totalDealProfit;
totalTrades++;
if(totalDealProfit > 0)
wins++;
else if(totalDealProfit < 0)
losses++;
}
}
}
}
// Calculate win rate
double winRate = 0.0;
if(totalTrades > 0)
winRate = (double)wins / (double)totalTrades * 100.0;
// Update metrics
strategyPerformances[i].quarterProfit = totalProfit;
strategyPerformances[i].quarterTrades = totalTrades;
strategyPerformances[i].quarterWins = wins;
strategyPerformances[i].quarterLosses = losses;
strategyPerformances[i].winRate = winRate;
break;
}
}
}
//+------------------------------------------------------------------+
//| Strategy Ranking Structure |
//+------------------------------------------------------------------+
struct StrategyRank {
int index;
double score;
};
//+------------------------------------------------------------------+
//| Calculate Strategy Score for Ranking |
//+------------------------------------------------------------------+
double CalculateStrategyScore(int strategyIndex)
{
double profit = strategyPerformances[strategyIndex].quarterProfit;
double winRate = strategyPerformances[strategyIndex].winRate;
double trades = strategyPerformances[strategyIndex].quarterTrades;
// Normalize profit (scale to 0-100 range, assuming max profit of $1000)
double normalizedProfit = MathMin(profit / 10.0, 100.0);
if(profit < 0) normalizedProfit = profit / 5.0; // Penalize losses more
// Calculate score
double score = 0.0;
if(PE_UseWinRateWeight)
{
// 50% profit, 50% win rate (if enough trades)
if(trades >= 5)
score = (normalizedProfit * 0.5) + (winRate * 0.5);
else
score = normalizedProfit; // Not enough trades, use profit only
}
else
{
// Profit only
score = normalizedProfit;
}
return score;
}
//+------------------------------------------------------------------+
//| Check if Month Ended and Evaluate Performance |
//+------------------------------------------------------------------+
void CheckMonthEnd()
{
datetime now = TimeCurrent();
// Check if we've entered a new month
if(now >= currentMonthEnd)
{
if(PE_EnableLogging)
Print("Performance Evaluator: Month ended. Evaluating and ranking strategies...");
// Update performance metrics for all strategies
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
{
UpdateStrategyPerformance(strategyPerformances[i].strategyName,
strategyPerformances[i].magicNumber);
}
}
// Rank strategies
int activeCount = 0;
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
activeCount++;
}
if(activeCount > 0)
{
// Create ranking array
StrategyRank ranks[];
ArrayResize(ranks, activeCount);
int rankIndex = 0;
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
{
ranks[rankIndex].index = i;
ranks[rankIndex].score = CalculateStrategyScore(i);
rankIndex++;
}
}
// Sort by score (descending - highest score first)
for(int i = 0; i < activeCount - 1; i++)
{
for(int j = i + 1; j < activeCount; j++)
{
if(ranks[j].score > ranks[i].score)
{
StrategyRank temp = ranks[i];
ranks[i] = ranks[j];
ranks[j] = temp;
}
}
}
// Adjust lot sizes based on ranking
if(PE_EnableAutoAdjustment)
{
// Increase top performers (skip if in penalty mode)
int topCount = MathMin(PE_TopPerformersCount, activeCount);
for(int i = 0; i < topCount; i++)
{
int strategyIdx = ranks[i].index;
// Skip if strategy is in penalty mode
if(strategyPerformances[strategyIdx].inPenaltyMode)
continue;
double oldLotSize = strategyPerformances[strategyIdx].currentLotSize;
double newLotSize = oldLotSize * (1.0 + PE_LotSizeIncreasePercent / 100.0);
if(newLotSize > PE_MaxLotSize)
newLotSize = PE_MaxLotSize;
strategyPerformances[strategyIdx].currentLotSize = newLotSize;
if(PE_EnableLogging)
Print("Performance Evaluator: Rank #", (i+1), " - Increasing '",
strategyPerformances[strategyIdx].strategyName,
"' lot size from ", oldLotSize, " to ", newLotSize,
" (Score: ", DoubleToString(ranks[i].score, 2),
", Profit: $", DoubleToString(strategyPerformances[strategyIdx].quarterProfit, 2),
", Win Rate: ", DoubleToString(strategyPerformances[strategyIdx].winRate, 2), "%)");
}
// Decrease bottom performers (skip worst one if blitz play is enabled)
int bottomCount = MathMin(PE_BottomPerformersCount, activeCount);
int startIdx = activeCount - bottomCount;
// If blitz play is enabled, skip the worst performer (it will get minimum penalty)
if(PE_EnableBlitzPlay && activeCount > 0)
startIdx = activeCount - bottomCount + 1;
for(int i = startIdx; i < activeCount; i++)
{
int strategyIdx = ranks[i].index;
// Skip if strategy is in penalty mode
if(strategyPerformances[strategyIdx].inPenaltyMode)
continue;
double oldLotSize = strategyPerformances[strategyIdx].currentLotSize;
double newLotSize = oldLotSize * (1.0 - PE_LotSizeDecreasePercent / 100.0);
// Use symbol-specific minimum lot size
double minLot = GetMinLotSizeForSymbol(strategyPerformances[strategyIdx].symbol);
if(newLotSize < minLot)
newLotSize = minLot;
strategyPerformances[strategyIdx].currentLotSize = newLotSize;
if(PE_EnableLogging)
Print("Performance Evaluator: Rank #", (i+1), " - Decreasing '",
strategyPerformances[strategyIdx].strategyName,
"' lot size from ", oldLotSize, " to ", newLotSize,
" (Score: ", DoubleToString(ranks[i].score, 2),
", Profit: $", DoubleToString(strategyPerformances[strategyIdx].quarterProfit, 2),
", Win Rate: ", DoubleToString(strategyPerformances[strategyIdx].winRate, 2), "%)");
}
}
// Blitz Play: Apply penalty to worst performer
if(PE_EnableBlitzPlay && activeCount > 0)
{
// Find worst performer (last in ranking)
int worstIdx = ranks[activeCount - 1].index;
// Remove penalty from previous worst performer (if any)
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive && strategyPerformances[i].inPenaltyMode)
{
// Check if penalty period has passed (one month)
if(now - strategyPerformances[i].penaltyStartTime >= 2592000) // ~30 days
{
// Restore lot size to before penalty
strategyPerformances[i].currentLotSize = strategyPerformances[i].lotSizeBeforePenalty;
strategyPerformances[i].inPenaltyMode = false;
strategyPerformances[i].penaltyStartTime = 0;
if(PE_EnableLogging)
Print("Blitz Play: Penalty removed from '", strategyPerformances[i].strategyName,
"'. Lot size restored to ", strategyPerformances[i].currentLotSize);
}
}
}
// Apply penalty to new worst performer
if(!strategyPerformances[worstIdx].inPenaltyMode)
{
strategyPerformances[worstIdx].lotSizeBeforePenalty = strategyPerformances[worstIdx].currentLotSize;
// Use symbol-specific minimum lot size
double minLot = GetMinLotSizeForSymbol(strategyPerformances[worstIdx].symbol);
strategyPerformances[worstIdx].currentLotSize = minLot;
strategyPerformances[worstIdx].inPenaltyMode = true;
strategyPerformances[worstIdx].penaltyStartTime = now;
if(PE_EnableLogging)
Print("Blitz Play: WORST PERFORMER - '", strategyPerformances[worstIdx].strategyName,
"' penalized! Lot size reduced from ", strategyPerformances[worstIdx].lotSizeBeforePenalty,
" to minimum ", minLot, " (Score: ", DoubleToString(ranks[activeCount - 1].score, 2),
", Profit: $", DoubleToString(strategyPerformances[worstIdx].quarterProfit, 2), ")");
}
}
// Log performance report
if(PE_EnableLogging)
{
Print("=== Monthly Performance Ranking ===");
for(int i = 0; i < activeCount; i++)
{
int strategyIdx = ranks[i].index;
Print("Rank #", (i+1), ": ", strategyPerformances[strategyIdx].strategyName,
" - Score: ", DoubleToString(ranks[i].score, 2),
", Profit: $", DoubleToString(strategyPerformances[strategyIdx].quarterProfit, 2),
", Win Rate: ", DoubleToString(strategyPerformances[strategyIdx].winRate, 2), "%",
", Trades: ", (int)strategyPerformances[strategyIdx].quarterTrades,
", Lot Size: ", DoubleToString(strategyPerformances[strategyIdx].currentLotSize, 2));
}
Print("===================================");
}
}
// Reset month metrics for all strategies
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
{
strategyPerformances[i].quarterProfit = 0.0;
strategyPerformances[i].quarterTrades = 0;
strategyPerformances[i].quarterWins = 0;
strategyPerformances[i].quarterLosses = 0;
strategyPerformances[i].maxDrawdown = 0.0;
strategyPerformances[i].winRate = 0.0;
}
}
// Update month dates
MqlDateTime dt;
TimeToStruct(now, dt);
// First day of current month
dt.day = 1;
dt.hour = 0;
dt.min = 0;
dt.sec = 0;
currentMonthStart = StructToTime(dt);
// First day of next month - 1 second
dt.mon += 1;
if(dt.mon > 12)
{
dt.mon = 1;
dt.year++;
}
currentMonthEnd = StructToTime(dt) - 1;
// Update month dates for all strategies
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
strategyPerformances[i].quarterStart = currentMonthStart;
strategyPerformances[i].quarterEnd = currentMonthEnd;
}
lastMonthCheck = now;
}
}
//+------------------------------------------------------------------+
//| Get Current Lot Size for Strategy |
//+------------------------------------------------------------------+
double GetStrategyLotSize(string strategyName, int magicNumber)
{
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].strategyName == strategyName &&
strategyPerformances[i].magicNumber == magicNumber &&
strategyPerformances[i].isActive)
{
return strategyPerformances[i].currentLotSize;
}
}
return 0.0;
}
//+------------------------------------------------------------------+
//| Process Performance Evaluation (call from OnTick) |
//+------------------------------------------------------------------+
void ProcessPerformanceEvaluation()
{
// Check if month ended
CheckMonthEnd();
// Check for penalty expiration (blitz play)
if(PE_EnableBlitzPlay)
{
datetime now = TimeCurrent();
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive && strategyPerformances[i].inPenaltyMode)
{
// Check if penalty period has passed (one month = ~30 days)
if(now - strategyPerformances[i].penaltyStartTime >= 2592000)
{
// Restore lot size to before penalty
strategyPerformances[i].currentLotSize = strategyPerformances[i].lotSizeBeforePenalty;
strategyPerformances[i].inPenaltyMode = false;
strategyPerformances[i].penaltyStartTime = 0;
if(PE_EnableLogging)
Print("Blitz Play: Penalty expired for '", strategyPerformances[i].strategyName,
"'. Lot size restored to ", strategyPerformances[i].currentLotSize);
}
}
}
}
// Update performance metrics periodically (every hour)
static datetime lastUpdate = 0;
if(TimeCurrent() - lastUpdate >= 3600)
{
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
{
UpdateStrategyPerformance(strategyPerformances[i].strategyName,
strategyPerformances[i].magicNumber);
}
}
lastUpdate = TimeCurrent();
}
}
//+------------------------------------------------------------------+
//| Get Performance Summary |
//+------------------------------------------------------------------+
string GetPerformanceSummary()
{
string summary = "\n=== Performance Summary ===\n";
summary += "Current Month: " + TimeToString(currentMonthStart) + " to " + TimeToString(currentMonthEnd) + "\n\n";
for(int i = 0; i < ArraySize(strategyPerformances); i++)
{
if(strategyPerformances[i].isActive)
{
summary += strategyPerformances[i].strategyName + ":\n";
summary += " Profit: $" + DoubleToString(strategyPerformances[i].quarterProfit, 2) + "\n";
summary += " Trades: " + IntegerToString((int)strategyPerformances[i].quarterTrades) + "\n";
summary += " Win Rate: " + DoubleToString(strategyPerformances[i].winRate, 2) + "%\n";
summary += " Lot Size: " + DoubleToString(strategyPerformances[i].currentLotSize, 2) + "\n\n";
}
}
return summary;
}
//+------------------------------------------------------------------+
@@ -0,0 +1,76 @@
# United EA Strategy Configuration Summary
## Strategy Symbols and Magic Numbers
### Strategy 1: DarvasBox
- **Symbol**: XAUUSD (Gold/USD)
- **Magic Number**: 135790
### Strategy 2: EMASlopeDistance
- **Symbol**: XAUUSD (Gold/USD)
- **Magic Number**: 12350
### Strategy 3: RSICrossOverReversal
- **Symbol**: XAUUSD (Gold/USD)
- **Magic Number**: 7
### Strategy 4: RSIMidPointHijack
- **Symbol**: XAUUSD (Gold/USD)
- **Magic Numbers**:
- RSIFollow: 1001
- RSIReverse: 1002
- EMACross: 1003
### Strategy 5: RSI Scalping APPL (Apple)
- **Symbol**: AAPL (Apple stock)
- **Magic Number**: 20001
- **Note**: Changed from "APPL" to "AAPL" (correct ticker symbol)
### Strategy 6: RSI Scalping BTCUSD
- **Symbol**: BTCUSD (Bitcoin/USD)
- **Magic Number**: 123459123
### Strategy 7: RSI Scalping MSFT
- **Symbol**: MSFT (Microsoft stock)
- **Magic Number**: 20002
### Strategy 8: RSI Scalping NVDA
- **Symbol**: NVDA (NVIDIA stock)
- **Magic Number**: 20003
### Strategy 9: RSI Scalping TSLA
- **Symbol**: TSLA (Tesla stock)
- **Magic Number**: 125421321
### Strategy 10: RSI Scalping XAUUSD
- **Symbol**: XAUUSD (Gold/USD)
- **Magic Number**: 129102315
## Important Notes
1. **Stock Symbols**: Stock symbols (AAPL, MSFT, NVDA, TSLA) must be:
- Added to Market Watch in MetaTrader 5
- Available from your broker
- Use the correct ticker symbol (e.g., "AAPL" not "APPL")
2. **Magic Numbers**: All strategies have unique magic numbers to prevent interference:
- Each strategy can be identified by its magic number
- RSIMidPointHijack uses 3 magic numbers (one for each sub-strategy)
3. **Symbol Configuration**: Each strategy trades on its own symbol:
- You can change symbols in the input parameters
- The EA will log warnings if a symbol is not available
- Strategies with unavailable symbols will be skipped (EA continues running)
4. **RSI Scalping Strategies**:
- Each RSI Scalping variant trades on a different symbol
- They all use the same strategy logic but with different parameters
- Buy and sell signals are generated based on RSI levels for each symbol
## Troubleshooting
If stock symbols are not working:
1. Check if the symbol exists in your broker's symbol list
2. Add the symbol to Market Watch in MetaTrader 5
3. Verify the symbol name matches your broker's naming convention
4. Some brokers use prefixes/suffixes (e.g., "NASDAQ:AAPL" or "AAPL.US")
@@ -0,0 +1,300 @@
//+------------------------------------------------------------------+
//| DarvasBoxStrategy.mqh |
//+------------------------------------------------------------------+
bool InitDarvasBox(string symbol)
{
dbData.symbol = symbol;
dbData.boxHigh = 0;
dbData.boxLow = 0;
dbData.boxFormed = false;
dbData.lastBoxTime = 0;
dbData.boxName = "DarvasBox_" + IntegerToString(DB_MagicNumber) + "_";
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("DarvasBox: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false;
}
Sleep(100); // Wait for symbol to be ready
dbData.point = SymbolInfoDouble(symbol, SYMBOL_POINT);
dbData.minStopLevel = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * dbData.point;
dbData.maHandle = iMA(symbol, DB_TrendTimeframe, DB_MA_Period, 0, DB_MA_Method, DB_MA_Price);
dbData.volumeHandle = iVolumes(symbol, PERIOD_CURRENT, VOLUME_TICK);
if(dbData.maHandle == INVALID_HANDLE || dbData.volumeHandle == INVALID_HANDLE)
{
Print("DarvasBox: Error creating indicators for '", symbol, "'");
return false;
}
dbData.trade.SetDeviationInPoints(10);
dbData.trade.SetTypeFilling(ORDER_FILLING_IOC);
dbData.trade.SetAsyncMode(false);
dbData.trade.SetExpertMagicNumber(DB_MagicNumber);
ObjectsDeleteAll(0, dbData.boxName);
dbData.isInitialized = true;
Print("DarvasBox: Successfully initialized for symbol '", symbol, "'");
return true;
}
void DeinitDarvasBox()
{
if(dbData.maHandle != INVALID_HANDLE) IndicatorRelease(dbData.maHandle);
if(dbData.volumeHandle != INVALID_HANDLE) IndicatorRelease(dbData.volumeHandle);
ObjectsDeleteAll(0, dbData.boxName);
}
void DrawDarvasBox()
{
if(!dbData.boxFormed) return;
datetime time1 = iTime(dbData.symbol, PERIOD_H1, DB_BoxPeriod);
datetime time2 = iTime(dbData.symbol, PERIOD_H1, 0);
ObjectsDeleteAll(0, dbData.boxName);
ObjectCreate(0, dbData.boxName + "Top", OBJ_TREND, 0, time1, dbData.boxHigh, time2, dbData.boxHigh);
ObjectCreate(0, dbData.boxName + "Bottom", OBJ_TREND, 0, time1, dbData.boxLow, time2, dbData.boxLow);
ObjectSetInteger(0, dbData.boxName + "Top", OBJPROP_COLOR, DB_BoxColor);
ObjectSetInteger(0, dbData.boxName + "Bottom", OBJPROP_COLOR, DB_BoxColor);
ObjectSetInteger(0, dbData.boxName + "Top", OBJPROP_WIDTH, DB_BoxWidth);
ObjectSetInteger(0, dbData.boxName + "Bottom", OBJPROP_WIDTH, DB_BoxWidth);
ObjectSetInteger(0, dbData.boxName + "Top", OBJPROP_RAY_RIGHT, true);
ObjectSetInteger(0, dbData.boxName + "Bottom", OBJPROP_RAY_RIGHT, true);
}
void CalculateDarvasBox()
{
double high = 0;
double low = DBL_MAX;
// Find highest high and lowest low in the period - EXACTLY like original
for(int i = 0; i < DB_BoxPeriod; i++)
{
high = MathMax(high, iHigh(dbData.symbol, PERIOD_H1, i));
low = MathMin(low, iLow(dbData.symbol, PERIOD_H1, i));
}
double range = high - low;
double allowedRange = DB_BoxDeviation * dbData.point; // Use dbData.point instead of _Point
if(DB_EnableLogging)
{
Print("DarvasBox: Box Calculation - High: ", high, " Low: ", low, " Range: ", range, " Allowed Range: ", allowedRange);
}
// Check if box is formed - EXACTLY like original
if(range <= allowedRange)
{
dbData.boxHigh = high;
dbData.boxLow = low;
dbData.boxFormed = true;
dbData.lastBoxTime = iTime(dbData.symbol, PERIOD_CURRENT, 0);
// Draw the box
DrawDarvasBox();
if(DB_EnableLogging)
Print("DarvasBox: Box Formed - High: ", dbData.boxHigh, " Low: ", dbData.boxLow, " Time: ", dbData.lastBoxTime);
}
else
{
dbData.boxFormed = false;
// Delete box if it exists
ObjectsDeleteAll(0, dbData.boxName);
}
}
bool ValidateStopLevels(double price, double &sl, double &tp, ENUM_ORDER_TYPE orderType)
{
double minSlDistance = MathMax(dbData.minStopLevel, DB_StopLoss * dbData.point);
double minTpDistance = MathMax(dbData.minStopLevel, DB_TakeProfit * dbData.point);
if(orderType == ORDER_TYPE_BUY)
{
sl = price - minSlDistance;
tp = price + minTpDistance;
}
else
{
sl = price + minSlDistance;
tp = price - minTpDistance;
}
return true;
}
bool IsTrendFavorable(ENUM_ORDER_TYPE orderType)
{
double ma[];
ArraySetAsSeries(ma, true);
if(CopyBuffer(dbData.maHandle, 0, 0, 2, ma) <= 0)
return false;
double currentPrice = SymbolInfoDouble(dbData.symbol, SYMBOL_ASK);
double trendStrength = MathAbs(currentPrice - ma[0]) / dbData.point;
if(orderType == ORDER_TYPE_BUY)
return (currentPrice > ma[0] && trendStrength > DB_TrendThreshold);
else
return (currentPrice < ma[0] && trendStrength > DB_TrendThreshold);
}
bool CheckVolumeConditions()
{
double volumes[];
ArraySetAsSeries(volumes, true);
if(CopyBuffer(dbData.volumeHandle, 0, 0, DB_VolumeMA_Period + 1, volumes) <= 0)
return false;
double volumeMA = 0;
for(int i = 1; i <= DB_VolumeMA_Period; i++)
volumeMA += volumes[i];
volumeMA /= DB_VolumeMA_Period;
double currentVolume = volumes[0];
double volumeRatio = currentVolume / volumeMA;
return (volumeRatio > DB_VolumeThresholdMultiplier);
}
bool PlaceOrder(ENUM_ORDER_TYPE orderType, double price, double sl, double tp)
{
if(!ValidateStopLevels(price, sl, tp, orderType))
{
if(DB_EnableLogging)
Print("DarvasBox: Order rejected - Stop levels validation failed");
return false;
}
if(!IsTrendFavorable(orderType))
{
if(DB_EnableLogging)
Print("DarvasBox: Order rejected - Trend not favorable for ", EnumToString(orderType));
return false;
}
if(!CheckVolumeConditions())
{
if(DB_EnableLogging)
Print("DarvasBox: Order rejected - Volume conditions not met");
return false;
}
bool result = false;
// Use market price (0) instead of explicit price - this ensures market order execution
// In backtesting, explicit price might fail if price has moved
if(orderType == ORDER_TYPE_BUY)
result = dbData.trade.Buy(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakout");
else
result = dbData.trade.Sell(0.01, dbData.symbol, 0, sl, tp, "Darvas Box Breakdown");
// Always log errors, success only if logging enabled
if(result)
{
if(DB_EnableLogging)
Print("DarvasBox: ", (orderType == ORDER_TYPE_BUY ? "Buy" : "Sell"), " Order Placed Successfully");
}
else
{
// Always log failures with detailed info
uint retcode_uint = dbData.trade.ResultRetcode();
int retcode = (int)retcode_uint;
string desc = dbData.trade.ResultRetcodeDescription();
ulong deal = dbData.trade.ResultDeal();
ulong order = dbData.trade.ResultOrder();
Print("DarvasBox: ", (orderType == ORDER_TYPE_BUY ? "Buy" : "Sell"),
" Order Failed - Retcode: ", retcode,
", Description: ", desc,
", Deal: ", deal,
", Order: ", order,
", Symbol: ", dbData.symbol,
", Requested Price: ", price,
", SL: ", sl,
", TP: ", tp);
}
return result;
}
void ProcessDarvasBox(string symbol)
{
// Skip if not initialized (symbol not available)
if(!dbData.isInitialized)
return;
dbData.symbol = symbol; // Update symbol in case it changed
// Calculate new box levels - EXACTLY like original (called every tick)
CalculateDarvasBox();
// Check for trading signals - EXACTLY like original (checked every tick)
if(dbData.boxFormed)
{
double currentPrice = SymbolInfoDouble(dbData.symbol, SYMBOL_ASK);
long currentVolume_long = iVolume(dbData.symbol, PERIOD_CURRENT, 0);
double currentVolume = (double)currentVolume_long;
if(DB_EnableLogging)
{
Print("DarvasBox: Current Price: ", currentPrice, " Box High: ", dbData.boxHigh, " Box Low: ", dbData.boxLow);
Print("DarvasBox: Current Volume: ", currentVolume, " Volume Threshold: ", DB_VolumeThreshold);
}
// Check for breakout above box - EXACTLY like original
if(currentPrice > dbData.boxHigh && currentVolume > DB_VolumeThreshold)
{
if(DB_EnableLogging)
Print("DarvasBox: Breakout Signal Detected - Price above box high");
// Buy signal
if(!PositionExistsByMagic(dbData.symbol, (ulong)DB_MagicNumber)) // No existing positions with our magic number
{
double sl = currentPrice - DB_StopLoss * dbData.point;
double tp = currentPrice + DB_TakeProfit * dbData.point;
if(DB_EnableLogging)
Print("DarvasBox: Preparing Buy Order - Price: ", currentPrice, " SL: ", sl, " TP: ", tp);
PlaceOrder(ORDER_TYPE_BUY, currentPrice, sl, tp);
}
else if(DB_EnableLogging)
Print("DarvasBox: Skipping Buy Signal - Position already exists");
}
// Check for breakdown below box - EXACTLY like original
if(currentPrice < dbData.boxLow && currentVolume > DB_VolumeThreshold)
{
if(DB_EnableLogging)
Print("DarvasBox: Breakdown Signal Detected - Price below box low");
// Sell signal
if(!PositionExistsByMagic(dbData.symbol, (ulong)DB_MagicNumber)) // No existing positions with our magic number
{
double sl = currentPrice + DB_StopLoss * dbData.point;
double tp = currentPrice - DB_TakeProfit * dbData.point;
if(DB_EnableLogging)
Print("DarvasBox: Preparing Sell Order - Price: ", currentPrice, " SL: ", sl, " TP: ", tp);
PlaceOrder(ORDER_TYPE_SELL, currentPrice, sl, tp);
}
else if(DB_EnableLogging)
Print("DarvasBox: Skipping Sell Signal - Position already exists");
}
}
else if(DB_EnableLogging)
Print("DarvasBox: No Box Formed - Waiting for consolidation");
}
//+------------------------------------------------------------------+
@@ -0,0 +1,496 @@
//+------------------------------------------------------------------+
//| EMASlopeDistanceStrategy.mqh |
//+------------------------------------------------------------------+
bool InitEMASlopeDistance(string symbol)
{
esData.symbol = symbol;
esData.letzte_überwachung_zeit = 0;
esData.überwachung_aktiv = false;
esData.preis_trigger_aktiv = false;
esData.steigung_trigger_aktiv = false;
esData.ticket = 0;
esData.trades_in_current_crossover = 0;
esData.crossover_detected = false;
esData.trade_open_time = 0;
esData.last_bar_time = 0;
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("EMASlopeDistance: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false;
}
Sleep(100); // Wait for symbol to be ready
esData.trade.SetExpertMagicNumber(ES_MagicNumber);
esData.trade.SetDeviationInPoints(10);
esData.trade.SetTypeFilling(ORDER_FILLING_IOC);
esData.ema_handle = iMA(symbol, ES_Timeframe, ES_EMA_Periode, 0, MODE_EMA, PRICE_CLOSE);
if(esData.ema_handle == INVALID_HANDLE)
{
Print("EMASlopeDistance: Error creating EMA indicator for '", symbol, "'");
return false;
}
ArraySetAsSeries(esData.ema_array, true);
esData.isInitialized = true;
Print("EMASlopeDistance: Successfully initialized for symbol '", symbol, "'");
return true;
}
void DeinitEMASlopeDistance()
{
if(esData.ema_handle != INVALID_HANDLE)
IndicatorRelease(esData.ema_handle);
}
//+------------------------------------------------------------------+
//| EMA Berechnung (EMA Calculation) |
//+------------------------------------------------------------------+
void BerechneEMA()
{
//--- EMA Werte vom Indicator kopieren (Copy EMA values from indicator)
int copied = CopyBuffer(esData.ema_handle, 0, 0, 3, esData.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]: ", esData.ema_array[0], " [1]: ", esData.ema_array[1], " [2]: ", esData.ema_array[2]);
}
//+------------------------------------------------------------------+
//| Trigger-Bedingungen prüfen (Check trigger conditions) |
//+------------------------------------------------------------------+
void PrüfeTrigger()
{
if(ArraySize(esData.ema_array) < 2)
{
Print("TRACE: Array zu klein - Größe: ", ArraySize(esData.ema_array));
return;
}
//--- Aktuelle Werte (Current values)
double aktueller_preis = SymbolInfoDouble(esData.symbol, SYMBOL_BID);
double aktueller_ask = SymbolInfoDouble(esData.symbol, SYMBOL_ASK);
double aktueller_close = iClose(esData.symbol, ES_Timeframe, 0);
int digits = (int)SymbolInfoInteger(esData.symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(esData.symbol, SYMBOL_POINT);
double pips_multiplier = (digits == 3 || digits == 5) ? 10.0 : 1.0;
//--- EMA Werte in Variablen (EMA values in variables)
double ema_aktuell = esData.ema_array[0];
double ema_vorher = esData.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)
{
esData.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: ", ES_PreisSchwelle, ")");
Print("TRACE: Close: ", aktueller_close, " EMA: ", ema_aktuell);
Print("TRACE: Trades im aktuellen Crossover: ", esData.trades_in_current_crossover, "/", ES_MaxTradesPerCrossover);
if(preis_abstand > ES_PreisSchwelle && !esData.preis_trigger_aktiv)
{
esData.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: ", ES_SteigungSchwelle, ")");
if(MathAbs(steigung) > ES_SteigungSchwelle && !esData.steigung_trigger_aktiv)
{
esData.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(esData.preis_trigger_aktiv && esData.steigung_trigger_aktiv && !esData.überwachung_aktiv)
{
esData.überwachung_aktiv = true;
if(ES_UseBarData)
{
esData.letzte_überwachung_zeit = iTime(esData.symbol, ES_Timeframe, 0); // Aktuelle Bar-Zeit
Print("TRACE: Überwachung gestartet - Beide Trigger aktiv (Bar: ", TimeToString(esData.letzte_überwachung_zeit), ")");
}
else
{
esData.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(esData.ü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(esData.trades_in_current_crossover >= ES_MaxTradesPerCrossover)
{
Print("TRACE: Trade-Limit erreicht (", ES_MaxTradesPerCrossover, ") - Kein neuer Trade");
return;
}
if(bullish_signal && !PositionExistsByMagic(esData.symbol, (ulong)ES_MagicNumber))
{
Print("TRACE: Versuche KAUF-Trade zu platzieren (Trade #", esData.trades_in_current_crossover + 1, ")");
if(PlatziereTrade(ORDER_TYPE_BUY))
{
esData.trades_in_current_crossover++;
}
}
else if(bearish_signal && !PositionExistsByMagic(esData.symbol, (ulong)ES_MagicNumber))
{
Print("TRACE: Versuche VERKAUF-Trade zu platzieren (Trade #", esData.trades_in_current_crossover + 1, ")");
if(PlatziereTrade(ORDER_TYPE_SELL))
{
esData.trades_in_current_crossover++;
}
}
else if(PositionExistsByMagic(esData.symbol, (ulong)ES_MagicNumber))
{
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: ", g_ES_LotSize);
bool success = false;
if(order_type == ORDER_TYPE_BUY)
{
success = esData.trade.Buy(g_ES_LotSize, esData.symbol, 0, 0, 0, "EMA Crossover Trade");
}
else
{
success = esData.trade.Sell(g_ES_LotSize, esData.symbol, 0, 0, 0, "EMA Crossover Trade");
}
if(success)
{
esData.ticket = (int)esData.trade.ResultOrder();
Print("TRACE: Trade erfolgreich platziert: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF", " Ticket: ", esData.ticket);
//--- Trade-Öffnungszeit speichern (Save trade opening time)
esData.trade_open_time = iTime(esData.symbol, ES_Timeframe, 0);
Print("TRACE: Trade-Öffnungszeit: ", TimeToString(esData.trade_open_time));
//--- Überwachung zurücksetzen (Reset monitoring)
esData.überwachung_aktiv = false;
esData.preis_trigger_aktiv = false;
esData.steigung_trigger_aktiv = false;
return true;
}
else
{
Print("TRACE: Fehler beim Platzieren des Trades - Retcode: ", esData.trade.ResultRetcode());
Print("TRACE: Fehlerbeschreibung: ", esData.trade.ResultRetcodeDescription());
return false;
}
}
//+------------------------------------------------------------------+
//| Trades verwalten (Manage trades) |
//+------------------------------------------------------------------+
void VerwalteTrades()
{
if(!PositionSelectByMagic(esData.symbol, (ulong)ES_MagicNumber))
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);
int digits = (int)SymbolInfoInteger(esData.symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(esData.symbol, SYMBOL_POINT);
double pips_multiplier = (digits == 3 || digits == 5) ? 10.0 : 1.0;
double trailing_stop_pips = ES_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(esData.ema_array) >= 1)
{
double aktueller_close = iClose(esData.symbol, ES_Timeframe, 0);
double ema_aktuell = esData.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 ", esData.trades_in_current_crossover);
}
}
//--- Profit-Prüfung nach X Bars (Profit check after X bars)
if(ES_CloseUnprofitableTrades && esData.trade_open_time != 0 && PositionExistsByMagic(esData.symbol, (ulong)ES_MagicNumber))
{
Print("TRACE: Profit-Prüfung aktiviert - CloseUnprofitableTrades: ", ES_CloseUnprofitableTrades);
PrüfeProfitNachBars();
}
else if(!ES_CloseUnprofitableTrades)
{
Print("TRACE: Profit-Prüfung deaktiviert - CloseUnprofitableTrades: ", ES_CloseUnprofitableTrades);
}
}
//+------------------------------------------------------------------+
//| Profit-Prüfung nach X Bars (Profit check after X bars) |
//+------------------------------------------------------------------+
void PrüfeProfitNachBars()
{
if(!PositionSelectByMagic(esData.symbol, (ulong)ES_MagicNumber))
{
return; // Keine Position offen
}
datetime current_bar_time = iTime(esData.symbol, ES_Timeframe, 0);
int bars_since_trade_open = iBarShift(esData.symbol, ES_Timeframe, esData.trade_open_time);
Print("TRACE: Bars seit Trade-Öffnung: ", bars_since_trade_open, "/", ES_ProfitCheckBars);
//--- Prüfe ob genügend Bars vergangen sind (Check if enough bars have passed)
if(bars_since_trade_open >= ES_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 ", ES_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)
esData.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)
esData.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 = ModifyPositionByMagic(esData.trade, esData.symbol, (ulong)ES_MagicNumber, 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: ", esData.trade.ResultRetcode());
Print("TRACE: Fehlerbeschreibung: ", esData.trade.ResultRetcodeDescription());
}
}
//+------------------------------------------------------------------+
//| Position schließen (Close position) |
//+------------------------------------------------------------------+
void SchließePosition(string reason = "Unbekannt")
{
Print("TRACE: Versuche Position zu schließen - Grund: ", reason);
bool success = ClosePositionByMagic(esData.trade, esData.symbol, (ulong)ES_MagicNumber);
if(success)
{
Print("TRACE: Position erfolgreich geschlossen - Grund: ", reason);
}
else
{
Print("TRACE: Fehler beim Schließen der Position - Retcode: ", esData.trade.ResultRetcode());
Print("TRACE: Fehlerbeschreibung: ", esData.trade.ResultRetcodeDescription());
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void ProcessEMASlopeDistance(string symbol)
{
// Skip if not initialized (symbol not available)
if(!esData.isInitialized)
return;
esData.symbol = symbol; // Update symbol in case it changed
//--- Bar-Daten oder Tick-Daten verwenden (Use bar data or tick data)
if(ES_UseBarData)
{
//--- Nur bei neuen Bars ausführen (Only execute on new bars)
datetime current_bar_time = iTime(esData.symbol, ES_Timeframe, 0);
if(current_bar_time == esData.last_bar_time)
{
return; // Kein neuer Bar, nichts tun
}
esData.last_bar_time = current_bar_time;
}
//--- EMA Werte berechnen (Calculate EMA values)
BerechneEMA();
//--- Debug: Aktuelle Werte ausgeben (Debug: Output current values)
if(ArraySize(esData.ema_array) > 0)
{
double aktueller_close = iClose(esData.symbol, ES_Timeframe, 0);
double ema_aktuell = esData.ema_array[0];
double ema_vorher = esData.ema_array[1];
int digits = (int)SymbolInfoInteger(esData.symbol, SYMBOL_DIGITS);
double point = SymbolInfoDouble(esData.symbol, SYMBOL_POINT);
double preis_abstand = MathAbs(aktueller_close - ema_aktuell) / point;
double steigung = (ema_aktuell - ema_vorher) / point;
if(ES_UseBarData)
{
Print("=== DEBUG INFO (Neuer Bar) ===");
Print("Bar Zeit: ", TimeToString(iTime(esData.symbol, ES_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: ", esData.preis_trigger_aktiv, " Steigungs-Trigger: ", esData.steigung_trigger_aktiv);
Print("Überwachung aktiv: ", esData.überwachung_aktiv);
Print("Position offen: ", PositionExistsByMagic(esData.symbol, (ulong)ES_MagicNumber));
Print("Trades im aktuellen Crossover: ", esData.trades_in_current_crossover, "/", ES_MaxTradesPerCrossover);
Print("==================");
}
//--- Überwachung prüfen (Check monitoring)
if(esData.überwachung_aktiv)
{
if(ES_UseBarData)
{
// Bar-basierte Überwachungszeit
int bars_since_monitoring = iBarShift(esData.symbol, ES_Timeframe, esData.letzte_überwachung_zeit);
int timeout_bars = (int)(ES_ÜberwachungTimeout / PeriodSeconds(ES_Timeframe));
if(bars_since_monitoring > timeout_bars)
{
esData.überwachung_aktiv = false;
esData.preis_trigger_aktiv = false;
esData.steigung_trigger_aktiv = false;
Print("Überwachung beendet - Bar-basierte Zeitüberschreitung (", bars_since_monitoring, " Bars)");
}
}
else
{
// Tick-basierte Überwachungszeit
if(TimeCurrent() - esData.letzte_überwachung_zeit > ES_ÜberwachungTimeout)
{
esData.überwachung_aktiv = false;
esData.preis_trigger_aktiv = false;
esData.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();
}
//+------------------------------------------------------------------+
@@ -0,0 +1,257 @@
//+------------------------------------------------------------------+
//| RSICrossOverReversalStrategy.mqh |
//+------------------------------------------------------------------+
void WeekDays_Init()
{
rcData.WeekDays[0] = RC_Sunday;
rcData.WeekDays[1] = RC_Monday;
rcData.WeekDays[2] = RC_Tuesday;
rcData.WeekDays[3] = RC_Wednesday;
rcData.WeekDays[4] = RC_Thursday;
rcData.WeekDays[5] = RC_Friday;
rcData.WeekDays[6] = RC_Saturday;
}
bool WeekDays_Check(datetime aTime)
{
MqlDateTime stm;
TimeToStruct(aTime, stm);
return(rcData.WeekDays[stm.day_of_week]);
}
bool RC_HourInWindow(const int h, const int beginRaw, const int endRaw)
{
const int b = beginRaw % 24;
const int e = endRaw % 24;
if(b == e)
return false;
if(b < e)
return (h >= b && h < e);
return (h >= b || h < e);
}
bool RC_TradingHoursAllow(const int currentHour)
{
return RC_HourInWindow(currentHour, RC_tradingHourOneBegin, RC_tradingHourOneEnd)
|| RC_HourInWindow(currentHour, RC_tradingHourTwoBegin, RC_tradingHourTwoEnd);
}
int TimeHour(datetime when = 0)
{
if(when == 0) when = TimeCurrent();
MqlDateTime dt;
TimeToStruct(when, dt);
return dt.hour;
}
bool InitRSICrossOverReversal(string symbol)
{
WeekDays_Init();
rcData.symbol = symbol;
rcData.previousRSIDef = 0;
rcData.lastTradeTime = 0;
rcData.bartime = 0;
rcData.lastBarTime = 0;
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("RSICrossOverReversal: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false;
}
Sleep(100); // Wait for symbol to be ready
rcData.rsiHandle = iRSI(symbol, RC_TimeFrame1, RC_rsiPeriod, PRICE_CLOSE);
if(rcData.rsiHandle == INVALID_HANDLE)
{
Print("RSICrossOverReversal: Error creating RSI handle for '", symbol, "'");
return false;
}
rcData.emaHandle = iMA(symbol, RC_TimeFrame2, RC_emaPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(rcData.emaHandle == INVALID_HANDLE)
{
Print("RSICrossOverReversal: Error creating EMA handle for '", symbol, "'");
return false;
}
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
rcData.isInitialized = true;
Print("RSICrossOverReversal: Successfully initialized for symbol '", symbol, "'");
return true;
}
void DeinitRSICrossOverReversal()
{
if(rcData.rsiHandle != INVALID_HANDLE)
IndicatorRelease(rcData.rsiHandle);
if(rcData.emaHandle != INVALID_HANDLE)
IndicatorRelease(rcData.emaHandle);
}
void Close_Position_MN(ulong magicNumber)
{
ClosePositionByMagic(rcData.trade, rcData.symbol, (int)magicNumber);
}
void ApplyTrailingStop()
{
if(!PositionSelectByMagic(rcData.symbol, RC_MagicNumber))
return;
ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
ENUM_POSITION_TYPE trade_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
string symbol = rcData.symbol;
double POINT = SymbolInfoDouble(symbol, SYMBOL_POINT);
int DIGIT = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
if(trade_type == POSITION_TYPE_BUY)
{
double Bid = NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_BID), DIGIT);
if(Bid - PositionGetDouble(POSITION_PRICE_OPEN) > NormalizeDouble(POINT * RC_TrailingStop, DIGIT))
{
if(PositionGetDouble(POSITION_SL) < NormalizeDouble(Bid - POINT * RC_TrailingStop, DIGIT))
{
ModifyPositionByMagic(rcData.trade, symbol, RC_MagicNumber,
NormalizeDouble(Bid - POINT * RC_TrailingStop, DIGIT),
PositionGetDouble(POSITION_TP));
}
}
}
else if(trade_type == POSITION_TYPE_SELL)
{
double Ask = NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_ASK), DIGIT);
if((PositionGetDouble(POSITION_PRICE_OPEN) - Ask) > NormalizeDouble(POINT * RC_TrailingStop, DIGIT))
{
if((PositionGetDouble(POSITION_SL) > NormalizeDouble(Ask + POINT * RC_TrailingStop, DIGIT)) ||
(PositionGetDouble(POSITION_SL) == 0))
{
ModifyPositionByMagic(rcData.trade, symbol, RC_MagicNumber,
NormalizeDouble(Ask + POINT * RC_TrailingStop, DIGIT),
PositionGetDouble(POSITION_TP));
}
}
}
}
void ProcessRSICrossOverReversal(string symbol)
{
// Skip if not initialized (symbol not available)
if(!rcData.isInitialized)
return;
rcData.symbol = symbol; // Update symbol in case it changed
if(rcData.bartime == iTime(rcData.symbol, RC_BarTimeFrame, 0))
return;
rcData.bartime = iTime(rcData.symbol, RC_BarTimeFrame, 0);
double rsi[];
if(CopyBuffer(rcData.rsiHandle, 0, 0, 2, rsi) <= 0)
return;
double ema[];
if(CopyBuffer(rcData.emaHandle, 0, 0, 2, ema) <= 0)
return;
datetime currentTime = TimeCurrent();
int currentHour = TimeHour(TimeCurrent());
if(!WeekDays_Check(TimeTradeServer()))
{
Close_Position_MN(RC_MagicNumber);
return;
}
if(!RC_TradingHoursAllow(currentHour))
{
Close_Position_MN(RC_MagicNumber);
return;
}
bool hasPosition = PositionExistsByMagic(rcData.symbol, RC_MagicNumber);
double currentRSI = rsi[0];
double previousRSI = rsi[1];
if(rcData.previousRSIDef == 0)
{
rcData.previousRSIDef = currentRSI;
return;
}
double currentEMA = ema[0];
double previousEMA = ema[1];
double emaSlope = (currentEMA - previousEMA) * 100;
const double closeCurr = iClose(rcData.symbol, RC_TimeFrame1, 0);
double priceToEmaDistance = (closeCurr - currentEMA) * 10;
bool isBuyPosition = false;
bool isSellPosition = false;
if(hasPosition)
{
if(PositionSelectByMagic(rcData.symbol, RC_MagicNumber))
{
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if(positionType == POSITION_TYPE_BUY)
isBuyPosition = true;
else if(positionType == POSITION_TYPE_SELL)
isSellPosition = true;
}
}
ApplyTrailingStop();
bool cooldownPassed = (currentTime - rcData.lastTradeTime) >= RC_cooldownSeconds;
bool isTrendStrong = MathAbs(emaSlope) > RC_emaSlopeThreshold || MathAbs(priceToEmaDistance) > RC_emaDistanceThreshold;
if(isBuyPosition && currentRSI > RC_exitBuyRSI)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
}
if(isSellPosition && currentRSI < RC_exitSellRSI)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
}
if(isTrendStrong)
{
Close_Position_MN(RC_MagicNumber);
rcData.lastTradeTime = currentTime;
}
if(!isTrendStrong &&
currentRSI < RC_overboughtLevel - RC_entryRSISellSpread && rcData.previousRSIDef >= RC_overboughtLevel &&
!isSellPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
if(rcData.trade.Sell(g_RC_LotSize, rcData.symbol, 0.0, 0.0, 0.0, "Sell Order"))
{
rcData.lastTradeTime = currentTime;
}
}
if(!isTrendStrong &&
currentRSI > RC_oversoldLevel + RC_entryRSIBuySpread && rcData.previousRSIDef <= RC_oversoldLevel &&
!isBuyPosition && !hasPosition && cooldownPassed)
{
rcData.trade.SetExpertMagicNumber(RC_MagicNumber);
if(rcData.trade.Buy(g_RC_LotSize, rcData.symbol, 0.0, 0.0, 0.0, "Buy Order"))
{
rcData.lastTradeTime = currentTime;
}
}
rcData.previousRSIDef = currentRSI;
}
//+------------------------------------------------------------------+
@@ -0,0 +1,471 @@
//+------------------------------------------------------------------+
//| RSIMidPointHijackStrategy.mqh |
//+------------------------------------------------------------------+
bool IsNewBar(string symbol)
{
datetime time[];
if(CopyTime(symbol, RM_InpTimeframe, 0, 1, time) > 0)
{
if(time[0] != rmData.lastBarTime)
{
rmData.lastBarTime = time[0];
return true;
}
}
return false;
}
bool IsWithinTradingHours(int startHour, int endHour)
{
MqlDateTime currentTime;
TimeToStruct(TimeCurrent(), currentTime);
if(startHour <= endHour)
return (currentTime.hour >= startHour && currentTime.hour < endHour);
else
return (currentTime.hour >= startHour || currentTime.hour < endHour);
}
bool HasPosition(string symbol, int magic)
{
return PositionExistsByMagic(symbol, magic);
}
bool HasProfitablePosition(int excludeMagic)
{
bool hasProfitable = false;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(rmData.positionInfo.SelectByIndex(i))
{
if(rmData.positionInfo.Magic() != excludeMagic)
{
double profit = rmData.positionInfo.Profit();
if(profit > RM_InpLockProfitThreshold * _Point)
{
hasProfitable = true;
if(RM_InpCloseOppositeTrades)
{
if((excludeMagic == RM_InpMagicNumberRSIFollow && rmData.positionInfo.Magic() == RM_InpMagicNumberRSIReverse) ||
(excludeMagic == RM_InpMagicNumberRSIReverse && rmData.positionInfo.Magic() == RM_InpMagicNumberRSIFollow) ||
(excludeMagic == RM_InpMagicNumberEMACross && (rmData.positionInfo.Magic() == RM_InpMagicNumberRSIReverse || rmData.positionInfo.Magic() == RM_InpMagicNumberRSIFollow)) ||
((excludeMagic == RM_InpMagicNumberRSIFollow || excludeMagic == RM_InpMagicNumberRSIReverse) && rmData.positionInfo.Magic() == RM_InpMagicNumberEMACross))
{
ClosePosition(rmData.symbol, (int)rmData.positionInfo.Magic());
}
}
}
}
}
}
return hasProfitable;
}
bool IsRSIReverseInCooldown(string symbol)
{
if(RM_InpRSIReverseCooldownBars <= 0)
return false;
if(!rmData.rsiReverseInCooldown)
return false;
datetime time[];
if(CopyTime(symbol, RM_InpTimeframe, 0, 1, time) > 0)
{
datetime currentBarTime = time[0];
datetime cooldownEndTime = rmData.rsiReverseLastCloseTime + RM_InpRSIReverseCooldownBars * PeriodSeconds(RM_InpTimeframe);
if(currentBarTime >= cooldownEndTime)
{
rmData.rsiReverseInCooldown = false;
return false;
}
}
return true;
}
void CheckRSIFollowStrategy(string symbol)
{
if(!IsWithinTradingHours(RM_InpRSIFollowStartHour, RM_InpRSIFollowEndHour))
{
if(RM_InpRSIFollowCloseOutsideHours)
{
if(HasPosition(symbol, RM_InpMagicNumberRSIFollow))
ClosePosition(symbol, RM_InpMagicNumberRSIFollow);
}
return;
}
if(RM_InpEnableStrategyLock && HasProfitablePosition(RM_InpMagicNumberRSIFollow))
return;
if(rmData.lastBarRSI > RM_InpRSIOverbought)
rmData.rsiOverbought = true;
else if(rmData.lastBarRSI < RM_InpRSIOversold)
rmData.rsiOversold = true;
if(rmData.rsiOverbought && rmData.lastBarRSI < RM_InpRSIExitLevel)
{
if(!HasPosition(symbol, RM_InpMagicNumberRSIFollow))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberRSIFollow);
rmData.trade.Sell(g_RM_LotSize, symbol, 0, 0, 0, "RSI Follow");
}
rmData.rsiOverbought = false;
}
else if(rmData.rsiOversold && rmData.lastBarRSI > RM_InpRSIExitLevel)
{
if(!HasPosition(symbol, RM_InpMagicNumberRSIFollow))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberRSIFollow);
rmData.trade.Buy(g_RM_LotSize, symbol, 0, 0, 0, "RSI Follow");
}
rmData.rsiOversold = false;
}
}
void CheckRSIReverseStrategy(string symbol)
{
if(!IsWithinTradingHours(RM_InpRSIReverseStartHour, RM_InpRSIReverseEndHour))
{
if(RM_InpRSIReverseCloseOutsideHours)
{
if(HasPosition(symbol, RM_InpMagicNumberRSIReverse))
ClosePosition(symbol, RM_InpMagicNumberRSIReverse);
}
return;
}
if(RM_InpEnableStrategyLock && HasProfitablePosition(RM_InpMagicNumberRSIReverse))
return;
if(IsRSIReverseInCooldown(symbol))
return;
if(rmData.lastBarRSIReverse > RM_InpRSIReverseOverbought)
rmData.rsiReverseOverbought = true;
else if(rmData.lastBarRSIReverse < RM_InpRSIReverseOversold)
rmData.rsiReverseOversold = true;
if(rmData.rsiReverseOverbought && rmData.lastBarRSIReverse < RM_InpRSIReverseCrossLevel)
{
if(!HasPosition(symbol, RM_InpMagicNumberRSIReverse))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberRSIReverse);
rmData.trade.Sell(g_RM_LotSize, symbol, 0, 0, 0, "RSI Reverse");
}
rmData.rsiReverseOverbought = false;
}
else if(rmData.rsiReverseOversold && rmData.lastBarRSIReverse > RM_InpRSIReverseCrossLevel)
{
if(!HasPosition(symbol, RM_InpMagicNumberRSIReverse))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberRSIReverse);
rmData.trade.Buy(g_RM_LotSize, symbol, 0, 0, 0, "RSI Reverse");
}
rmData.rsiReverseOversold = false;
}
}
void CheckEMACrossStrategy(string symbol)
{
if(!IsWithinTradingHours(RM_InpEMACrossStartHour, RM_InpEMACrossEndHour))
{
if(RM_InpEMACrossCloseOutsideHours)
{
if(HasPosition(symbol, RM_InpMagicNumberEMACross))
ClosePosition(symbol, RM_InpMagicNumberEMACross);
}
return;
}
if(RM_InpEnableStrategyLock && HasProfitablePosition(RM_InpMagicNumberEMACross))
return;
if(rmData.lastBarEMAPrev < rmData.lastBarClosePrev && rmData.lastBarEMA > rmData.lastBarClose)
{
rmData.emaCrossBuySignal = true;
rmData.emaCrossSellSignal = false;
rmData.emaCrossSignalBar = 0;
}
else if(rmData.lastBarEMAPrev > rmData.lastBarClosePrev && rmData.lastBarEMA < rmData.lastBarClose)
{
rmData.emaCrossSellSignal = true;
rmData.emaCrossBuySignal = false;
rmData.emaCrossSignalBar = 0;
}
if(RM_InpUseEMADistanceEntry)
{
if(rmData.emaCrossBuySignal)
{
bool distanceConditionMet = true;
double emaHistory[], closeHistory[];
ArraySetAsSeries(emaHistory, true);
ArraySetAsSeries(closeHistory, true);
if(CopyBuffer(rmData.emaHandle, 0, 0, RM_InpEMADistancePeriod, emaHistory) > 0 &&
CopyClose(symbol, RM_InpTimeframe, 0, RM_InpEMADistancePeriod, closeHistory) > 0)
{
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
for(int i = 0; i < RM_InpEMADistancePeriod; i++)
{
double distance = (closeHistory[i] - emaHistory[i]) / point;
if(distance < RM_InpEMADistancePips)
{
distanceConditionMet = false;
break;
}
}
if(distanceConditionMet && !HasPosition(symbol, RM_InpMagicNumberEMACross))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberEMACross);
rmData.trade.Buy(g_RM_LotSize, symbol, 0, 0, 0, "EMA Cross Distance");
rmData.emaCrossBuySignal = false;
}
}
}
else if(rmData.emaCrossSellSignal)
{
bool distanceConditionMet = true;
double emaHistory[], closeHistory[];
ArraySetAsSeries(emaHistory, true);
ArraySetAsSeries(closeHistory, true);
if(CopyBuffer(rmData.emaHandle, 0, 0, RM_InpEMADistancePeriod, emaHistory) > 0 &&
CopyClose(symbol, RM_InpTimeframe, 0, RM_InpEMADistancePeriod, closeHistory) > 0)
{
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
for(int i = 0; i < RM_InpEMADistancePeriod; i++)
{
double distance = (emaHistory[i] - closeHistory[i]) / point;
if(distance < RM_InpEMADistancePips)
{
distanceConditionMet = false;
break;
}
}
if(distanceConditionMet && !HasPosition(symbol, RM_InpMagicNumberEMACross))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberEMACross);
rmData.trade.Sell(g_RM_LotSize, symbol, 0, 0, 0, "EMA Cross Distance");
rmData.emaCrossSellSignal = false;
}
}
}
}
else
{
if(rmData.lastBarEMAPrev < rmData.lastBarClosePrev && rmData.lastBarEMA > rmData.lastBarClose)
{
if(!HasPosition(symbol, RM_InpMagicNumberEMACross))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberEMACross);
rmData.trade.Buy(g_RM_LotSize, symbol, 0, 0, 0, "EMA Cross");
}
}
else if(rmData.lastBarEMAPrev > rmData.lastBarClosePrev && rmData.lastBarEMA < rmData.lastBarClose)
{
if(!HasPosition(symbol, RM_InpMagicNumberEMACross))
{
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberEMACross);
rmData.trade.Sell(g_RM_LotSize, symbol, 0, 0, 0, "EMA Cross");
}
}
}
if(rmData.emaCrossBuySignal || rmData.emaCrossSellSignal)
{
rmData.emaCrossSignalBar++;
if(rmData.emaCrossSignalBar > RM_InpEMADistancePeriod * 2)
{
rmData.emaCrossBuySignal = false;
rmData.emaCrossSellSignal = false;
}
}
}
void CheckExitConditions(string symbol)
{
if(RM_InpEnableRSIFollow)
{
if(HasPosition(symbol, RM_InpMagicNumberRSIFollow))
{
if(PositionSelectByMagic(symbol, RM_InpMagicNumberRSIFollow))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((posType == POSITION_TYPE_BUY && rmData.lastBarRSI < RM_InpRSIExitLevel) ||
(posType == POSITION_TYPE_SELL && rmData.lastBarRSI > RM_InpRSIExitLevel))
{
ClosePosition(symbol, RM_InpMagicNumberRSIFollow);
}
}
}
}
if(RM_InpEnableRSIReverse)
{
if(HasPosition(symbol, RM_InpMagicNumberRSIReverse))
{
if(PositionSelectByMagic(symbol, RM_InpMagicNumberRSIReverse))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((posType == POSITION_TYPE_BUY && rmData.lastBarRSIReverse < RM_InpRSIReverseExitLevel) ||
(posType == POSITION_TYPE_SELL && rmData.lastBarRSIReverse > RM_InpRSIReverseExitLevel))
{
ClosePosition(symbol, RM_InpMagicNumberRSIReverse);
}
}
}
}
if(RM_InpEnableEMACross)
{
if(HasPosition(symbol, RM_InpMagicNumberEMACross))
{
if(PositionSelectByMagic(symbol, RM_InpMagicNumberEMACross))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((posType == POSITION_TYPE_BUY && rmData.lastBarEMA > rmData.lastBarClose) ||
(posType == POSITION_TYPE_SELL && rmData.lastBarEMA < rmData.lastBarClose))
{
ClosePosition(symbol, RM_InpMagicNumberEMACross);
}
}
}
}
}
void ClosePosition(string symbol, int magic)
{
if(!PositionExistsByMagic(symbol, magic))
return;
ulong ticket = GetPositionTicketByMagic(symbol, magic);
if(ticket == 0)
return;
if(magic == RM_InpMagicNumberRSIReverse)
{
if(PositionSelectByTicketSymbolAndMagic(ticket, symbol, magic))
{
datetime time[];
if(CopyTime(symbol, RM_InpTimeframe, 0, 1, time) > 0)
{
rmData.rsiReverseLastCloseTime = time[0];
double profit = PositionGetDouble(POSITION_PROFIT);
if(!RM_InpRSIReverseCooldownOnLoss || profit < 0)
{
rmData.rsiReverseInCooldown = true;
}
}
}
}
ClosePositionByMagic(rmData.trade, symbol, magic);
}
bool InitRSIMidPointHijack(string symbol)
{
rmData.symbol = symbol;
rmData.rsiOverbought = false;
rmData.rsiOversold = false;
rmData.rsiReverseOverbought = false;
rmData.rsiReverseOversold = false;
rmData.emaCrossBuySignal = false;
rmData.emaCrossSellSignal = false;
rmData.emaCrossSignalBar = 0;
rmData.rsiReverseInCooldown = false;
rmData.lastBarRSI = 0;
rmData.lastBarRSIReverse = 0;
rmData.lastBarEMA = 0;
rmData.lastBarClose = 0;
rmData.lastBarEMAPrev = 0;
rmData.lastBarClosePrev = 0;
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("RSIMidPointHijack: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false;
}
Sleep(100); // Wait for symbol to be ready
rmData.rsiHandle = iRSI(symbol, RM_InpTimeframe, RM_InpRSIPeriod, PRICE_CLOSE);
rmData.rsiReverseHandle = iRSI(symbol, RM_InpTimeframe, RM_InpRSIReversePeriod, PRICE_CLOSE);
rmData.emaHandle = iMA(symbol, RM_InpTimeframe, RM_InpEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(rmData.rsiHandle == INVALID_HANDLE || rmData.rsiReverseHandle == INVALID_HANDLE || rmData.emaHandle == INVALID_HANDLE)
{
Print("RSIMidPointHijack: Error creating indicators for '", symbol, "'");
return false;
}
rmData.trade.SetExpertMagicNumber(RM_InpMagicNumberRSIFollow);
rmData.trade.SetMarginMode();
rmData.trade.SetTypeFillingBySymbol(symbol);
rmData.trade.SetDeviationInPoints(10);
datetime time[];
if(CopyTime(symbol, RM_InpTimeframe, 0, 1, time) > 0)
rmData.lastBarTime = time[0];
rmData.isInitialized = true;
Print("RSIMidPointHijack: Successfully initialized for symbol '", symbol, "'");
return true;
}
void DeinitRSIMidPointHijack()
{
if(rmData.rsiHandle != INVALID_HANDLE) IndicatorRelease(rmData.rsiHandle);
if(rmData.rsiReverseHandle != INVALID_HANDLE) IndicatorRelease(rmData.rsiReverseHandle);
if(rmData.emaHandle != INVALID_HANDLE) IndicatorRelease(rmData.emaHandle);
}
void ProcessRSIMidPointHijack(string symbol)
{
// Skip if not initialized (symbol not available)
if(!rmData.isInitialized)
return;
rmData.symbol = symbol; // Update symbol in case it changed
if(!IsNewBar(rmData.symbol))
return;
double rsi[], rsiReverse[], ema[], close[];
ArraySetAsSeries(rsi, true);
ArraySetAsSeries(rsiReverse, true);
ArraySetAsSeries(ema, true);
ArraySetAsSeries(close, true);
rmData.lastBarEMAPrev = rmData.lastBarEMA;
rmData.lastBarClosePrev = rmData.lastBarClose;
if(CopyBuffer(rmData.rsiHandle, 0, 0, 1, rsi) > 0)
rmData.lastBarRSI = rsi[0];
if(CopyBuffer(rmData.rsiReverseHandle, 0, 0, 1, rsiReverse) > 0)
rmData.lastBarRSIReverse = rsiReverse[0];
if(CopyBuffer(rmData.emaHandle, 0, 0, 1, ema) > 0)
rmData.lastBarEMA = ema[0];
if(CopyClose(rmData.symbol, RM_InpTimeframe, 0, 1, close) > 0)
rmData.lastBarClose = close[0];
if(RM_InpEnableRSIFollow)
CheckRSIFollowStrategy(rmData.symbol);
if(RM_InpEnableRSIReverse)
CheckRSIReverseStrategy(rmData.symbol);
if(RM_InpEnableEMACross)
CheckEMACrossStrategy(rmData.symbol);
CheckExitConditions(rmData.symbol);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,493 @@
//+------------------------------------------------------------------+
//| RSIReversalAsianStrategy.mqh |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| RSI Reversal Asian Strategy Data Structure |
//+------------------------------------------------------------------+
struct RSIReversalAsianData {
string symbol;
bool isInitialized;
int rsiHandle;
CTrade trade;
bool isPositionOpen;
double positionOpenPrice;
datetime positionOpenTime;
ENUM_POSITION_TYPE lastPositionType;
bool sessionCloseAttempted;
// RSI crossover variables
double rsiCurrent;
double rsiPrevious;
double rsiPrevious2;
bool rsiCrossedOverbought;
bool rsiCrossedOversold;
bool rsiCrossedExitLevel;
// Strategy parameters
int RSIPeriod;
double OverboughtLevel;
double OversoldLevel;
int TakeProfitPips;
int StopLossPips;
double MaxLotSize;
int MaxSpread;
int MaxDuration;
bool UseStopLoss;
bool UseTakeProfit;
bool UseRSIExit;
double RSIExitLevel;
bool CloseOutsideSession;
ENUM_TIMEFRAMES TimeFrame;
int MagicNumber;
int Slippage;
double point;
};
// Session times (UTC)
const int AsianSessionStart = 0; // 00:00 UTC
const int AsianSessionEnd = 8; // 08:00 UTC
//+------------------------------------------------------------------+
//| Check if current time is in Asian session |
//+------------------------------------------------------------------+
bool IsAsianSession()
{
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
return (timeStruct.hour >= AsianSessionStart && timeStruct.hour < AsianSessionEnd);
}
//+------------------------------------------------------------------+
//| Check if trading is allowed for symbol |
//+------------------------------------------------------------------+
bool IsTradingAllowed(RSIReversalAsianData& data)
{
// Check if market is open
long tradeMode = SymbolInfoInteger(data.symbol, SYMBOL_TRADE_MODE);
if(tradeMode != SYMBOL_TRADE_MODE_FULL)
{
return false;
}
// Check if we have enough money
if(AccountInfoDouble(ACCOUNT_MARGIN_FREE) <= 0)
{
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Check RSI crossover conditions |
//+------------------------------------------------------------------+
void CheckRSICrossover(RSIReversalAsianData& data)
{
// Reset crossover flags
data.rsiCrossedOverbought = false;
data.rsiCrossedOversold = false;
data.rsiCrossedExitLevel = false;
// Check for overbought crossover (RSI crosses above overbought level)
if(data.rsiPrevious < data.OverboughtLevel && data.rsiCurrent >= data.OverboughtLevel)
{
data.rsiCrossedOverbought = true;
}
// Check for oversold crossover (RSI crosses below oversold level)
if(data.rsiPrevious > data.OversoldLevel && data.rsiCurrent <= data.OversoldLevel)
{
data.rsiCrossedOversold = true;
}
// Check for exit level crossover
if(data.rsiPrevious < data.RSIExitLevel && data.rsiCurrent >= data.RSIExitLevel)
{
data.rsiCrossedExitLevel = true;
}
else if(data.rsiPrevious > data.RSIExitLevel && data.rsiCurrent <= data.RSIExitLevel)
{
data.rsiCrossedExitLevel = true;
}
}
//+------------------------------------------------------------------+
//| Close all trades for the symbol |
//+------------------------------------------------------------------+
bool CloseAllTrades(RSIReversalAsianData& data, string reason = "")
{
bool allClosed = true;
int totalPositions = PositionsTotal();
if(totalPositions == 0)
return true;
for(int i = totalPositions - 1; i >= 0; i--)
{
if(PositionGetSymbol(i) == data.symbol)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0 && PositionSelectByTicket(ticket))
{
if(PositionGetInteger(POSITION_MAGIC) == (ulong)data.MagicNumber)
{
// Try to close position with retry logic
int retryCount = 0;
bool positionClosed = false;
while(retryCount < 3 && !positionClosed)
{
if(data.trade.PositionClose(ticket))
{
data.isPositionOpen = false;
positionClosed = true;
}
else
{
int error = GetLastError();
// If error is 4756 (Trade disabled), wait longer before retry
if(error == 4756)
{
Sleep(5000); // Wait 5 seconds before retry
retryCount++;
}
else
{
// For other errors, break the loop
break;
}
}
}
if(!positionClosed)
{
allClosed = false;
}
}
}
}
}
return allClosed;
}
//+------------------------------------------------------------------+
//| Initialize RSI Reversal Asian Strategy |
//+------------------------------------------------------------------+
bool InitRSIReversalAsian(RSIReversalAsianData& data, string symbol,
int RSIPeriod, double OverboughtLevel, double OversoldLevel,
int TakeProfitPips, int StopLossPips, double MaxLotSize,
int MaxSpread, int MaxDuration, bool UseStopLoss,
bool UseTakeProfit, bool UseRSIExit, double RSIExitLevel,
bool CloseOutsideSession, ENUM_TIMEFRAMES TimeFrame,
int MagicNumber, int Slippage)
{
data.symbol = symbol;
data.isInitialized = false;
// Check if symbol exists
if(!SymbolSelect(symbol, true))
{
Print("RSIReversalAsian: Symbol '", symbol, "' not available in Market Watch. Please add it to Market Watch or check symbol name.");
return false;
}
// Wait a bit for symbol to be ready
Sleep(100);
// Get symbol point
data.point = SymbolInfoDouble(symbol, SYMBOL_POINT);
// Store parameters
data.RSIPeriod = RSIPeriod;
data.OverboughtLevel = OverboughtLevel;
data.OversoldLevel = OversoldLevel;
data.TakeProfitPips = TakeProfitPips;
data.StopLossPips = StopLossPips;
data.MaxLotSize = MaxLotSize;
data.MaxSpread = MaxSpread;
data.MaxDuration = MaxDuration;
data.UseStopLoss = UseStopLoss;
data.UseTakeProfit = UseTakeProfit;
data.UseRSIExit = UseRSIExit;
data.RSIExitLevel = RSIExitLevel;
data.CloseOutsideSession = CloseOutsideSession;
data.TimeFrame = TimeFrame;
data.MagicNumber = MagicNumber;
data.Slippage = Slippage;
// Initialize RSI indicator with retry logic (for insufficient history in backtesting)
data.rsiHandle = INVALID_HANDLE;
int retryCount = 0;
int maxRetries = 5;
while(retryCount < maxRetries && data.rsiHandle == INVALID_HANDLE)
{
data.rsiHandle = iRSI(symbol, TimeFrame, RSIPeriod, PRICE_CLOSE);
if(data.rsiHandle == INVALID_HANDLE)
{
int error = GetLastError();
// Error 4805 = insufficient history - wait longer and retry
if(error == 4805 && retryCount < maxRetries - 1)
{
Sleep(1000); // Wait 1 second for history to load
retryCount++;
continue;
}
Print("RSIReversalAsian: Error creating RSI indicator for '", symbol, "' - Error: ", error, " (", error == 4805 ? "Insufficient history data" : "Unknown", ")");
return false;
}
}
if(data.rsiHandle == INVALID_HANDLE)
{
Print("RSIReversalAsian: Failed to create RSI indicator for '", symbol, "' after ", maxRetries, " retries");
return false;
}
// Wait a bit for the indicator to be ready
Sleep(100);
// Initialize RSI values with retry logic
double rsi[];
ArraySetAsSeries(rsi, true);
retryCount = 0;
bool rsiInitialized = false;
while(retryCount < 10 && !rsiInitialized)
{
int copied = CopyBuffer(data.rsiHandle, 0, 0, 3, rsi);
if(copied >= 3)
{
data.rsiCurrent = rsi[0];
data.rsiPrevious = rsi[1];
data.rsiPrevious2 = rsi[2];
rsiInitialized = true;
}
else
{
retryCount++;
Sleep(100);
}
}
if(!rsiInitialized)
{
// Don't fail initialization, just set default values
data.rsiCurrent = 50.0;
data.rsiPrevious = 50.0;
data.rsiPrevious2 = 50.0;
}
// Set trade parameters
data.trade.SetExpertMagicNumber(MagicNumber);
data.trade.SetDeviationInPoints(Slippage);
data.trade.SetTypeFilling(ORDER_FILLING_IOC);
// Initialize state
data.isPositionOpen = false;
data.positionOpenPrice = 0;
data.positionOpenTime = 0;
data.lastPositionType = POSITION_TYPE_BUY;
data.sessionCloseAttempted = false;
data.rsiCrossedOverbought = false;
data.rsiCrossedOversold = false;
data.rsiCrossedExitLevel = false;
data.isInitialized = true;
Print("RSIReversalAsian: Successfully initialized for symbol '", symbol, "'");
return true;
}
//+------------------------------------------------------------------+
//| Deinitialize RSI Reversal Asian Strategy |
//+------------------------------------------------------------------+
void DeinitRSIReversalAsian(RSIReversalAsianData& data)
{
if(data.rsiHandle != INVALID_HANDLE)
IndicatorRelease(data.rsiHandle);
}
//+------------------------------------------------------------------+
//| Process RSI Reversal Asian Strategy |
//+------------------------------------------------------------------+
void ProcessRSIReversalAsian(RSIReversalAsianData& data, double lotSize)
{
if(!data.isInitialized)
return;
// Check if trading is allowed
if(!IsTradingAllowed(data))
{
return;
}
// Check if we're in Asian session
if(!IsAsianSession())
{
// Close all positions if outside Asian session and CloseOutsideSession is true
if(data.CloseOutsideSession && !data.sessionCloseAttempted)
{
CloseAllTrades(data, "Outside Asian session");
data.sessionCloseAttempted = true;
}
return;
}
else
{
// Reset the session close attempt flag when we enter Asian session
data.sessionCloseAttempted = false;
}
// Get current spread
double spread = SymbolInfoDouble(data.symbol, SYMBOL_ASK) - SymbolInfoDouble(data.symbol, SYMBOL_BID);
int spreadInPips = (int)(spread / data.point);
// Check if spread is too high
if(spreadInPips > data.MaxSpread)
{
return;
}
// Get RSI values from bar data
double rsi[];
ArraySetAsSeries(rsi, true);
int copied = CopyBuffer(data.rsiHandle, 0, 0, 3, rsi);
if(copied < 3)
{
return;
}
// Update RSI values
data.rsiPrevious2 = data.rsiPrevious;
data.rsiPrevious = data.rsiCurrent;
data.rsiCurrent = rsi[0];
// Validate RSI values
if(data.rsiCurrent == 0 || data.rsiPrevious == 0)
{
return;
}
// Check for RSI crossovers
CheckRSICrossover(data);
// Get current prices
double currentBid = SymbolInfoDouble(data.symbol, SYMBOL_BID);
double currentAsk = SymbolInfoDouble(data.symbol, SYMBOL_ASK);
// Check for open position
bool hasOpenPosition = PositionExistsByMagic(data.symbol, (ulong)data.MagicNumber);
if(hasOpenPosition)
{
// Get position details
ulong ticket = GetPositionTicketByMagic(data.symbol, (ulong)data.MagicNumber);
if(ticket > 0 && PositionSelectByTicket(ticket))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openTime = (datetime)PositionGetInteger(POSITION_TIME);
// Check for RSI exit if enabled
if(data.UseRSIExit && data.rsiCrossedExitLevel)
{
bool shouldExit = false;
// For long positions, exit when RSI crosses above exit level
if(posType == POSITION_TYPE_BUY && data.rsiCurrent >= data.RSIExitLevel && data.rsiPrevious < data.RSIExitLevel)
{
shouldExit = true;
}
// For short positions, exit when RSI crosses below exit level
else if(posType == POSITION_TYPE_SELL && data.rsiCurrent <= data.RSIExitLevel && data.rsiPrevious > data.RSIExitLevel)
{
shouldExit = true;
}
if(shouldExit)
{
CloseAllTrades(data, "RSI Exit Crossover");
return;
}
}
// Check for timeout
if(TimeCurrent() - openTime > data.MaxDuration * 3600)
{
CloseAllTrades(data, "Timeout");
return;
}
}
}
// If no position is open, look for entry signals based on RSI crossover
if(!hasOpenPosition)
{
// Place buy order if RSI crosses below oversold level (oversold crossover)
if(data.rsiCrossedOversold)
{
double sl = data.UseStopLoss ? currentBid - data.StopLossPips * data.point : 0;
double tp = data.UseTakeProfit ? currentBid + data.TakeProfitPips * data.point : 0;
if(data.UseStopLoss && sl >= currentBid)
return;
if(data.UseTakeProfit && tp <= currentBid)
return;
// Set trade parameters
data.trade.SetDeviationInPoints(data.Slippage);
data.trade.SetTypeFilling(ORDER_FILLING_IOC);
data.trade.SetExpertMagicNumber(data.MagicNumber);
// Use dynamic lot size
double tradeLotSize = lotSize > 0 ? lotSize : data.MaxLotSize;
// Place buy order using CTrade
if(data.trade.Buy(tradeLotSize, data.symbol, currentAsk, sl, tp, "RSI Oversold Crossover Buy"))
{
data.isPositionOpen = true;
data.positionOpenPrice = currentAsk;
data.positionOpenTime = TimeCurrent();
data.lastPositionType = POSITION_TYPE_BUY;
}
}
// Place sell order if RSI crosses above overbought level (overbought crossover)
else if(data.rsiCrossedOverbought)
{
double sl = data.UseStopLoss ? currentAsk + data.StopLossPips * data.point : 0;
double tp = data.UseTakeProfit ? currentAsk - data.TakeProfitPips * data.point : 0;
if(data.UseStopLoss && sl <= currentAsk)
return;
if(data.UseTakeProfit && tp >= currentAsk)
return;
// Set trade parameters
data.trade.SetDeviationInPoints(data.Slippage);
data.trade.SetTypeFilling(ORDER_FILLING_IOC);
data.trade.SetExpertMagicNumber(data.MagicNumber);
// Use dynamic lot size
double tradeLotSize = lotSize > 0 ? lotSize : data.MaxLotSize;
// Place sell order using CTrade
if(data.trade.Sell(tradeLotSize, data.symbol, currentBid, sl, tp, "RSI Overbought Crossover Sell"))
{
data.isPositionOpen = true;
data.positionOpenPrice = currentBid;
data.positionOpenTime = TimeCurrent();
data.lastPositionType = POSITION_TYPE_SELL;
}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,683 @@
//+------------------------------------------------------------------+
//| UnitedEA.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"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Indicators\Trend.mqh>
#include <Indicators\Volumes.mqh>
#include "MagicNumberHelpers.mqh"
#include "PerformanceEvaluator.mqh"
//+------------------------------------------------------------------+
//| Strategy Enable/Disable Switches |
//+------------------------------------------------------------------+
input group "=== Strategy Enable/Disable ==="
input bool EnableDarvasBox = true;
input bool EnableEMASlopeDistance = true;
input bool EnableRSICrossOverReversal = true;
input bool EnableRSIMidPointHijack = true;
input bool EnableRSIScalpingAPPL = true;
input bool EnableRSIScalpingBTCUSD = true;
input bool EnableRSIScalpingMSFT = true;
input bool EnableRSIScalpingNVDA = true;
input bool EnableRSIScalpingTSLA = true;
input bool EnableRSIScalpingXAUUSD = true;
//+------------------------------------------------------------------+
//| Strategy 1: DarvasBoxXAUUSD |
//+------------------------------------------------------------------+
input group "=== DarvasBox Strategy ==="
input string DB_Symbol = "XAUUSD";
input int DB_BoxPeriod = 165;
input double DB_BoxDeviation = 30000; // Increased to allow larger ranges (was 25140)
input int DB_VolumeThreshold = 0; // Set to 0 to disable volume threshold check. Volume data from indicator used instead.
input double DB_StopLoss = 1665;
input double DB_TakeProfit = 3685;
input bool DB_EnableLogging = false;
input color DB_BoxColor = clrBlue;
input int DB_BoxWidth = 1;
input ENUM_TIMEFRAMES DB_TrendTimeframe = PERIOD_H2;
input int DB_MA_Period = 125;
input ENUM_MA_METHOD DB_MA_Method = MODE_EMA;
input ENUM_APPLIED_PRICE DB_MA_Price = PRICE_WEIGHTED;
input double DB_TrendThreshold = 4.94;
input int DB_VolumeMA_Period = 110;
input double DB_VolumeThresholdMultiplier = 1.5;
input int DB_MagicNumber = 135790;
//+------------------------------------------------------------------+
//| Strategy 2: EMASlopeDistanceCocktailXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== EMA Slope Distance Strategy ==="
input string ES_Symbol = "XAUUSD";
input int ES_EMA_Periode = 46;
input double ES_PreisSchwelle = 600.0;
input double ES_SteigungSchwelle = 80.0;
input int ES_ÜberwachungTimeout = 800;
input double ES_TrailingStop = 250.0;
input double ES_LotGröße = 0.03;
input int ES_MagicNumber = 12350;
input bool ES_UseSpreadAdjustment = true;
input ENUM_TIMEFRAMES ES_Timeframe = PERIOD_H1;
input bool ES_UseBarData = true;
input int ES_MaxTradesPerCrossover = 9;
input int ES_ProfitCheckBars = 18;
input bool ES_CloseUnprofitableTrades = true;
//+------------------------------------------------------------------+
//| Strategy 3: RSICrossOverReversalXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI CrossOver Reversal Strategy ==="
input string RC_Symbol = "XAUUSD";
input int RC_MagicNumber = 7;
input int RC_rsiPeriod = 19;
input int RC_overboughtLevel = 93;
input int RC_oversoldLevel = 22;
input double RC_entryRSIBuySpread = 0;
input double RC_entryRSISellSpread = 0;
input double RC_lotSize = 0.01;
input int RC_slippage = 3;
input int RC_cooldownSeconds = 209;
input ENUM_TIMEFRAMES RC_TimeFrame1 = PERIOD_M1;
input ENUM_TIMEFRAMES RC_TimeFrame2 = PERIOD_M1;
input ENUM_TIMEFRAMES RC_BarTimeFrame = PERIOD_M12;
input int RC_emaPeriod = 140;
input double RC_emaSlopeThreshold = 105;
input double RC_exitBuyRSI = 86;
input double RC_exitSellRSI = 10;
input double RC_TrailingStop = 295;
input double RC_emaDistanceThreshold = 165;
input int RC_tradingHourOneBegin = 24;
input int RC_tradingHourOneEnd = 22;
input int RC_tradingHourTwoBegin = 6;
input int RC_tradingHourTwoEnd = 19;
input bool RC_Sunday = false;
input bool RC_Monday = false;
input bool RC_Tuesday = true;
input bool RC_Wednesday = true;
input bool RC_Thursday = true;
input bool RC_Friday = false;
input bool RC_Saturday = false;
//+------------------------------------------------------------------+
//| Strategy 4: RSIMidPointHijackXAUUSD |
//| PEPPERSTONE US: Gold symbol is typically "XAUUSD" or "GOLD" |
//+------------------------------------------------------------------+
input group "=== RSI MidPoint Hijack Strategy ==="
input string RM_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RM_InpTimeframe = PERIOD_H1;
input double RM_InpLotSize = 0.02;
input int RM_InpMagicNumberRSIFollow = 1001;
input int RM_InpMagicNumberRSIReverse = 1002;
input int RM_InpMagicNumberEMACross = 1003;
input bool RM_InpEnableRSIFollow = true;
input bool RM_InpEnableRSIReverse = true;
input bool RM_InpEnableEMACross = true;
input bool RM_InpEnableStrategyLock = false;
input double RM_InpLockProfitThreshold = 0.0;
input bool RM_InpCloseOppositeTrades = false;
input int RM_InpRSIPeriod = 32;
input int RM_InpRSIOverbought = 78;
input int RM_InpRSIOversold = 46;
input int RM_InpRSIExitLevel = 44;
input int RM_InpRSIFollowStartHour = 23;
input int RM_InpRSIFollowEndHour = 8;
input bool RM_InpRSIFollowCloseOutsideHours = false;
input int RM_InpRSIReversePeriod = 59;
input int RM_InpRSIReverseOverbought = 51;
input int RM_InpRSIReverseOversold = 49;
input int RM_InpRSIReverseCrossLevel = 53;
input int RM_InpRSIReverseExitLevel = 48;
input int RM_InpRSIReverseStartHour = 7;
input int RM_InpRSIReverseEndHour = 13;
input bool RM_InpRSIReverseCloseOutsideHours = false;
input int RM_InpRSIReverseCooldownBars = 15;
input bool RM_InpRSIReverseCooldownOnLoss = true;
input int RM_InpEMAPeriod = 120;
input int RM_InpEMACrossStartHour = 8;
input int RM_InpEMACrossEndHour = 14;
input bool RM_InpEMACrossCloseOutsideHours = true;
input bool RM_InpUseEMADistanceEntry = true;
input double RM_InpEMADistancePips = 160.0;
input int RM_InpEMADistancePeriod = 26;
//+------------------------------------------------------------------+
//| Strategy 5-10: RSI Scalping Strategies |
//| Each RSI Scalping strategy trades on its own symbol: |
//| - APPL: Apple stock (AAPL) |
//| - BTCUSD: Bitcoin/USD |
//| - MSFT: Microsoft stock |
//| - NVDA: NVIDIA stock |
//| - TSLA: Tesla stock |
//| - XAUUSD: Gold/USD |
//| |
//| PEPPERSTONE US SYMBOL FORMATS: |
//| - Stocks may use: "AAPL.US", "NASDAQ:AAPL", or just "AAPL" |
//| - To find correct symbols: |
//| 1. Open Market Watch (Ctrl+M) |
//| 2. Right-click > Show All |
//| 3. Search for the stock name |
//| 4. Use the exact symbol name shown |
//+------------------------------------------------------------------+
input group "=== RSI Scalping APPL (AAPL) - Pepperstone US ==="
input string RS_APPL_Symbol = "AAPL.US"; // Try: "AAPL.US", "NASDAQ:AAPL", or "AAPL"
input ENUM_TIMEFRAMES RS_APPL_TimeFrame = PERIOD_M10;
input int RS_APPL_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_APPL_RSI_Applied_Price = PRICE_CLOSE;
input double RS_APPL_RSI_Overbought = 80;
input double RS_APPL_RSI_Oversold = 78;
input double RS_APPL_RSI_Target_Buy = 94;
input double RS_APPL_RSI_Target_Sell = 44;
input int RS_APPL_BarsToWait = 7;
input double RS_APPL_LotSize = 25;
input int RS_APPL_MagicNumber = 20001;
input int RS_APPL_Slippage = 3;
input group "=== RSI Scalping BTCUSD ==="
input string RS_BTCUSD_Symbol = "BTCUSD"; // Pepperstone may use: "BTCUSD", "BTC/USD", or "BTCUSD.c"
input ENUM_TIMEFRAMES RS_BTCUSD_TimeFrame = PERIOD_H1;
input int RS_BTCUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_BTCUSD_RSI_Applied_Price = PRICE_CLOSE;
input double RS_BTCUSD_RSI_Overbought = 90;
input double RS_BTCUSD_RSI_Oversold = 73;
input double RS_BTCUSD_RSI_Target_Buy = 88;
input double RS_BTCUSD_RSI_Target_Sell = 48;
input int RS_BTCUSD_BarsToWait = 6;
input double RS_BTCUSD_LotSize = 0.1;
input int RS_BTCUSD_MagicNumber = 123459123;
input int RS_BTCUSD_Slippage = 3;
input group "=== RSI Scalping MSFT - Pepperstone US ==="
input string RS_MSFT_Symbol = "MSFT.US"; // Try: "MSFT.US", "NASDAQ:MSFT", or "MSFT"
input ENUM_TIMEFRAMES RS_MSFT_TimeFrame = PERIOD_H3;
input int RS_MSFT_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_MSFT_RSI_Applied_Price = PRICE_CLOSE;
input double RS_MSFT_RSI_Overbought = 19;
input double RS_MSFT_RSI_Oversold = 50;
input double RS_MSFT_RSI_Target_Buy = 71;
input double RS_MSFT_RSI_Target_Sell = 70;
input int RS_MSFT_BarsToWait = 1;
input double RS_MSFT_LotSize = 50;
input int RS_MSFT_MagicNumber = 20002;
input int RS_MSFT_Slippage = 3;
input group "=== RSI Scalping NVDA - Pepperstone US ==="
input string RS_NVDA_Symbol = "NVDA.US"; // Try: "NVDA.US", "NASDAQ:NVDA", or "NVDA"
input ENUM_TIMEFRAMES RS_NVDA_TimeFrame = PERIOD_M15;
input int RS_NVDA_RSI_Period = 8;
input ENUM_APPLIED_PRICE RS_NVDA_RSI_Applied_Price = PRICE_CLOSE;
input double RS_NVDA_RSI_Overbought = 36;
input double RS_NVDA_RSI_Oversold = 38;
input double RS_NVDA_RSI_Target_Buy = 90;
input double RS_NVDA_RSI_Target_Sell = 70;
input int RS_NVDA_BarsToWait = 5;
input double RS_NVDA_LotSize = 50;
input int RS_NVDA_MagicNumber = 20003;
input int RS_NVDA_Slippage = 3;
input group "=== RSI Scalping TSLA - Pepperstone US ==="
input string RS_TSLA_Symbol = "TSLA.US"; // Try: "TSLA.US", "NASDAQ:TSLA", or "TSLA"
input ENUM_TIMEFRAMES RS_TSLA_TimeFrame = PERIOD_H1;
input int RS_TSLA_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_TSLA_RSI_Applied_Price = PRICE_CLOSE;
input double RS_TSLA_RSI_Overbought = 54;
input double RS_TSLA_RSI_Oversold = 73;
input double RS_TSLA_RSI_Target_Buy = 87;
input double RS_TSLA_RSI_Target_Sell = 33;
input int RS_TSLA_BarsToWait = 1;
input double RS_TSLA_LotSize = 50;
input int RS_TSLA_MagicNumber = 125421321;
input int RS_TSLA_Slippage = 3;
input group "=== RSI Scalping XAUUSD ==="
input string RS_XAUUSD_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES RS_XAUUSD_TimeFrame = PERIOD_H1;
input int RS_XAUUSD_RSI_Period = 14;
input ENUM_APPLIED_PRICE RS_XAUUSD_RSI_Applied_Price = PRICE_CLOSE;
input double RS_XAUUSD_RSI_Overbought = 71;
input double RS_XAUUSD_RSI_Oversold = 57;
input double RS_XAUUSD_RSI_Target_Buy = 80;
input double RS_XAUUSD_RSI_Target_Sell = 57;
input int RS_XAUUSD_BarsToWait = 4;
input double RS_XAUUSD_LotSize = 0.1;
input int RS_XAUUSD_MagicNumber = 129102315;
input int RS_XAUUSD_Slippage = 3;
//+------------------------------------------------------------------+
//| Global Variables - DarvasBox |
//+------------------------------------------------------------------+
struct DarvasBoxData {
string symbol;
bool isInitialized;
double boxHigh;
double boxLow;
bool boxFormed;
datetime lastBoxTime;
string boxName;
double minStopLevel;
double point;
CTrade trade;
int maHandle;
int volumeHandle;
datetime lastBarTime;
};
//+------------------------------------------------------------------+
//| Global Variables - EMA Slope Distance |
//+------------------------------------------------------------------+
struct EMASlopeData {
string symbol;
bool isInitialized;
int ema_handle;
double ema_array[];
datetime letzte_überwachung_zeit;
bool überwachung_aktiv;
bool preis_trigger_aktiv;
bool steigung_trigger_aktiv;
int ticket;
CTrade trade;
int trades_in_current_crossover;
bool crossover_detected;
datetime trade_open_time;
datetime last_bar_time;
};
//+------------------------------------------------------------------+
//| Global Variables - RSI CrossOver Reversal |
//+------------------------------------------------------------------+
struct RSICrossOverData {
string symbol;
bool isInitialized;
int rsiHandle;
int emaHandle;
double previousRSIDef;
CTrade trade;
datetime lastTradeTime;
datetime bartime;
bool WeekDays[7];
datetime lastBarTime;
};
//+------------------------------------------------------------------+
//| Global Variables - RSI MidPoint Hijack |
//+------------------------------------------------------------------+
struct RSIMidPointData {
string symbol;
bool isInitialized;
int rsiHandle;
int rsiReverseHandle;
int emaHandle;
bool rsiOverbought;
bool rsiOversold;
bool rsiReverseOverbought;
bool rsiReverseOversold;
CTrade trade;
CPositionInfo positionInfo;
bool emaCrossBuySignal;
bool emaCrossSellSignal;
int emaCrossSignalBar;
datetime lastBarTime;
datetime rsiReverseLastCloseTime;
bool rsiReverseInCooldown;
double lastBarRSI;
double lastBarRSIReverse;
double lastBarEMA;
double lastBarClose;
double lastBarEMAPrev;
double lastBarClosePrev;
};
//+------------------------------------------------------------------+
//| Global Variables - RSI Scalping |
//+------------------------------------------------------------------+
struct RSIScalpingData {
string symbol;
bool isInitialized;
CTrade trade;
int rsi_handle;
double rsi_buffer[];
double rsi_prev;
double rsi_current;
double rsi_two_bars_ago;
bool position_open;
ulong position_ticket;
ENUM_POSITION_TYPE current_position_type;
datetime last_bar_time;
bool rsi_against_position;
int bars_against_count;
};
//+------------------------------------------------------------------+
//| Global Strategy Instances |
//+------------------------------------------------------------------+
DarvasBoxData dbData;
EMASlopeData esData;
RSICrossOverData rcData;
RSIMidPointData rmData;
RSIScalpingData rsAPPLData;
RSIScalpingData rsBTCUSDData;
RSIScalpingData rsMSFTData;
RSIScalpingData rsNVDAData;
RSIScalpingData rsTSLAData;
RSIScalpingData rsXAUUSDData;
//+------------------------------------------------------------------+
//| Global Variables for Dynamic Lot Sizes |
//+------------------------------------------------------------------+
// All strategies start with minimum lot size for safety (will be adjusted by performance evaluator)
double g_DB_LotSize = 0.01; // DarvasBox uses fixed lot size
double g_ES_LotSize = 0.01; // EMA Slope Distance - start with minimum
double g_RC_LotSize = 0.01; // RSI CrossOver Reversal - start with minimum
double g_RM_LotSize = 0.01; // RSI MidPoint Hijack - start with minimum
double g_RS_APPL_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_BTCUSD_LotSize = 0.01; // Crypto - start with forex minimum (0.01)
double g_RS_MSFT_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_NVDA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_TSLA_LotSize = 5.0; // Stock - start with stock minimum (5.0)
double g_RS_XAUUSD_LotSize = 0.01; // Forex - start with forex minimum (0.01)
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
int initResult = INIT_SUCCEEDED;
// Initialize Performance Evaluator
InitPerformanceTracking();
// Initialize strategies - log warnings but don't fail entire EA if symbol unavailable
if(EnableDarvasBox)
{
if(!InitDarvasBox(DB_Symbol))
Print("Warning: DarvasBox strategy failed to initialize for symbol '", DB_Symbol, "'");
else
RegisterStrategy("DarvasBox", DB_MagicNumber, 0.01, DB_Symbol); // Fixed lot size
}
if(EnableEMASlopeDistance)
{
if(!InitEMASlopeDistance(ES_Symbol))
Print("Warning: EMASlopeDistance strategy failed to initialize for symbol '", ES_Symbol, "'");
else
{
RegisterStrategy("EMASlopeDistance", ES_MagicNumber, ES_LotGröße, ES_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(ES_Symbol);
g_ES_LotSize = minLot;
}
}
if(EnableRSICrossOverReversal)
{
if(!InitRSICrossOverReversal(RC_Symbol))
Print("Warning: RSICrossOverReversal strategy failed to initialize for symbol '", RC_Symbol, "'");
else
{
RegisterStrategy("RSICrossOverReversal", RC_MagicNumber, RC_lotSize, RC_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RC_Symbol);
g_RC_LotSize = minLot;
}
}
if(EnableRSIMidPointHijack)
{
if(!InitRSIMidPointHijack(RM_Symbol))
Print("Warning: RSIMidPointHijack strategy failed to initialize for symbol '", RM_Symbol, "'");
else
{
RegisterStrategy("RSIMidPointHijack", RM_InpMagicNumberRSIFollow, RM_InpLotSize, RM_Symbol);
RegisterStrategy("RSIMidPointHijack_Reverse", RM_InpMagicNumberRSIReverse, RM_InpLotSize, RM_Symbol);
RegisterStrategy("RSIMidPointHijack_EMACross", RM_InpMagicNumberEMACross, RM_InpLotSize, RM_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RM_Symbol);
g_RM_LotSize = minLot;
}
}
// Initialize RSI Scalping strategies - don't fail entire EA if symbol unavailable
if(EnableRSIScalpingAPPL)
{
InitRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price, RS_APPL_MagicNumber, RS_APPL_Slippage);
RegisterStrategy("RSIScalpingAPPL", RS_APPL_MagicNumber, RS_APPL_LotSize, RS_APPL_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_APPL_Symbol);
g_RS_APPL_LotSize = minLot;
}
if(EnableRSIScalpingBTCUSD)
{
InitRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price, RS_BTCUSD_MagicNumber, RS_BTCUSD_Slippage);
RegisterStrategy("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber, RS_BTCUSD_LotSize, RS_BTCUSD_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_BTCUSD_Symbol);
g_RS_BTCUSD_LotSize = minLot;
}
if(EnableRSIScalpingMSFT)
{
InitRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price, RS_MSFT_MagicNumber, RS_MSFT_Slippage);
RegisterStrategy("RSIScalpingMSFT", RS_MSFT_MagicNumber, RS_MSFT_LotSize, RS_MSFT_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_MSFT_Symbol);
g_RS_MSFT_LotSize = minLot;
}
if(EnableRSIScalpingNVDA)
{
InitRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price, RS_NVDA_MagicNumber, RS_NVDA_Slippage);
RegisterStrategy("RSIScalpingNVDA", RS_NVDA_MagicNumber, RS_NVDA_LotSize, RS_NVDA_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_NVDA_Symbol);
g_RS_NVDA_LotSize = minLot;
}
if(EnableRSIScalpingTSLA)
{
InitRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price, RS_TSLA_MagicNumber, RS_TSLA_Slippage);
RegisterStrategy("RSIScalpingTSLA", RS_TSLA_MagicNumber, RS_TSLA_LotSize, RS_TSLA_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_TSLA_Symbol);
g_RS_TSLA_LotSize = minLot;
}
if(EnableRSIScalpingXAUUSD)
{
InitRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price, RS_XAUUSD_MagicNumber, RS_XAUUSD_Slippage);
RegisterStrategy("RSIScalpingXAUUSD", RS_XAUUSD_MagicNumber, RS_XAUUSD_LotSize, RS_XAUUSD_Symbol);
// Start with minimum lot size (will be adjusted by performance evaluator)
double minLot = GetMinLotSizeForSymbol(RS_XAUUSD_Symbol);
g_RS_XAUUSD_LotSize = minLot;
}
// Load adjusted lot sizes from performance evaluator
if(PE_EnableAutoAdjustment)
{
double adjustedLot;
adjustedLot = GetStrategyLotSize("EMASlopeDistance", ES_MagicNumber);
if(adjustedLot > 0) g_ES_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSICrossOverReversal", RC_MagicNumber);
if(adjustedLot > 0) g_RC_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIMidPointHijack", RM_InpMagicNumberRSIFollow);
if(adjustedLot > 0) g_RM_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingAPPL", RS_APPL_MagicNumber);
if(adjustedLot > 0) g_RS_APPL_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingTSLA", RS_TSLA_MagicNumber);
if(adjustedLot > 0) g_RS_TSLA_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingXAUUSD", RS_XAUUSD_MagicNumber);
if(adjustedLot > 0) g_RS_XAUUSD_LotSize = adjustedLot;
}
Print("United EA initialized. Active strategies: ",
(EnableDarvasBox ? "DarvasBox " : ""),
(EnableEMASlopeDistance ? "EMASlope " : ""),
(EnableRSICrossOverReversal ? "RSICrossOver " : ""),
(EnableRSIMidPointHijack ? "RSIMidPoint " : ""),
(EnableRSIScalpingAPPL ? "RSIScalpingAPPL " : ""),
(EnableRSIScalpingBTCUSD ? "RSIScalpingBTCUSD " : ""),
(EnableRSIScalpingMSFT ? "RSIScalpingMSFT " : ""),
(EnableRSIScalpingNVDA ? "RSIScalpingNVDA " : ""),
(EnableRSIScalpingTSLA ? "RSIScalpingTSLA " : ""),
(EnableRSIScalpingXAUUSD ? "RSIScalpingXAUUSD " : ""));
if(PE_EnableLogging)
Print(GetPerformanceSummary());
return initResult;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(EnableDarvasBox)
DeinitDarvasBox();
if(EnableEMASlopeDistance)
DeinitEMASlopeDistance();
if(EnableRSICrossOverReversal)
DeinitRSICrossOverReversal();
if(EnableRSIMidPointHijack)
DeinitRSIMidPointHijack();
if(EnableRSIScalpingAPPL)
DeinitRSIScalping(rsAPPLData);
if(EnableRSIScalpingBTCUSD)
DeinitRSIScalping(rsBTCUSDData);
if(EnableRSIScalpingMSFT)
DeinitRSIScalping(rsMSFTData);
if(EnableRSIScalpingNVDA)
DeinitRSIScalping(rsNVDAData);
if(EnableRSIScalpingTSLA)
DeinitRSIScalping(rsTSLAData);
if(EnableRSIScalpingXAUUSD)
DeinitRSIScalping(rsXAUUSDData);
Print("United EA deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Process performance evaluation (checks for quarter end and adjusts lot sizes)
ProcessPerformanceEvaluation();
// Update lot sizes from performance evaluator if auto-adjustment is enabled
if(PE_EnableAutoAdjustment)
{
double adjustedLot;
adjustedLot = GetStrategyLotSize("EMASlopeDistance", ES_MagicNumber);
if(adjustedLot > 0) g_ES_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSICrossOverReversal", RC_MagicNumber);
if(adjustedLot > 0) g_RC_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIMidPointHijack", RM_InpMagicNumberRSIFollow);
if(adjustedLot > 0) g_RM_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingAPPL", RS_APPL_MagicNumber);
if(adjustedLot > 0) g_RS_APPL_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingBTCUSD", RS_BTCUSD_MagicNumber);
if(adjustedLot > 0) g_RS_BTCUSD_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingMSFT", RS_MSFT_MagicNumber);
if(adjustedLot > 0) g_RS_MSFT_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingNVDA", RS_NVDA_MagicNumber);
if(adjustedLot > 0) g_RS_NVDA_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingTSLA", RS_TSLA_MagicNumber);
if(adjustedLot > 0) g_RS_TSLA_LotSize = adjustedLot;
adjustedLot = GetStrategyLotSize("RSIScalpingXAUUSD", RS_XAUUSD_MagicNumber);
if(adjustedLot > 0) g_RS_XAUUSD_LotSize = adjustedLot;
}
if(EnableDarvasBox)
ProcessDarvasBox(DB_Symbol);
if(EnableEMASlopeDistance)
ProcessEMASlopeDistance(ES_Symbol);
if(EnableRSICrossOverReversal)
ProcessRSICrossOverReversal(RC_Symbol);
if(EnableRSIMidPointHijack)
ProcessRSIMidPointHijack(RM_Symbol);
if(EnableRSIScalpingAPPL)
ProcessRSIScalping(rsAPPLData, RS_APPL_Symbol, RS_APPL_TimeFrame, RS_APPL_RSI_Period, RS_APPL_RSI_Applied_Price,
RS_APPL_RSI_Overbought, RS_APPL_RSI_Oversold, RS_APPL_RSI_Target_Buy, RS_APPL_RSI_Target_Sell,
RS_APPL_BarsToWait, g_RS_APPL_LotSize, RS_APPL_MagicNumber);
if(EnableRSIScalpingBTCUSD)
ProcessRSIScalping(rsBTCUSDData, RS_BTCUSD_Symbol, RS_BTCUSD_TimeFrame, RS_BTCUSD_RSI_Period, RS_BTCUSD_RSI_Applied_Price,
RS_BTCUSD_RSI_Overbought, RS_BTCUSD_RSI_Oversold, RS_BTCUSD_RSI_Target_Buy, RS_BTCUSD_RSI_Target_Sell,
RS_BTCUSD_BarsToWait, g_RS_BTCUSD_LotSize, RS_BTCUSD_MagicNumber);
if(EnableRSIScalpingMSFT)
ProcessRSIScalping(rsMSFTData, RS_MSFT_Symbol, RS_MSFT_TimeFrame, RS_MSFT_RSI_Period, RS_MSFT_RSI_Applied_Price,
RS_MSFT_RSI_Overbought, RS_MSFT_RSI_Oversold, RS_MSFT_RSI_Target_Buy, RS_MSFT_RSI_Target_Sell,
RS_MSFT_BarsToWait, g_RS_MSFT_LotSize, RS_MSFT_MagicNumber);
if(EnableRSIScalpingNVDA)
ProcessRSIScalping(rsNVDAData, RS_NVDA_Symbol, RS_NVDA_TimeFrame, RS_NVDA_RSI_Period, RS_NVDA_RSI_Applied_Price,
RS_NVDA_RSI_Overbought, RS_NVDA_RSI_Oversold, RS_NVDA_RSI_Target_Buy, RS_NVDA_RSI_Target_Sell,
RS_NVDA_BarsToWait, g_RS_NVDA_LotSize, RS_NVDA_MagicNumber);
if(EnableRSIScalpingTSLA)
ProcessRSIScalping(rsTSLAData, RS_TSLA_Symbol, RS_TSLA_TimeFrame, RS_TSLA_RSI_Period, RS_TSLA_RSI_Applied_Price,
RS_TSLA_RSI_Overbought, RS_TSLA_RSI_Oversold, RS_TSLA_RSI_Target_Buy, RS_TSLA_RSI_Target_Sell,
RS_TSLA_BarsToWait, g_RS_TSLA_LotSize, RS_TSLA_MagicNumber);
if(EnableRSIScalpingXAUUSD)
ProcessRSIScalping(rsXAUUSDData, RS_XAUUSD_Symbol, RS_XAUUSD_TimeFrame, RS_XAUUSD_RSI_Period, RS_XAUUSD_RSI_Applied_Price,
RS_XAUUSD_RSI_Overbought, RS_XAUUSD_RSI_Oversold, RS_XAUUSD_RSI_Target_Buy, RS_XAUUSD_RSI_Target_Sell,
RS_XAUUSD_BarsToWait, g_RS_XAUUSD_LotSize, RS_XAUUSD_MagicNumber);
}
//+------------------------------------------------------------------+
//| Include strategy implementations |
//+------------------------------------------------------------------+
#include "Strategies/DarvasBoxStrategy.mqh"
#include "Strategies/EMASlopeDistanceStrategy.mqh"
#include "Strategies/RSICrossOverReversalStrategy.mqh"
#include "Strategies/RSIMidPointHijackStrategy.mqh"
#include "Strategies/RSIScalpingStrategy.mqh"
//+------------------------------------------------------------------+
@@ -0,0 +1,27 @@
; saved on 2026.04.22
; genetic optimization set for DarvasBoxXAUUSD/main.mq5
; load in MT5 Strategy Tester -> Inputs -> Load
;
; === Core Darvas Box Parameters ===
BoxPeriod=165||80||5||280||Y
BoxDeviation=25140||8000||500||50000||Y
VolumeThreshold=938||200||25||2500||Y
StopLoss=1665||600||50||4000||Y
TakeProfit=3685||1200||75||8000||Y
EnableLogging=false||false||0||true||N
BoxColor=255||0||1||16777215||N
BoxWidth=1||1||1||3||N
;
; === Trend Confirmation Parameters ===
TrendTimeframe=16386||16385||1||16388||Y
MA_Period=125||20||5||260||Y
MA_Method=1||0||1||3||Y
MA_Price=6||0||1||6||Y
TrendThreshold=4.94||1.0||0.2||20.0||Y
;
; === Volume Analysis Parameters ===
VolumeMA_Period=110||20||5||220||Y
VolumeThresholdMultiplier=1.5||1.0||0.1||3.5||Y
;
; === Execution / ID ===
MagicNumber=135790||135790||1||1357900||N
@@ -3,25 +3,30 @@
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property link "https://www.mql5.com"
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
#include "../_united/MagicNumberHelpers.mqh"
//--- Eingabeparameter (Input Parameters) - Optimized Profitable Parameters
input int EMA_Periode = 46; // EMA Periode
input double PreisSchwelle = 600.0; // Preisbewegung Schwelle in Pips
input double SteigungSchwelle = 80.0; // EMA Steigung Schwelle in Pips
input int ÜberwachungTimeout = 800; // Überwachungszeit in Sekunden
input double TrailingStop = 260.0; // Gleitender Stop in Pips
input double LotGröße = 0.03; // Handelsvolumen
input int MagicNumber = 12351; // Magic Number für Trades
input int EMA_Periode = 50; // EMA Periode
input double PreisSchwelle = 700.0; // Preisbewegung Schwelle in Pips
input double SteigungSchwelle = 25.0; // EMA Steigung Schwelle in Pips
input int ÜberwachungTimeout = 340; // Überwachungszeit in Sekunden
input double TrailingStop = 370.0; // Gleitender Stop in Pips
input double LotGröße = 0.07; // Handelsvolumen
input int MagicNumber = 135790; // 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 = 9; // Maximale Trades pro Crossover-Ereignis
input int ProfitCheckBars = 12; // Bars bis zur Profit-Prüfung
input int MaxTradesPerCrossover = 10; // Maximale Trades pro Crossover-Ereignis
input int ProfitCheckBars = 15; // Bars bis zur Profit-Prüfung
input bool CloseUnprofitableTrades = true; // Unprofitable Trades nach X Bars schließen
input bool UseWeeklyADXFilter = true; // W1 ADX Trendfilter aktivieren
input int WeeklyADXPeriod = 15; // ADX-Periode auf W1
input double WeeklyADXMin = 40.0; // Minimaler ADX fuer Trendfreigabe
input int WeeklyADXBarShift = 2; // 1=letzte geschlossene W1-Kerze
input bool WeeklyADXUseDirection = true; // +DI/-DI Richtung mitpruefen
//--- Globale Variablen (Global Variables)
int ema_handle; // EMA Indicator Handle
@@ -36,6 +41,64 @@ 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
//+------------------------------------------------------------------+
//| Weekly ADX trend filter |
//+------------------------------------------------------------------+
bool IsWeeklyADXTrendFavorable(ENUM_ORDER_TYPE order_type)
{
if(!UseWeeklyADXFilter)
return true;
int adxShift = WeeklyADXBarShift;
if(adxShift < 0)
adxShift = 0;
int adx_handle = iADX(_Symbol, PERIOD_W1, WeeklyADXPeriod);
if(adx_handle == INVALID_HANDLE)
{
Print("TRACE: Weekly ADX Handle ungültig - Filter blockiert Entry");
return false;
}
double adx_buf[], plus_di_buf[], minus_di_buf[];
ArraySetAsSeries(adx_buf, true);
ArraySetAsSeries(plus_di_buf, true);
ArraySetAsSeries(minus_di_buf, true);
bool ok_adx = (CopyBuffer(adx_handle, 0, adxShift, 1, adx_buf) > 0);
bool ok_plus = (CopyBuffer(adx_handle, 1, adxShift, 1, plus_di_buf) > 0);
bool ok_minus = (CopyBuffer(adx_handle, 2, adxShift, 1, minus_di_buf) > 0);
IndicatorRelease(adx_handle);
if(!ok_adx || !ok_plus || !ok_minus)
{
Print("TRACE: Weekly ADX Daten nicht verfügbar - Filter blockiert Entry");
return false;
}
double adx_value = adx_buf[0];
double plus_di = plus_di_buf[0];
double minus_di = minus_di_buf[0];
bool strength_ok = (adx_value >= WeeklyADXMin);
bool direction_ok = true;
if(WeeklyADXUseDirection)
{
if(order_type == ORDER_TYPE_BUY)
direction_ok = (plus_di > minus_di);
else
direction_ok = (minus_di > plus_di);
}
Print("TRACE: Weekly ADX Filter | ADX=", DoubleToString(adx_value, 2),
" +DI=", DoubleToString(plus_di, 2),
" -DI=", DoubleToString(minus_di, 2),
" strength_ok=", strength_ok,
" direction_ok=", direction_ok);
return (strength_ok && direction_ok);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
@@ -292,6 +355,11 @@ void PrüfeTrigger()
if(bullish_signal && !PositionExistsByMagic(_Symbol, MagicNumber))
{
if(!IsWeeklyADXTrendFavorable(ORDER_TYPE_BUY))
{
Print("TRACE: Weekly ADX blockiert BUY-Entry");
return;
}
Print("TRACE: Versuche KAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")");
if(PlatziereTrade(ORDER_TYPE_BUY))
{
@@ -300,6 +368,11 @@ void PrüfeTrigger()
}
else if(bearish_signal && !PositionExistsByMagic(_Symbol, MagicNumber))
{
if(!IsWeeklyADXTrendFavorable(ORDER_TYPE_SELL))
{
Print("TRACE: Weekly ADX blockiert SELL-Entry");
return;
}
Print("TRACE: Versuche VERKAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")");
if(PlatziereTrade(ORDER_TYPE_SELL))
{

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,362 @@
#property strict
#property version "1.00"
#property description "BTCUSD mean reversion: RSI extreme + EMA distance + low ADX; escape when ADX trends up."
#include <Trade/Trade.mqh>
input group "=== Market ==="
input string InpSymbol = "BTCUSD";
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_M20;
input double InpLots = 0.01;
input int InpSlippagePoints = 30;
input int InpMagic = 930201;
input int InpMaxPositions = 5;
input bool InpDebugLogs = false;
input group "=== EMA distance (mean reversion stretch) ==="
input int InpEmaPeriod = 250;
input double InpMinEmaDistancePts = 3650.0; // |close-EMA| in points; raise/lower for BTC broker digits
input group "=== RSI ==="
input int InpRsiPeriod = 28;
input double InpRsiOversold = 40.0;
input double InpRsiOverbought = 83.0;
input bool InpUseRsiCross = false; // true: require cross into zone on last bar
input group "=== ADX (trend filter + escape) ==="
input int InpAdxPeriod = 27;
input double InpAdxMaxForEntry = 17.0; // no new trades if ADX >= this (ranging bias)
input double InpAdxEscape = 34.0; // close all if ADX >= this (trend building)
input group "=== Price action (optional) ==="
input bool InpRequireReversalBar = false; // buy: bearish bar at signal; sell: bullish bar
input group "=== Risk ==="
input bool InpUseHardSLTP = false;
input double InpSLPoints = 1300;
input double InpTPPoints = 13400;
CTrade trade;
datetime g_lastBarTime = 0;
int g_hRsi = INVALID_HANDLE;
int g_hEma = INVALID_HANDLE;
int g_hAdx = INVALID_HANDLE;
void DebugLog(const string msg)
{
if(InpDebugLogs)
Print("[MeanRevEMA_RSI_ADX] ", msg);
}
bool IsNewBar(const string symbol, const ENUM_TIMEFRAMES tf)
{
datetime t = iTime(symbol, tf, 0);
if(t <= 0 || t == g_lastBarTime)
return false;
g_lastBarTime = t;
return true;
}
bool CopyOne(const int handle, const int buffer, const int shift, double &out)
{
if(handle == INVALID_HANDLE)
return false;
double v[1];
if(CopyBuffer(handle, buffer, shift, 1, v) != 1)
return false;
out = v[0];
return true;
}
double GetAdx(const int shift)
{
double v = 0.0;
if(!CopyOne(g_hAdx, 0, shift, v))
return 0.0;
return v;
}
double GetRsi(const int shift)
{
double v = 0.0;
if(!CopyOne(g_hRsi, 0, shift, v))
return 0.0;
return v;
}
double GetEma(const int shift)
{
double v = 0.0;
if(!CopyOne(g_hEma, 0, shift, v))
return 0.0;
return v;
}
int CountPositionsByMagic(const string symbol, const int magic)
{
int count = 0;
for(int i = PositionsTotal() - 1; i >= 0; --i)
{
ulong t = PositionGetTicket(i);
if(t == 0)
continue;
if(PositionGetString(POSITION_SYMBOL) == symbol &&
(int)PositionGetInteger(POSITION_MAGIC) == magic)
count++;
}
return count;
}
void CloseAllByMagic(const string symbol, const int magic)
{
for(int i = PositionsTotal() - 1; i >= 0; --i)
{
ulong t = PositionGetTicket(i);
if(t == 0)
continue;
if(PositionGetString(POSITION_SYMBOL) == symbol &&
(int)PositionGetInteger(POSITION_MAGIC) == magic)
trade.PositionClose(t);
}
}
void ComputeSLTP(const bool isBuy, const double entry, double &sl, double &tp)
{
if(!InpUseHardSLTP)
{
sl = 0.0;
tp = 0.0;
return;
}
if(isBuy)
{
sl = entry - InpSLPoints * _Point;
tp = entry + InpTPPoints * _Point;
}
else
{
sl = entry + InpSLPoints * _Point;
tp = entry - InpTPPoints * _Point;
}
}
bool RsiOversoldSignal()
{
double r1 = 0.0, r2 = 0.0;
if(!CopyOne(g_hRsi, 0, 1, r1) || !CopyOne(g_hRsi, 0, 2, r2))
return false;
if(InpUseRsiCross)
return (r2 > InpRsiOversold && r1 <= InpRsiOversold);
return (r1 <= InpRsiOversold);
}
bool RsiOverboughtSignal()
{
double r1 = 0.0, r2 = 0.0;
if(!CopyOne(g_hRsi, 0, 1, r1) || !CopyOne(g_hRsi, 0, 2, r2))
return false;
if(InpUseRsiCross)
return (r2 < InpRsiOverbought && r1 >= InpRsiOverbought);
return (r1 >= InpRsiOverbought);
}
bool BarBearish(const int shift)
{
double o = iOpen(InpSymbol, InpTimeframe, shift);
double c = iClose(InpSymbol, InpTimeframe, shift);
return (c < o);
}
bool BarBullish(const int shift)
{
double o = iOpen(InpSymbol, InpTimeframe, shift);
double c = iClose(InpSymbol, InpTimeframe, shift);
return (c > o);
}
bool BuySetup()
{
if(!RsiOversoldSignal())
return false;
double ema = GetEma(1);
double cls = iClose(InpSymbol, InpTimeframe, 1);
if(ema <= 0.0 || cls <= 0.0)
return false;
double distPts = (ema - cls) / _Point;
if(distPts < InpMinEmaDistancePts)
return false;
if(InpRequireReversalBar && !BarBearish(1))
return false;
double adx = GetAdx(1);
if(adx <= 0.0)
return false;
if(adx >= InpAdxMaxForEntry)
return false;
return true;
}
bool SellSetup()
{
if(!RsiOverboughtSignal())
return false;
double ema = GetEma(1);
double cls = iClose(InpSymbol, InpTimeframe, 1);
if(ema <= 0.0 || cls <= 0.0)
return false;
double distPts = (cls - ema) / _Point;
if(distPts < InpMinEmaDistancePts)
return false;
if(InpRequireReversalBar && !BarBullish(1))
return false;
double adx = GetAdx(1);
if(adx <= 0.0)
return false;
if(adx >= InpAdxMaxForEntry)
return false;
return true;
}
int OnInit()
{
if(StringLen(InpSymbol) == 0)
{
Print("[MeanRevEMA_RSI_ADX] OnInit: InpSymbol is empty.");
return INIT_PARAMETERS_INCORRECT;
}
if(InpRsiPeriod < 2 || InpEmaPeriod < 1 || InpAdxPeriod < 1)
{
Print("[MeanRevEMA_RSI_ADX] OnInit: invalid periods rsi=", InpRsiPeriod,
" ema=", InpEmaPeriod, " adx=", InpAdxPeriod);
return INIT_PARAMETERS_INCORRECT;
}
if(!SymbolSelect(InpSymbol, true))
{
Print("[MeanRevEMA_RSI_ADX] OnInit: SymbolSelect failed (symbol missing on this agent?): ", InpSymbol,
" err=", GetLastError(),
" — use Local agents only for broker-specific names, or set InpSymbol to a symbol the agent has.");
return INIT_PARAMETERS_INCORRECT;
}
g_hRsi = iRSI(InpSymbol, InpTimeframe, InpRsiPeriod, PRICE_CLOSE);
if(g_hRsi == INVALID_HANDLE)
{
Print("[MeanRevEMA_RSI_ADX] OnInit: iRSI failed sym=", InpSymbol, " tf=", (int)InpTimeframe,
" period=", InpRsiPeriod, " err=", GetLastError());
return INIT_FAILED;
}
g_hEma = iMA(InpSymbol, InpTimeframe, InpEmaPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(g_hEma == INVALID_HANDLE)
{
Print("[MeanRevEMA_RSI_ADX] OnInit: iMA failed sym=", InpSymbol, " tf=", (int)InpTimeframe,
" period=", InpEmaPeriod, " err=", GetLastError());
IndicatorRelease(g_hRsi);
g_hRsi = INVALID_HANDLE;
return INIT_FAILED;
}
g_hAdx = iADX(InpSymbol, InpTimeframe, InpAdxPeriod);
if(g_hAdx == INVALID_HANDLE)
{
Print("[MeanRevEMA_RSI_ADX] OnInit: iADX failed sym=", InpSymbol, " tf=", (int)InpTimeframe,
" period=", InpAdxPeriod, " err=", GetLastError());
IndicatorRelease(g_hRsi);
IndicatorRelease(g_hEma);
g_hRsi = g_hEma = INVALID_HANDLE;
return INIT_FAILED;
}
trade.SetExpertMagicNumber(InpMagic);
trade.SetDeviationInPoints(InpSlippagePoints);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(g_hRsi != INVALID_HANDLE) IndicatorRelease(g_hRsi);
if(g_hEma != INVALID_HANDLE) IndicatorRelease(g_hEma);
if(g_hAdx != INVALID_HANDLE) IndicatorRelease(g_hAdx);
g_hRsi = g_hEma = g_hAdx = INVALID_HANDLE;
}
void OnTick()
{
if(_Symbol != InpSymbol)
{
static datetime lastMismatchLog = 0;
datetime nowBar = iTime(_Symbol, PERIOD_M1, 0);
if(nowBar != lastMismatchLog)
{
lastMismatchLog = nowBar;
DebugLog(StringFormat("Skipped: chart symbol=%s but InpSymbol=%s.", _Symbol, InpSymbol));
}
return;
}
const int posCount = CountPositionsByMagic(InpSymbol, InpMagic);
const double adxLive = GetAdx(0);
if(posCount > 0 && adxLive > 0.0 && adxLive >= InpAdxEscape)
{
DebugLog(StringFormat("ADX escape: adx0=%.2f >= %.2f -> closing %d position(s).", adxLive, InpAdxEscape, posCount));
CloseAllByMagic(InpSymbol, InpMagic);
return;
}
if(!IsNewBar(InpSymbol, InpTimeframe))
return;
const double rsi1 = GetRsi(1);
const double adx1 = GetAdx(1);
const double ema1 = GetEma(1);
const double c1 = iClose(InpSymbol, InpTimeframe, 1);
DebugLog(StringFormat("Bar=%s rsi1=%.2f adx1=%.2f ema1=%.5f close1=%.5f positions=%d",
TimeToString(iTime(InpSymbol, InpTimeframe, 1), TIME_DATE | TIME_MINUTES),
rsi1, adx1, ema1, c1, posCount));
if(posCount >= InpMaxPositions)
{
DebugLog(StringFormat("Skipped: max positions (%d).", InpMaxPositions));
return;
}
MqlTick tick;
if(!SymbolInfoTick(InpSymbol, tick))
{
DebugLog("Skipped: SymbolInfoTick failed.");
return;
}
double sl = 0.0, tp = 0.0;
if(BuySetup())
{
ComputeSLTP(true, tick.ask, sl, tp);
if(trade.Buy(InpLots, InpSymbol, tick.ask, sl, tp, "MeanRev_RSI_OS_EMA"))
DebugLog(StringFormat("BUY lots=%.2f ask=%.2f sl=%.2f tp=%.2f", InpLots, tick.ask, sl, tp));
else
DebugLog(StringFormat("BUY failed retcode=%d", trade.ResultRetcode()));
return;
}
if(SellSetup())
{
ComputeSLTP(false, tick.bid, sl, tp);
if(trade.Sell(InpLots, InpSymbol, tick.bid, sl, tp, "MeanRev_RSI_OB_EMA"))
DebugLog(StringFormat("SELL lots=%.2f bid=%.2f sl=%.2f tp=%.2f", InpLots, tick.bid, sl, tp));
else
DebugLog(StringFormat("SELL failed retcode=%d", trade.ResultRetcode()));
return;
}
DebugLog("No entry: RSI/EMA distance/ADX/bar filters not aligned.");
}
@@ -0,0 +1,29 @@
; Synced with daughter.set (ranges + current defaults). Strategy Tester → Inputs → Load.
; Format: value||start||step||stop||Y|N
;
; === Market ===
InpSymbol=BTCUSD
InpTimeframe=20||15||0||16385||Y
InpLots=0.01||0.01||0.001000||0.050000||N
InpSlippagePoints=30||30||1||300||N
InpMagic=930201||930201||1||930201||N
InpMaxPositions=5||1||1||8||Y
InpDebugLogs=false||false||0||true||N
; === EMA distance (mean reversion stretch) ===
InpEmaPeriod=250||50||10||400||Y
InpMinEmaDistancePts=3650||200.0||50.0||5000.0||Y
; === RSI ===
InpRsiPeriod=28||7||1||28||Y
InpRsiOversold=40||18.0||1.0||42.0||Y
InpRsiOverbought=83||58.0||1.0||88.0||Y
InpUseRsiCross=false||false||0||true||Y
; === ADX (trend filter + escape) ===
InpAdxPeriod=27||7||1||28||Y
InpAdxMaxForEntry=17||15.0||1.0||40.0||Y
InpAdxEscape=34||22.0||1.0||55.0||Y
; === Price action (optional) ===
InpRequireReversalBar=false||false||0||true||Y
; === Risk ===
InpUseHardSLTP=false||false||0||true||Y
InpSLPoints=1300||800.0||100.0||8000.0||Y
InpTPPoints=13400||1000.0||200.0||15000.0||Y
@@ -0,0 +1,30 @@
; saved on 2026.04.23 22:29:36
; this file contains input parameters for testing/optimizing MeanReversion expert advisor
; to use it in the strategy tester, click Load in the context menu of the Inputs tab
;
; === Market ===
InpSymbol=BTCUSD
InpTimeframe=20||15||0||16385||Y
InpLots=0.01||0.01||0.001000||0.050000||N
InpSlippagePoints=30||30||1||300||N
InpMagic=930201||930201||1||930201||N
InpMaxPositions=5||1||1||8||Y
InpDebugLogs=false||false||0||true||N
; === EMA distance (mean reversion stretch) ===
InpEmaPeriod=250||50||10||400||Y
InpMinEmaDistancePts=3650||200.0||50.0||5000.0||Y
; === RSI ===
InpRsiPeriod=28||7||1||28||Y
InpRsiOversold=40||18.0||1.0||42.0||Y
InpRsiOverbought=83||58.0||1.0||88.0||Y
InpUseRsiCross=false||false||0||true||Y
; === ADX (trend filter + escape) ===
InpAdxPeriod=27||7||1||28||Y
InpAdxMaxForEntry=17||15.0||1.0||40.0||Y
InpAdxEscape=34||22.0||1.0||55.0||Y
; === Price action (optional) ===
InpRequireReversalBar=false||false||0||true||Y
; === Risk ===
InpUseHardSLTP=false||false||0||true||Y
InpSLPoints=1300||800.0||100.0||8000.0||Y
InpTPPoints=13400||1000.0||200.0||15000.0||Y
@@ -0,0 +1,347 @@
//+------------------------------------------------------------------+
//| RSIConsolidation.mq5 |
//| Mean-reversion RSI for ranging markets; trend filters block runs |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
//--- Symbol (empty = chart symbol)
input group "=== Symbol & session ==="
input string InpSymbol = "";
input group "=== Timeframe & bar logic ==="
input ENUM_TIMEFRAMES SignalTF = PERIOD_M15;
input bool EntryOnNewBarOnly = true;
//--- Core: no trend / consolidation regime
input group "=== Regime: consolidation (anti-trend) ==="
input int ADX_Period = 23;
input double ADX_Max = 29.0;
input bool UseATRRatioFilter = true;
input int ATR_Period = 8;
input int ATR_SMA_Period = 35;
input double ATR_Ratio_Max = 1.36;
input bool UseFlatEMAFilter = true;
input int EMA_Fast = 13;
input int EMA_Slow = 17;
input double EMA_Separation_MaxPct = 0.26;
//--- RSI entries (fade extremes toward mean)
input group "=== RSI entries ==="
input int RSI_Period = 8;
input ENUM_APPLIED_PRICE RSI_Price = PRICE_OPEN;
input double RSI_Oversold = 22.0;
input double RSI_Overbought = 63.0;
//--- Exits: mean target + hard ATR bracket
input group "=== Exits ==="
input bool UseRSI_MeanExit = true;
input double RSI_Exit_Long = 48.0;
input double RSI_Exit_Short = 52.0;
input double SL_ATR_Mult = 2.15;
input double TP_ATR_Mult = 2.40;
input int MaxBarsInTrade = 54;
input group "=== Risk & execution ==="
input double Lots = 0.10;
input ulong MagicNumber = 20250420;
input int Slippage = 10;
input int MaxSpreadPoints = 28;
CTrade trade;
string g_sym;
int h_rsi = INVALID_HANDLE;
int h_adx = INVALID_HANDLE;
int h_atr = INVALID_HANDLE;
int h_ema_fast = INVALID_HANDLE;
int h_ema_slow = INVALID_HANDLE;
datetime g_last_bar = 0;
bool PositionExistsByMagicSym(string sym, ulong magic)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t == 0) continue;
if(PositionGetString(POSITION_SYMBOL) == sym && PositionGetInteger(POSITION_MAGIC) == (long)magic)
return true;
}
return false;
}
ulong GetPositionTicketByMagicSym(string sym, ulong magic)
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t == 0) continue;
if(PositionGetString(POSITION_SYMBOL) == sym && PositionGetInteger(POSITION_MAGIC) == (long)magic)
return t;
}
return 0;
}
bool SelectPositionTicketSymMagic(ulong ticket, string sym, ulong magic)
{
if(!PositionSelectByTicket(ticket)) return false;
return PositionGetString(POSITION_SYMBOL) == sym && PositionGetInteger(POSITION_MAGIC) == (long)magic;
}
double NormalizeVolume(string sym, double vol)
{
double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
if(step > 0.0)
vol = MathFloor(vol / step) * step;
if(vol < minLot) vol = minLot;
if(vol > maxLot) vol = maxLot;
return vol;
}
int CurrentSpreadPoints(string sym)
{
long spread = 0;
if(!SymbolInfoInteger(sym, SYMBOL_SPREAD, spread))
return 999999;
return (int)spread;
}
double MinStopsDistancePrice(string sym)
{
long lvl = 0;
if(!SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL, lvl))
return 0;
double pt = SymbolInfoDouble(sym, SYMBOL_POINT);
if(pt <= 0)
return 0;
return (double)lvl * pt;
}
bool Copy1(int handle, double &v)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(handle, 0, 0, 1, b) < 1) return false;
v = b[0];
return true;
}
bool RSI_Buffers(double &cur, double &prev, double &twoAgo)
{
double b[];
ArraySetAsSeries(b, true);
if(CopyBuffer(h_rsi, 0, 0, 3, b) < 3) return false;
cur = b[0];
prev = b[1];
twoAgo = b[2];
return true;
}
bool Regime_IsConsolidation()
{
double adx = 0;
if(!Copy1(h_adx, adx))
return false;
if(adx >= ADX_Max)
return false;
if(UseATRRatioFilter)
{
double atrArr[], atrSma[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(h_atr, 0, 0, ATR_SMA_Period + 1, atrArr) < ATR_SMA_Period + 1)
return false;
double sum = 0;
for(int i = 1; i <= ATR_SMA_Period; i++)
sum += atrArr[i];
double smaAtr = sum / (double)ATR_SMA_Period;
if(smaAtr <= 0.0)
return false;
double ratio = atrArr[0] / smaAtr;
if(ratio > ATR_Ratio_Max)
return false;
}
if(UseFlatEMAFilter)
{
double ef[], es[];
ArraySetAsSeries(ef, true);
ArraySetAsSeries(es, true);
if(CopyBuffer(h_ema_fast, 0, 0, 1, ef) < 1) return false;
if(CopyBuffer(h_ema_slow, 0, 0, 1, es) < 1) return false;
double c = SymbolInfoDouble(g_sym, SYMBOL_BID);
if(c <= 0) return false;
double sep = MathAbs(ef[0] - es[0]) / c * 100.0;
if(sep > EMA_Separation_MaxPct)
return false;
}
return true;
}
bool Entry_BuyCross(double twoAgo, double prev)
{
return (twoAgo <= RSI_Oversold && prev > RSI_Oversold);
}
bool Entry_SellCross(double twoAgo, double prev)
{
return (twoAgo >= RSI_Overbought && prev < RSI_Overbought);
}
void TryCloseByRSI(ENUM_POSITION_TYPE typ, double rsi)
{
ulong tk = GetPositionTicketByMagicSym(g_sym, MagicNumber);
if(tk == 0 || !SelectPositionTicketSymMagic(tk, g_sym, MagicNumber))
return;
if(!UseRSI_MeanExit)
return;
if(typ == POSITION_TYPE_BUY && rsi >= RSI_Exit_Long)
trade.PositionClose(tk);
else if(typ == POSITION_TYPE_SELL && rsi <= RSI_Exit_Short)
trade.PositionClose(tk);
}
void ManageOpenPosition(double rsi)
{
ulong tk = GetPositionTicketByMagicSym(g_sym, MagicNumber);
if(tk == 0 || !SelectPositionTicketSymMagic(tk, g_sym, MagicNumber))
return;
ENUM_POSITION_TYPE typ = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
datetime openT = (datetime)PositionGetInteger(POSITION_TIME);
int barsAgo = iBarShift(g_sym, SignalTF, openT, false);
if(barsAgo >= 0 && barsAgo >= MaxBarsInTrade)
{
trade.PositionClose(tk);
return;
}
TryCloseByRSI(typ, rsi);
}
int OnInit()
{
g_sym = InpSymbol;
StringTrimLeft(g_sym);
StringTrimRight(g_sym);
if(StringLen(g_sym) == 0)
g_sym = _Symbol;
if(!SymbolSelect(g_sym, true))
{
Print("RSIConsolidation: SymbolSelect failed: ", g_sym);
return INIT_FAILED;
}
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_RETURN);
h_rsi = iRSI(g_sym, SignalTF, RSI_Period, RSI_Price);
h_adx = iADX(g_sym, SignalTF, ADX_Period);
h_atr = iATR(g_sym, SignalTF, ATR_Period);
h_ema_fast = iMA(g_sym, SignalTF, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
h_ema_slow = iMA(g_sym, SignalTF, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
if(h_rsi == INVALID_HANDLE || h_adx == INVALID_HANDLE || h_atr == INVALID_HANDLE
|| h_ema_fast == INVALID_HANDLE || h_ema_slow == INVALID_HANDLE)
{
Print("RSIConsolidation: indicator init failed");
return INIT_FAILED;
}
Print("RSIConsolidation: symbol=", g_sym, " TF=", EnumToString(SignalTF));
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(h_rsi != INVALID_HANDLE) IndicatorRelease(h_rsi);
if(h_adx != INVALID_HANDLE) IndicatorRelease(h_adx);
if(h_atr != INVALID_HANDLE) IndicatorRelease(h_atr);
if(h_ema_fast != INVALID_HANDLE) IndicatorRelease(h_ema_fast);
if(h_ema_slow != INVALID_HANDLE) IndicatorRelease(h_ema_slow);
}
bool EnoughHistory()
{
int need = MathMax(RSI_Period + 3, MathMax(ADX_Period + 2, ATR_SMA_Period + 3));
if(Bars(g_sym, SignalTF) < need)
return false;
return true;
}
void OnTick()
{
if(!EnoughHistory())
return;
if(MaxSpreadPoints > 0 && CurrentSpreadPoints(g_sym) > MaxSpreadPoints)
return;
double rsi, rsiPrev, rsi2;
if(!RSI_Buffers(rsi, rsiPrev, rsi2))
return;
datetime barTime = iTime(g_sym, SignalTF, 0);
bool isNew = (barTime != g_last_bar);
if(PositionExistsByMagicSym(g_sym, MagicNumber))
{
ManageOpenPosition(rsi);
if(isNew)
g_last_bar = barTime;
return;
}
if(EntryOnNewBarOnly && !isNew)
return;
g_last_bar = barTime;
if(!Regime_IsConsolidation())
return;
double atrArr[];
ArraySetAsSeries(atrArr, true);
if(CopyBuffer(h_atr, 0, 0, 1, atrArr) < 1)
return;
double atr = atrArr[0];
int dig = (int)SymbolInfoInteger(g_sym, SYMBOL_DIGITS);
double slDist = atr * SL_ATR_Mult;
double tpDist = atr * TP_ATR_Mult;
double minD = MinStopsDistancePrice(g_sym);
if(slDist < minD)
slDist = minD;
if(tpDist < minD)
tpDist = minD;
double vol = NormalizeVolume(g_sym, Lots);
if(Entry_BuyCross(rsi2, rsiPrev))
{
double ask = SymbolInfoDouble(g_sym, SYMBOL_ASK);
double sl = ask - slDist;
double tp = ask + tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
trade.Buy(vol, g_sym, ask, sl, tp, "RSIConsolidation BUY");
}
else if(Entry_SellCross(rsi2, rsiPrev))
{
double bid = SymbolInfoDouble(g_sym, SYMBOL_BID);
double sl = bid + slDist;
double tp = bid - tpDist;
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
trade.Sell(vol, g_sym, bid, sl, tp, "RSIConsolidation SELL");
}
}
//+------------------------------------------------------------------+
@@ -0,0 +1,37 @@
; RSIConsolidation.mq5 — optimization preset (Strategy Tester → Inputs → Load)
; Format: Name=Current||Start||Step||Stop||Y|N (Y = include in optimization)
;
; === Symbol & session ===
InpSymbol=
; === Timeframe & bar logic ===
; SignalTF: optimize per run (ENUM is non-sequential); M15=15, H1=16385, H4=16388
SignalTF=15||15||0||15||N
EntryOnNewBarOnly=true||false||0||true||N
; === Regime: consolidation (anti-trend) ===
ADX_Period=14||7||1||28||Y
ADX_Max=22.0||16.0||1.0||32.0||Y
UseATRRatioFilter=true||false||0||true||N
ATR_Period=14||7||1||21||Y
ATR_SMA_Period=50||20||5||100||Y
ATR_Ratio_Max=1.18||1.0||0.02||1.35||Y
UseFlatEMAFilter=true||false||0||true||N
EMA_Fast=8||5||1||13||Y
EMA_Slow=21||13||2||34||Y
EMA_Separation_MaxPct=0.22||0.08||0.02||0.45||Y
; === RSI entries ===
RSI_Period=14||7||1||21||Y
RSI_Price=1||1||1||7||Y
RSI_Oversold=32.0||22.0||1.0||42.0||Y
RSI_Overbought=68.0||58.0||1.0||78.0||Y
; === Exits ===
UseRSI_MeanExit=true||false||0||true||N
RSI_Exit_Long=52.0||48.0||1.0||62.0||Y
RSI_Exit_Short=48.0||38.0||1.0||52.0||Y
SL_ATR_Mult=1.35||0.9||0.05||2.2||Y
TP_ATR_Mult=1.85||1.0||0.05||3.0||Y
MaxBarsInTrade=36||12||2||80||Y
; === Risk & execution ===
Lots=0.1||0.1||0.01||1.0||N
MagicNumber=20250420||20250420||1||20250420||N
Slippage=10||10||1||100||N
MaxSpreadPoints=0||0||1||30||Y
@@ -9,7 +9,7 @@ input int overboughtLevel = 93; // Overbought level (RSI > 70 for sell)
input int oversoldLevel = 22; // Oversold level (RSI < 30 for buy)
input double entryRSIBuySpread = 0;
input double entryRSISellSpread = 0;
input double lotSize = 0.01; // Trade lot size
input double lotSize = 0.1; // Trade lot size
input int slippage = 3; // Slippage for orders
input int cooldownSeconds = 209; // Cooldown period in seconds
input ENUM_TIMEFRAMES TimeFrame1 = PERIOD_M1; // RSI Timeframe
@@ -14,7 +14,7 @@
// Input Parameters
input group "General Settings"
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_H1; // Trading Timeframe
input double InpLotSize = 0.02; // Lot Size
input double InpLotSize = 0.1; // Lot Size
input int InpMagicNumberRSIFollow = 1001; // Magic Number RSI Follow
input int InpMagicNumberRSIReverse = 1002;// Magic Number RSI Reverse
input int InpMagicNumberEMACross = 1003; // Magic Number EMA Cross
@@ -23,9 +23,9 @@ input group "Strategy Switches"
input bool InpEnableRSIFollow = true; // Enable RSI Follow Strategy
input bool InpEnableRSIReverse = true; // Enable RSI Reverse Strategy
input bool InpEnableEMACross = true; // Enable EMA Cross Strategy
input bool InpEnableStrategyLock = false; // Enable Strategy Lock
input double InpLockProfitThreshold = 0.0; // Lock Profit Threshold (pips)
input bool InpCloseOppositeTrades = false; // Close Opposite Trades When Profiting
input bool InpEnableStrategyLock = true; // Enable Strategy Lock
input double InpLockProfitThreshold = 6.0; // Lock Profit Threshold (pips)
input bool InpCloseOppositeTrades = true; // Close Opposite Trades When Profiting
input group "RSI Follow Strategy"
input int InpRSIPeriod = 32; // RSI Period

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 241 KiB

Some files were not shown because too many files have changed in this diff Show More