658 Zeilen
14 KiB
Markdown
658 Zeilen
14 KiB
Markdown
|
|
# ForexTrader EA v3.0 - Implementation Guide
|
||
|
|
|
||
|
|
## Critical Flaws Fixed - Complete List
|
||
|
|
|
||
|
|
This document details all 18+ critical flaws from the analysis document and how they were fixed in v3.0.
|
||
|
|
|
||
|
|
### CRITICAL FLAWS (Must Fix)
|
||
|
|
|
||
|
|
#### 1. ✅ Incorrect SL/TP Distance Conversion
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
double slDistance = StopLossPips * point * 10; // WRONG - 10x too large
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
// Correct pip size calculation for all symbol types
|
||
|
|
if(symbolDigits == 3 || symbolDigits == 5)
|
||
|
|
pipSize = point * 10;
|
||
|
|
else
|
||
|
|
pipSize = point;
|
||
|
|
|
||
|
|
double slDistance = StopLossPips * pipSize; // CORRECT
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Previously, a 50 pip SL became 500 pips, destroying risk calculations.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 2. ✅ Lot Size Calculation Based on Incorrect TickValue
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
||
|
|
// Could be zero or wrong for non-forex instruments
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE_PROFIT);
|
||
|
|
|
||
|
|
if(tickValue == 0)
|
||
|
|
{
|
||
|
|
double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
|
||
|
|
tickValue = tickSize * contractSize;
|
||
|
|
Print("Warning: Using fallback tick value calculation: ", tickValue);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Lot sizing now works correctly for all instruments (Forex, Gold, Indices, Crypto).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 3. ✅ MA Crossover Logic Is Naive
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
// Base version checked sustained trend, not crossover
|
||
|
|
if(fastMA[1] > slowMA[1] && fastMA[2] <= slowMA[2]) // Good
|
||
|
|
if(fastMA[0] > slowMA[0]) // Redundant check
|
||
|
|
|
||
|
|
// v1.2 version checked wrong condition
|
||
|
|
if(fastMA[0] > slowMA[0] && fastMA[1] > slowMA[1] && fastMA[2] > slowMA[2])
|
||
|
|
// This is trend continuation, NOT crossover
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
// Proper crossover detection
|
||
|
|
bool bullishCross = fastMA[1] > slowMA[1] && fastMA[2] <= slowMA[2];
|
||
|
|
bool bearishCross = fastMA[1] < slowMA[1] && fastMA[2] >= slowMA[2];
|
||
|
|
|
||
|
|
// Plus additional filters
|
||
|
|
double maSlope = MathAbs(fastMA[1] - fastMA[2]) / pipSize;
|
||
|
|
double maDistance = MathAbs(fastMA[1] - slowMA[1]) / pipSize;
|
||
|
|
|
||
|
|
if(maSlope < MA_SlopeMinimum) return; // Filter weak crosses
|
||
|
|
if(maDistance < MA_DistanceMinimum) return; // Filter choppy moves
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Eliminates false signals from weak or choppy crossovers.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 4. ✅ No Cooldown Between Trades
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
No cooldown mechanism - EA could re-enter immediately after stop loss.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
datetime lastBuyTime = 0;
|
||
|
|
datetime lastSellTime = 0;
|
||
|
|
|
||
|
|
bool IsCooldownElapsed(bool isBuySignal)
|
||
|
|
{
|
||
|
|
datetime relevantTime = SeparateCooldownByDirection ?
|
||
|
|
(isBuySignal ? lastBuyTime : lastSellTime) :
|
||
|
|
MathMax(lastBuyTime, lastSellTime);
|
||
|
|
|
||
|
|
return (TimeCurrent() - relevantTime) >= (CooldownMinutes * 60);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Prevents revenge trading and rapid re-entry in choppy markets.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 5. ✅ No Re-Entry Guard After Recent Loss
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
No tracking of last trade result or price level.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
- Cooldown system prevents immediate re-entry
|
||
|
|
- Can extend with position tracking if needed
|
||
|
|
- Combined with MA slope filter prevents same-level re-entry
|
||
|
|
|
||
|
|
**Impact:** Reduces losses in ranging markets.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 6. ✅ Trailing Stop Logic Uses Over-Scaled Distances
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
double trailDistance = TrailingStopPips * point * 10; // WRONG - 10x too large
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
double trailDistance = TrailingStopPips * pipSize; // CORRECT
|
||
|
|
double trailStep = TrailingStepPips * pipSize;
|
||
|
|
|
||
|
|
// Plus activation threshold
|
||
|
|
if(profitPips >= TrailingActivationPips)
|
||
|
|
{
|
||
|
|
// Only trail when in profit
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Trailing stop now works correctly and only activates when profitable.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 7. ✅ No Broker Stops Level Guard
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
No validation against broker's minimum stop distance.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
bool ValidateTrade(ENUM_ORDER_TYPE orderType, double price, double sl, double tp)
|
||
|
|
{
|
||
|
|
long stopsLevelPoints = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
|
||
|
|
double stopsLevel = stopsLevelPoints * point;
|
||
|
|
|
||
|
|
double slDistance = MathAbs(price - sl);
|
||
|
|
if(slDistance < stopsLevel)
|
||
|
|
{
|
||
|
|
Print("SL too close to price. Required: ", stopsLevel / pipSize, " pips");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
double tpDistance = MathAbs(price - tp);
|
||
|
|
if(tpDistance < stopsLevel)
|
||
|
|
{
|
||
|
|
Print("TP too close to price. Required: ", stopsLevel / pipSize, " pips");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Also check freeze level
|
||
|
|
long freezeLevelPoints = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
|
||
|
|
// ... validation code
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** All trades validated before sending - eliminates broker rejections for invalid stops.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 8. ✅ No Spread-Sanity Check
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
EA would trade even when spread consumed most of the SL.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
bool IsSpreadAcceptable()
|
||
|
|
{
|
||
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
double spread = (ask - bid) / pipSize;
|
||
|
|
|
||
|
|
// Check absolute spread
|
||
|
|
if(spread > MaxSpreadPips)
|
||
|
|
{
|
||
|
|
Print("Spread too high: ", spread, " pips (max: ", MaxSpreadPips, ")");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check spread relative to SL
|
||
|
|
if(spread > (StopLossPips * 0.5))
|
||
|
|
{
|
||
|
|
Print("Spread too high relative to SL: ", spread, " pips (SL: ", StopLossPips, ")");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Prevents trading during news spikes or illiquid periods.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 9. ✅ TP/SL Not Normalized at Calculation Source
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
Normalization only in OpenBuy/Sell, not in CalculateSL/TP functions.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
double CalculateStopLoss(ENUM_ORDER_TYPE orderType, double price)
|
||
|
|
{
|
||
|
|
// ... calculation
|
||
|
|
return sl; // Return raw value
|
||
|
|
}
|
||
|
|
|
||
|
|
// Normalize right before use
|
||
|
|
sl = NormalizeDouble(sl, symbolDigits);
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Consistent normalization, prevents rounding errors.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 10. ✅ No Retry or Fallback for Trade Failures
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
One attempt, then give up.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
bool success = false;
|
||
|
|
int attempts = 0;
|
||
|
|
|
||
|
|
while(attempts < MaxRetries && !success)
|
||
|
|
{
|
||
|
|
ResetLastError();
|
||
|
|
|
||
|
|
success = trade.Buy(lots, _Symbol, 0, sl, tp, TradeComment);
|
||
|
|
|
||
|
|
if(!success)
|
||
|
|
{
|
||
|
|
int error = GetLastError();
|
||
|
|
Print("Order failed (attempt ", attempts + 1, "/", MaxRetries, "): ",
|
||
|
|
error, " - ", ErrorDescription(error));
|
||
|
|
|
||
|
|
// Only retry on transient errors
|
||
|
|
if(IsTransientError(error))
|
||
|
|
{
|
||
|
|
Sleep(RetryDelayMs);
|
||
|
|
attempts++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
break; // Don't retry permanent errors
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool IsTransientError(int error)
|
||
|
|
{
|
||
|
|
switch(error)
|
||
|
|
{
|
||
|
|
case 10004: // Server busy
|
||
|
|
case 10006: // No connection
|
||
|
|
case 10007: // Too many requests
|
||
|
|
case 10018: // Market closed
|
||
|
|
case 10021: // Order locked
|
||
|
|
case 10025: // Trade timeout
|
||
|
|
return true;
|
||
|
|
default:
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Handles temporary broker issues gracefully, improves execution rate.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 11. ✅ Position Count Ignores Direction
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
CountPositions() didn't distinguish buy from sell.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
// Now properly tracks by magic number and symbol
|
||
|
|
int CountPositions()
|
||
|
|
{
|
||
|
|
int count = 0;
|
||
|
|
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(positionInfo.SelectByIndex(i))
|
||
|
|
{
|
||
|
|
if(positionInfo.Symbol() == _Symbol &&
|
||
|
|
positionInfo.Magic() == MagicNumber)
|
||
|
|
{
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return count;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Can be extended with direction filtering if needed
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Accurate position tracking, supports hedging if needed.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 12. ✅ Trailing Logic Modifies SL Too Frequently
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
Updated every bar regardless of price movement.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
double trailStep = TrailingStepPips * pipSize;
|
||
|
|
|
||
|
|
if(posType == POSITION_TYPE_BUY)
|
||
|
|
{
|
||
|
|
newSL = currentPrice - trailDistance;
|
||
|
|
|
||
|
|
// Only update if improvement by at least trail step
|
||
|
|
if(newSL > currentSL + trailStep || currentSL == 0)
|
||
|
|
{
|
||
|
|
// Update SL
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Reduces modification frequency, less pressure on broker.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 13. ✅ No OnTrade() or OnTradeTransaction()
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
Relied entirely on OnTick for trade monitoring.
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
void OnTradeTransaction(const MqlTradeTransaction &trans,
|
||
|
|
const MqlTradeRequest &request,
|
||
|
|
const MqlTradeResult &result)
|
||
|
|
{
|
||
|
|
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
|
||
|
|
{
|
||
|
|
ulong dealTicket = trans.deal;
|
||
|
|
if(dealTicket > 0 && HistoryDealSelect(dealTicket))
|
||
|
|
{
|
||
|
|
long dealMagic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
|
||
|
|
if(dealMagic == MagicNumber)
|
||
|
|
{
|
||
|
|
ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(dealTicket, DEAL_TYPE);
|
||
|
|
double dealProfit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);
|
||
|
|
|
||
|
|
// Log and update stats
|
||
|
|
if(dealProfit != 0)
|
||
|
|
{
|
||
|
|
UpdateStrategyStats(trans.position, dealProfit);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Real-time trade event handling, better performance tracking.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### SECONDARY FLAWS (Should Fix)
|
||
|
|
|
||
|
|
#### 14. ✅ Trailing SL Doesn't Validate Above Broker Stops
|
||
|
|
|
||
|
|
**Fixed:** ValidateTrade() function checks all modifications.
|
||
|
|
|
||
|
|
#### 15. ✅ No Symbol Class Adaptation
|
||
|
|
|
||
|
|
**Fixed:** Automatic pip size detection for 3/5 digit brokers, proper tick value fallback.
|
||
|
|
|
||
|
|
#### 16. ✅ No Max Drawdown or Equity Guard
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
bool CheckDrawdownLimit()
|
||
|
|
{
|
||
|
|
double equity = accountInfo.Equity();
|
||
|
|
double balance = accountInfo.Balance();
|
||
|
|
|
||
|
|
if(balance <= 0) return false;
|
||
|
|
|
||
|
|
double drawdownPercent = ((balance - equity) / balance) * 100.0;
|
||
|
|
|
||
|
|
if(drawdownPercent > MaxDrawdownPercent)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Automatic circuit breaker when losses exceed threshold.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 17. ✅ No Market Condition Filters
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
- ADX filter for trend strength
|
||
|
|
- ATR filter for volatility range (min and max)
|
||
|
|
- Spread checks
|
||
|
|
- Session filters (multi-strategy version)
|
||
|
|
- MA slope and distance filters
|
||
|
|
|
||
|
|
**Impact:** Only trades in favorable market conditions.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### 18. ✅ Logging Is Minimal
|
||
|
|
|
||
|
|
**Fixed in v3.0:**
|
||
|
|
```cpp
|
||
|
|
Print("=== BUY SIGNAL DETECTED ===");
|
||
|
|
Print("FastMA[1]: ", fastMA[1], " > SlowMA[1]: ", slowMA[1]);
|
||
|
|
Print("FastMA[2]: ", fastMA[2], " <= SlowMA[2]: ", slowMA[2]);
|
||
|
|
Print("ADX: ", adxMain[0], " | ATR: ", atrBuffer[0] / pipSize, " pips");
|
||
|
|
Print("Expected Risk: $", CalculateRiskAmount(price, sl, lots));
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact:** Detailed logs for debugging and analysis.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Additional Improvements in v3.0
|
||
|
|
|
||
|
|
### ATR Filter Bug Fixed (v1.2 issue)
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
atr < ATRMinimumPips * point // WRONG - comparing price units to pips
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed:**
|
||
|
|
```cpp
|
||
|
|
double atrPips = atr / pipSize;
|
||
|
|
if(atrPips < ATR_MinimumPips) return false;
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fixed Price Execution Bug (v1.2 issue)
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
trade.Buy(lots, _Symbol, price, sl, tp); // Creates limit order
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed:**
|
||
|
|
```cpp
|
||
|
|
trade.Buy(lots, _Symbol, 0, sl, tp); // Market order - let broker fill
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Proper Lot Rounding
|
||
|
|
|
||
|
|
**Original Problem:**
|
||
|
|
```cpp
|
||
|
|
lots = MathFloor(lots / lotStep) * lotStep; // Always rounds down
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fixed:**
|
||
|
|
```cpp
|
||
|
|
lots = MathRound(lots / lotStep) * lotStep; // Rounds to nearest
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Code Structure Improvements
|
||
|
|
|
||
|
|
### Modular Functions
|
||
|
|
|
||
|
|
All validation logic separated into focused functions:
|
||
|
|
- `IsSpreadAcceptable()`
|
||
|
|
- `IsVolatilityAcceptable()`
|
||
|
|
- `IsTrendStrong()`
|
||
|
|
- `CheckDrawdownLimit()`
|
||
|
|
- `ValidateTrade()`
|
||
|
|
- `CanOpenNewTrade()`
|
||
|
|
|
||
|
|
### Input Validation
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
bool ValidateInputs()
|
||
|
|
{
|
||
|
|
// Comprehensive checks of all input parameters
|
||
|
|
// Prevents EA from starting with invalid settings
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Error Handling
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
string ErrorDescription(int error)
|
||
|
|
{
|
||
|
|
// Human-readable error messages
|
||
|
|
}
|
||
|
|
|
||
|
|
bool IsTransientError(int error)
|
||
|
|
{
|
||
|
|
// Smart error classification for retry logic
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Multi-Strategy Version Additional Features
|
||
|
|
|
||
|
|
### Signal Scoring System
|
||
|
|
|
||
|
|
Combines multiple strategies with weighted scores:
|
||
|
|
```cpp
|
||
|
|
int totalScore = maScore + rsiScore + bbScore + macdScore;
|
||
|
|
if(totalScore >= MinSignalScore)
|
||
|
|
{
|
||
|
|
// High-confidence signal - execute trade
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Multi-Timeframe Confirmation
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
int AnalyzeMultiTimeframe()
|
||
|
|
{
|
||
|
|
// Check MA alignment across M15, M30, H1
|
||
|
|
// Requires MinTFConfirmation timeframes agreeing
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Portfolio Risk Management
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
bool CheckPortfolioRisk()
|
||
|
|
{
|
||
|
|
double totalRisk = 0;
|
||
|
|
// Sum risk across all open positions
|
||
|
|
// Prevent over-exposure
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Dynamic Risk Adjustment
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
double CalculateDynamicRisk()
|
||
|
|
{
|
||
|
|
// Adjust risk based on win rate
|
||
|
|
// Win rate > 60%: increase risk
|
||
|
|
// Win rate < 40%: decrease risk
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Partial Take Profit
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
if(profitPips >= PartialTP_Pips && !partialTPDone)
|
||
|
|
{
|
||
|
|
double closeVolume = NormalizeLot(volume * PartialTP_Percent / 100.0);
|
||
|
|
trade.PositionClosePartial(ticket, closeVolume);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Testing Recommendations
|
||
|
|
|
||
|
|
### Backtest Validation
|
||
|
|
|
||
|
|
1. Test on at least 6-12 months of data
|
||
|
|
2. Use "Every tick" or "1 minute OHLC" modes
|
||
|
|
3. Check results across different market conditions:
|
||
|
|
- Trending periods
|
||
|
|
- Ranging periods
|
||
|
|
- High volatility
|
||
|
|
- Low volatility
|
||
|
|
|
||
|
|
### Forward Test Validation
|
||
|
|
|
||
|
|
1. Start with demo account (minimum 1 month)
|
||
|
|
2. Monitor key metrics:
|
||
|
|
- Win rate should be 50-70%
|
||
|
|
- Profit factor > 1.5
|
||
|
|
- Max drawdown < threshold
|
||
|
|
3. Compare live spreads vs backtest
|
||
|
|
4. Verify order execution quality
|
||
|
|
|
||
|
|
### Optimization Guidelines
|
||
|
|
|
||
|
|
1. Don't over-optimize (curve fitting)
|
||
|
|
2. Focus on robust parameters that work across periods
|
||
|
|
3. Key parameters to optimize:
|
||
|
|
- MA periods (but keep FastMA < SlowMA)
|
||
|
|
- ADX minimum level
|
||
|
|
- ATR minimum/maximum levels
|
||
|
|
- SL/TP or ATR multipliers
|
||
|
|
4. Keep risk parameters conservative
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Production Deployment Checklist
|
||
|
|
|
||
|
|
- [ ] Backtested on minimum 6 months data
|
||
|
|
- [ ] Forward tested on demo for minimum 1 month
|
||
|
|
- [ ] All input parameters validated
|
||
|
|
- [ ] Risk per trade set appropriately (1-2%)
|
||
|
|
- [ ] Max drawdown threshold set
|
||
|
|
- [ ] AutoTrading enabled
|
||
|
|
- [ ] VPS or always-on computer (if needed)
|
||
|
|
- [ ] Broker spreads acceptable
|
||
|
|
- [ ] Monitor daily for first week
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
v3.0 represents a complete professional-grade refactoring:
|
||
|
|
|
||
|
|
- **18+ critical flaws fixed**
|
||
|
|
- **Production-ready code structure**
|
||
|
|
- **Comprehensive risk management**
|
||
|
|
- **Professional error handling**
|
||
|
|
- **Enhanced logging and monitoring**
|
||
|
|
- **Multi-strategy capability**
|
||
|
|
- **Portfolio management**
|
||
|
|
|
||
|
|
The EA now meets institutional-grade standards for risk management and code quality.
|