Files
EA/Buffer EA/TEST_PLAN.md
Kunthawat Greethong 04aa2eb2e6 New EA and Indi
2026-01-25 10:34:54 +07:00

18 KiB

Universal Buffer Reader EA - Test Plan

Phase 11: Testing & Validation

Version: 2.0 Date: 2025-01-20 Status: Ready for Testing


1. Compilation Verification

1.1 Pre-Compilation Checklist

  • All syntax errors fixed (removed extra quotes from #property strict)
  • All bracket balances verified (10 files, all balanced)
  • All include statements verified
  • All class declarations verified

1.2 Compilation Steps

  1. Open MetaEditor 5
  2. Open Universal_Buffer_Reader_EA.mq5
  3. Press F7 or click "Compile"
  4. Verify no errors in "Errors" tab
  5. Verify no warnings in "Warnings" tab

Expected Result: 0 errors, 0 warnings

1.3 Individual File Compilation

Compile each include file separately:

  • Include/LoggingManager.mqh
  • Include/SignalDetector.mqh
  • Include/TimeFilter.mqh
  • Include/MoneyManager.mqh
  • Include/RiskManager.mqh
  • Include/PartialCloseManager.mqh
  • Include/TradeExecutor.mqh
  • Include/StateManager.mqh
  • Include/UIManager.mqh

2. Component Unit Tests

2.1 CLoggingManager

Test Cases:

  1. Error Deduplication

    • Log same error twice → Should only print once
    • Log different errors → Should print both
    • Clear error records → Should allow duplicate again
  2. Log Level Filtering

    • Debug mode enabled → All messages printed
    • Debug mode disabled → Only info/warning/error printed
  3. Session ID Generation

    • Generate session ID → Should be unique
    • Format: "SES_YYYYMMDD_HHMMSS"

Test Method:

// In OnInit
CLoggingManager *logger = new CLoggingManager();
logger.SetParameters(true);
logger.SetDebugMode(true);

// Test error deduplication
logger.LogError(1, "Test error");  // Should print
logger.LogError(1, "Test error");  // Should NOT print (duplicate)
logger.ClearErrorRecords();
logger.LogError(1, "Test error");  // Should print again (cleared)

2.2 CSignalDetector

Test Cases:

  1. Signal Detection

    • Buy signal in buffer 0 → Should detect BUY
    • Sell signal in buffer 1 → Should detect SELL
    • No signal → Should return NO_SIGNAL
  2. SL/TP Buffer Reading

    • Read Buy SL from buffer 2 → Should return correct value
    • Read Buy TP1 from buffer 3 → Should return correct value
    • Read Sell SL from buffer 6 → Should return correct value
    • Read Sell TP1 from buffer 7 → Should return correct value
  3. ATR Fallback

    • Indicator SL/TP empty → Should use ATR
    • ATR value valid → Should calculate SL/TP from ATR
    • Minimum TP enforcement → Should enforce minimum TP
  4. Buffer Validation

    • Invalid buffer index → Should return 0
    • Empty buffer → Should return 0

Test Method:

// In OnInit
CSignalDetector *detector = new CSignalDetector();
detector.SetParameters("TestIndicator", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 1.5, 20, true);

// Test signal detection
int signal = detector.DetectSignal();
Print("Signal: ", signal);

// Test SL/TP reading
double buy_sl = detector.GetBuySL();
double buy_tp1 = detector.GetBuyTP1();
Print("Buy SL: ", buy_sl, " TP1: ", buy_tp1);

2.3 CTimeFilter

Test Cases:

  1. Day of Week Filtering

    • Monday enabled, current day Monday → Should return true
    • Monday disabled, current day Monday → Should return false
    • All days enabled → Should always return true
  2. Session Filtering

    • Asian session enabled, current time in Asian → Should return true
    • Asian session disabled, current time in Asian → Should return false
    • All sessions enabled → Should always return true
  3. Helper Methods

    • IsAsianSession() → Should return correct status
    • IsEuropeSession() → Should return correct status
    • IsAmericaSession() → Should return correct status

Test Method:

// In OnInit
CTimeFilter *time_filter = new CTimeFilter();
bool days[7] = {false, true, true, true, true, true, false};  // Mon-Fri
time_filter.SetParameters(true, days, true, true, true, true);

// Test time filtering
bool allowed = time_filter.IsTimeAllowed();
Print("Time allowed: ", allowed);

// Test helper methods
Print("Asian session: ", time_filter.IsAsianSession());
Print("Europe session: ", time_filter.IsEuropeSession());
Print("America session: ", time_filter.IsAmericaSession());

2.4 CMoneyManager

Test Cases:

  1. Lot Size Calculation

    • Fixed lot size → Should return base lot size
    • Percent of balance → Should calculate based on balance
    • Min/Max lot enforcement → Should enforce limits
  2. Daily Profit Tracking

    • Start of day → Should reset daily profit
    • Profit made → Should track correctly
    • Daily target reached → Should return true
  3. Lot Step Rounding

    • Lot size 0.123, step 0.01 → Should round to 0.12
    • Lot size 0.125, step 0.01 → Should round to 0.13

Test Method:

// In OnInit
CMoneyManager *money_manager = new CMoneyManager();
money_manager.SetParameters(0.03, true, 1.0, 2.0, 0.01, 10.0, 0.01, 0.0001, 1.0, true);

// Test lot size calculation
double lot_size = money_manager.CalculateLotSize(true, 1.2500, 1.2550, 10000);
Print("Lot size: ", lot_size);

// Test daily profit tracking
money_manager.UpdateDailyProfit(50.0);
bool target_reached = money_manager.IsDailyProfitTargetReached();
Print("Target reached: ", target_reached);

2.5 CRiskManager

Test Cases:

  1. Breakeven

    • Profit >= BreakevenPips → Should move SL to open price
    • Profit < BreakevenPips → Should not move SL
    • Breakeven already set → Should not modify again
  2. TP-Based Trailing

    • TP1 reached → Should move SL to breakeven
    • TP2 reached → Should move SL to TP1
    • Partial close disabled → Should not use TP-based trailing
  3. Standard Trailing

    • Profit >= TrailingStart → Should start trailing
    • Profit moves up → Should move SL up
    • Profit moves down → Should keep SL at trailing distance
  4. Partial Close Tracking

    • Partial close enabled → Should track TP levels
    • Partial close disabled → Should not track TP levels

Test Method:

// In OnInit
CRiskManager *risk_manager = new CRiskManager();
risk_manager.SetParameters(true, 20, true, 10, true, 30, 15, true);
risk_manager.EnablePartialClose(true);

// Test breakeven
risk_manager.ManageBreakeven(ticket, open_price, current_sl, current_tp);

// Test TP-based trailing
risk_manager.ManageTPBasedTrailing(ticket, open_price, current_sl, tp1, tp2, tp3);

// Test standard trailing
risk_manager.ManageTrailingStop(ticket, open_price, current_sl, current_tp);

2.6 CPartialCloseManager

Test Cases:

  1. Multiple TPs

    • TP1 reached → Should close partial position
    • TP2 reached → Should close another partial
    • TP3 reached → Should close remaining
  2. Equal Division

    • 3 TPs, equal division → Should close 33.33% each
    • 2 TPs, equal division → Should close 50% each
  3. Custom Percentages

    • Custom percentages → Should use specified amounts
    • Sum = 100% → Should close entire position
  4. TP Tracking

    • TP1 reached → Should mark TP1 as hit
    • TP2 reached → Should mark TP2 as hit
    • Already hit → Should not close again

Test Method:

// In OnInit
CPartialCloseManager *partial_close = new CPartialCloseManager();
double percentages[3] = {33.33, 33.33, 33.34};
partial_close.SetParameters(true, false, percentages, true);

// Test partial close
partial_close.CheckAndClosePartial(ticket, current_price, tp1, tp2, tp3);

2.7 CTradeExecutor

Test Cases:

  1. Order Execution

    • Buy order → Should execute correctly
    • Sell order → Should execute correctly
    • Invalid parameters → Should return false
  2. Screenshot Capture

    • Screenshot enabled → Should capture image
    • Screenshot disabled → Should not capture
    • File path valid → Should save correctly
  3. Opposite Trade Closure

    • Buy signal, existing sell → Should close sell
    • Sell signal, existing buy → Should close buy
    • No opposite trade → Should do nothing
  4. Order Comment Format

    • Order comment → Should contain TP levels
    • Format: UnivBufEA_24680;TP1=1.2530;TP2=1.2560;TP3=1.2600;BE=0;TS=0

Test Method:

// In OnInit
CTradeExecutor *executor = new CTradeExecutor();
executor.SetParameters(3, 24680, true, true);

// Test buy order
ulong ticket = executor.OpenBuy(1.2500, 1.2450, 1.2550, 1.2600, 1.2650, 0.03);
Print("Buy ticket: ", ticket);

// Test sell order
ticket = executor.OpenSell(1.2500, 1.2550, 1.2450, 1.2400, 1.2350, 0.03);
Print("Sell ticket: ", ticket);

2.8 CStateManager

Test Cases:

  1. State Persistence

    • Save state → Should write to global variables
    • Load state → Should read from global variables
    • State survives EA restart → Should persist
  2. State Validation

    • Valid state → Should load correctly
    • Invalid state (negative) → Should reset to 0
    • Missing state → Should initialize to 0
  3. State Keys

    • Accumulated loss key → UnivBufEA_{Symbol}_{MagicNumber}_AccumLoss
    • Consecutive loss key → UnivBufEA_{Symbol}_{MagicNumber}_ConsecLoss

Test Method:

// In OnInit
CStateManager *state_manager = new CStateManager();
state_manager.SetParameters("EURUSD", 24680, "UnivBufEA");

// Test state loading
state_manager.LoadState();
double accum_loss = state_manager.GetAccumulatedLoss();
int consec_loss = state_manager.GetConsecutiveLosses();
Print("Accumulated loss: ", accum_loss, " Consecutive losses: ", consec_loss);

// Test state saving
state_manager.SetAccumulatedLoss(100.0);
state_manager.SetConsecutiveLosses(3);
state_manager.SaveState();

2.9 CUIManager

Test Cases:

  1. Chart Labels

    • Create labels → Should appear on chart
    • Update labels → Should reflect changes
    • Delete labels → Should remove from chart
  2. Manual Mode UI

    • Manual mode enabled → Should show manual controls
    • Manual mode disabled → Should hide controls
    • Buy button → Should trigger buy order
    • Sell button → Should trigger sell order
  3. Loss Display

    • Accumulated loss → Should display correctly
    • Consecutive losses → Should display correctly
    • Update on change → Should reflect immediately

Test Method:

// In OnInit
CUIManager *ui_manager = new CUIManager();
ui_manager.SetParameters(0, true, 24680, "EURUSD", 100.0, 3, true);

// Test UI creation
ui_manager.CreateUI();

// Test loss display update
ui_manager.UpdateLossDisplay(150.0, 4);

3. Integration Tests

3.1 Full Signal-to-Execution Flow

Test Scenario:

  1. Indicator generates buy signal
  2. Time filter allows trading
  3. Daily profit target not reached
  4. Money manager calculates lot size
  5. Trade executor opens buy order
  6. Risk manager sets breakeven
  7. Partial close manager monitors TPs
  8. UI manager updates display

Expected Result: Order opened successfully, all components work together

Test Steps:

// In OnTick
if (IsNewBar()) {
    // 1. Check time filter
    if (!g_time_filter.IsTimeAllowed()) {
        return;
    }

    // 2. Check daily profit
    if (g_money_manager.IsDailyProfitTargetReached()) {
        return;
    }

    // 3. Detect signal
    int signal = g_signal_detector.DetectSignal();
    if (signal == SIGNAL_BUY) {
        // 4. Calculate lot size
        double lot_size = g_money_manager.CalculateLotSize(...);

        // 5. Open order
        ulong ticket = g_trade_executor.OpenBuy(...);

        // 6. Update UI
        g_ui_manager.UpdateLossDisplay(...);
    }
}

3.2 Partial Close with Breakeven and Trailing

Test Scenario:

  1. Open buy order with 3 TPs
  2. Price reaches TP1 → Partial close 33.33%, SL to breakeven
  3. Price reaches TP2 → Partial close 33.33%, SL to TP1
  4. Price reaches TP3 → Close remaining 33.34%
  5. Standard trailing activates after all TPs

Expected Result: All partial closes execute correctly, SL moves as expected

Test Steps:

// In OnTick
// 1. Check partial closes
g_partial_close.CheckAndClosePartial(ticket, current_price, tp1, tp2, tp3);

// 2. Manage risk (breakeven + trailing)
g_risk_manager.ManageRiskManagement(ticket, open_price, current_sl, tp1, tp2, tp3);

3.3 State Persistence Across EA Restart

Test Scenario:

  1. EA runs, accumulates $100 loss
  2. EA stopped and restarted
  3. State should persist: $100 loss still tracked

Expected Result: State survives EA restart

Test Steps:

// In OnInit
g_state_manager.LoadState();
double accum_loss = g_state_manager.GetAccumulatedLoss();
Print("Accumulated loss after restart: ", accum_loss);  // Should be 100.0

// In OnDeinit
g_state_manager.SaveState();

3.4 Time Filtering Behavior

Test Scenario:

  1. Enable Monday-Friday only
  2. Test on Sunday → Should not trade
  3. Test on Monday → Should trade
  4. Enable Asian session only
  5. Test during Asian → Should trade
  6. Test during Europe → Should not trade

Expected Result: Time filter works correctly

Test Steps:

// In OnTick
if (!g_time_filter.IsTimeAllowed()) {
    g_logging.LogInfo("Trading not allowed at this time");
    return;
}

3.5 Daily Profit Target Enforcement

Test Scenario:

  1. Set daily profit target to 2%
  2. Account balance $10,000 → Target $200
  3. Make $150 profit → Should continue trading
  4. Make $250 profit → Should stop trading
  5. Next day → Should reset and allow trading

Expected Result: Trading stops when target reached, resets next day

Test Steps:

// In OnTick
if (g_money_manager.IsDailyProfitTargetReached()) {
    g_logging.LogInfo("Daily profit target reached, stopping trading");
    return;
}

4. Backtesting Preparation

4.1 Test Configuration

Symbol: EURUSD Timeframe: H1 Period: 2024-01-01 to 2024-12-31 Model: Every tick Spread: Fixed 10 points

4.2 Input Parameters

Trade_Mode = MODE_INDICATOR
LotSize = 0.03
Slippage = 3
MagicNumber = 24680
TakeScreenshotOnOpen = false
EnableDebugPrints = true
ExitOnOppositeSignal = false

UsePercentBalanceLot = true
PercentOfBalanceForProfit = 1.0
DailyProfitTargetPercent = 2.0

EnableTimeFilter = true
TradingDays = Mon,Tue,Wed,Thu,Fri
AsianSession = true
EuropeSession = true
AmericaSession = true

IndicatorName = "Custom Indicator"
BuySignalBuffer = 0
SellSignalBuffer = 1
BuySLBuffer = 2
BuyTP1Buffer = 3
BuyTP2Buffer = 4
BuyTP3Buffer = 5
SellSLBuffer = 6
SellTP1Buffer = 7
SellTP2Buffer = 8
SellTP3Buffer = 9
ATRPeriod = 14
ATRMultiple = 1.5
MinTPPips = 20

EnableBreakeven = true
BreakevenPips = 10
EnableTPBasedTrailing = true
TPBasedTrailingStep = 30
EnableTrailingStop = true
TrailingStopPips = 15
TrailingStartPips = 30

EnablePartialClose = true
UseEqualDivision = true
PartialClosePercentages = 33.33,33.33,33.34

4.3 Backtesting Checklist

  • Indicator file available in Indicators/ folder
  • Historical data downloaded for test period
  • Spread set correctly
  • Input parameters configured
  • Visual mode enabled for debugging
  • Log file location noted

4.4 Expected Metrics

  • Total trades
  • Win rate
  • Average profit/loss
  • Maximum drawdown
  • Profit factor
  • Sharpe ratio

5. Documentation

5.1 User Guide Sections

  1. Installation

    • Copy files to MetaTrader 5
    • Enable algorithmic trading
    • Allow DLL imports (if needed)
  2. Configuration

    • Input parameters reference
    • Indicator setup
    • Time filter configuration
  3. Operation

    • How to start/stop EA
    • Manual mode usage
    • Monitoring trades
  4. Troubleshooting

    • Common errors and solutions
    • Debug mode usage
    • Log file analysis

5.2 Input Parameters Reference

Create a table with all input parameters:

  • Parameter name
  • Type
  • Default value
  • Description
  • Valid range

5.3 Troubleshooting Guide

Common issues:

  • EA not trading
  • Orders not opening
  • Partial closes not working
  • State not persisting
  • Time filter blocking trades

6. Test Execution Checklist

Phase 1: Pre-Testing

  • All files compiled successfully
  • No errors or warnings
  • Indicator file available
  • Historical data downloaded

Phase 2: Component Tests

  • CLoggingManager tests passed
  • CSignalDetector tests passed
  • CTimeFilter tests passed
  • CMoneyManager tests passed
  • CRiskManager tests passed
  • CPartialCloseManager tests passed
  • CTradeExecutor tests passed
  • CStateManager tests passed
  • CUIManager tests passed

Phase 3: Integration Tests

  • Signal-to-execution flow passed
  • Partial close with breakeven/trailing passed
  • State persistence passed
  • Time filtering passed
  • Daily profit target passed

Phase 4: Backtesting

  • Backtest configuration complete
  • Backtest executed successfully
  • Results analyzed
  • Performance metrics recorded

Phase 5: Documentation

  • User guide created
  • Input parameters reference created
  • Troubleshooting guide created

7. Success Criteria

Compilation

  • 0 errors
  • 0 warnings

Component Tests

  • All 9 components tested
  • All test cases passed
  • No memory leaks

Integration Tests

  • All 5 integration scenarios tested
  • All scenarios passed
  • No unexpected behavior

Backtesting

  • Backtest executed without errors
  • Performance metrics acceptable
  • No critical issues found

Documentation

  • User guide complete
  • Input parameters reference complete
  • Troubleshooting guide complete

8. Next Steps

After testing is complete:

  1. Fix any issues found
  2. Re-test fixes
  3. Finalize documentation
  4. Prepare for deployment
  5. Create release notes

Test Plan Status: Ready for Execution

Last Updated: 2025-01-20