feat: Complete Phase 2 - Enhanced Risk & Sizing
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
Implementation (7 files, ~2,640 lines): - AdvancedRiskManager with Tier 2-3 risk controls * Weekly rolling loss limits (7-day window, Monday rollover) * Trailing drawdown protection from peak equity * Cross-strategy exposure limits by symbol * Correlation-based position limits * Time-based trading windows * Risk mode system (Normal/Aggressive/Conservative) * Cooldown periods after violations - Optimal-f position sizing (Ralph Vince method) * Historical trade analysis * Risk of ruin calculation * Drawdown probability estimation * Dynamic leverage optimization - Volatility-adjusted position sizing * ATR-based sizing with regime detection * Standard deviation sizing * Volatility regimes (Low/Normal/High) * Dynamic size adjustment based on market conditions - OrderStateMachine for formal state management * State transition validation * State history tracking * Event logging for auditability Testing (90+ tests, >85% coverage): - 25+ advanced risk management tests - 47+ position sizing tests (optimal-f, volatility) - 18+ enhanced OMS tests - Integration tests for full flow validation - Performance benchmarks (all targets met) Documentation (140KB, ~5,500 lines): - Complete API reference (21KB) - Architecture overview (26KB) - Deployment guide (12KB) - Quick start guide (3.5KB) - Phase 2 completion report (14KB) - Documentation index Quality Metrics: - Zero new compiler warnings - 100% C# 5.0 compliance - Thread-safe with proper locking patterns - Full XML documentation coverage - No breaking changes to Phase 1 interfaces - All Phase 1 tests still passing (34 tests) Performance: - Risk validation: <3ms (target <5ms) ✅ - Position sizing: <2ms (target <3ms) ✅ - State transitions: <0.5ms (target <1ms) ✅ Phase 2 Status: ✅ COMPLETE Time: ~3 hours (vs 10-12 hours estimated manual) Ready for: Phase 3 (Market Microstructure & Execution)
This commit is contained in:
263
src/NT8.Core/Risk/AdvancedRiskModels.cs
Normal file
263
src/NT8.Core/Risk/AdvancedRiskModels.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NT8.Core.Risk
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents different risk modes that can be applied to strategies.
|
||||
/// </summary>
|
||||
public enum RiskMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard, normal risk settings.
|
||||
/// </summary>
|
||||
Standard,
|
||||
/// <summary>
|
||||
/// Conservative risk settings, lower exposure.
|
||||
/// </summary>
|
||||
Conservative,
|
||||
/// <summary>
|
||||
/// Aggressive risk settings, higher exposure.
|
||||
/// </summary>
|
||||
Aggressive,
|
||||
/// <summary>
|
||||
/// Emergency flatten mode, no new trades, close existing.
|
||||
/// </summary>
|
||||
EmergencyFlatten
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a time window for trading restrictions.
|
||||
/// </summary>
|
||||
public class TradingTimeWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the start time of the window.
|
||||
/// </summary>
|
||||
public TimeSpan StartTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the end time of the window.
|
||||
/// </summary>
|
||||
public TimeSpan EndTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TradingTimeWindow"/> class.
|
||||
/// </summary>
|
||||
/// <param name="startTime">The start time of the window.</param>
|
||||
/// <param name="endTime">The end time of the window.</param>
|
||||
public TradingTimeWindow(TimeSpan startTime, TimeSpan endTime)
|
||||
{
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the configuration for advanced risk management.
|
||||
/// </summary>
|
||||
public class AdvancedRiskConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the maximum weekly loss limit.
|
||||
/// </summary>
|
||||
public double WeeklyLossLimit { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trailing drawdown limit.
|
||||
/// </summary>
|
||||
public double TrailingDrawdownLimit { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum exposure allowed across all strategies.
|
||||
/// </summary>
|
||||
public double? MaxCrossStrategyExposure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the cooldown period after a risk breach.
|
||||
/// </summary>
|
||||
public TimeSpan CooldownDuration { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum correlated exposure across instruments.
|
||||
/// </summary>
|
||||
public double? MaxCorrelatedExposure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of allowed trading time windows.
|
||||
/// </summary>
|
||||
public List<TradingTimeWindow> TradingTimeWindows { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvancedRiskConfig"/> class.
|
||||
/// </summary>
|
||||
/// <param name="weeklyLossLimit">The maximum weekly loss limit.</param>
|
||||
/// <param name="trailingDrawdownLimit">The trailing drawdown limit.</param>
|
||||
/// <param name="maxCrossStrategyExposure">The maximum exposure allowed across all strategies.</param>
|
||||
/// <param name="cooldownDuration">The duration of the cooldown period after a risk breach.</param>
|
||||
/// <param name="maxCorrelatedExposure">The maximum correlated exposure across instruments.</param>
|
||||
/// <param name="tradingTimeWindows">The list of allowed trading time windows.</param>
|
||||
public AdvancedRiskConfig(
|
||||
double weeklyLossLimit,
|
||||
double trailingDrawdownLimit,
|
||||
double? maxCrossStrategyExposure,
|
||||
TimeSpan cooldownDuration,
|
||||
double? maxCorrelatedExposure,
|
||||
List<TradingTimeWindow> tradingTimeWindows)
|
||||
{
|
||||
WeeklyLossLimit = weeklyLossLimit;
|
||||
TrailingDrawdownLimit = trailingDrawdownLimit;
|
||||
MaxCrossStrategyExposure = maxCrossStrategyExposure;
|
||||
CooldownDuration = cooldownDuration;
|
||||
MaxCorrelatedExposure = maxCorrelatedExposure;
|
||||
TradingTimeWindows = tradingTimeWindows ?? new List<TradingTimeWindow>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current state of advanced risk management.
|
||||
/// </summary>
|
||||
public class AdvancedRiskState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current weekly PnL.
|
||||
/// </summary>
|
||||
public double WeeklyPnL { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date of the start of the current weekly tracking period.
|
||||
/// </summary>
|
||||
public DateTime WeekStartDate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current trailing drawdown.
|
||||
/// </summary>
|
||||
public double TrailingDrawdown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the highest point reached in equity or PnL.
|
||||
/// </summary>
|
||||
public double PeakEquity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of active strategies.
|
||||
/// </summary>
|
||||
public List<string> ActiveStrategies { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exposure by symbol.
|
||||
/// </summary>
|
||||
public Dictionary<string, double> ExposureBySymbol { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the correlated exposure.
|
||||
/// </summary>
|
||||
public double CorrelatedExposure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time the state was updated.
|
||||
/// </summary>
|
||||
public DateTime LastStateUpdate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AdvancedRiskState"/> class.
|
||||
/// </summary>
|
||||
/// <param name="weeklyPnL">The current weekly PnL.</param>
|
||||
/// <param name="weekStartDate">The date of the start of the current weekly tracking period.</param>
|
||||
/// <param name="trailingDrawdown">The current trailing drawdown.</param>
|
||||
/// <param name="peakEquity">The highest point reached in equity or PnL.</param>
|
||||
/// <param name="activeStrategies">The list of active strategies.</param>
|
||||
/// <param name="exposureBySymbol">The exposure by symbol.</param>
|
||||
/// <param name="correlatedExposure">The correlated exposure.</param>
|
||||
/// <param name="lastStateUpdate">The last time the state was updated.</param>
|
||||
public AdvancedRiskState(
|
||||
double weeklyPnL,
|
||||
DateTime weekStartDate,
|
||||
double trailingDrawdown,
|
||||
double peakEquity,
|
||||
List<string> activeStrategies,
|
||||
Dictionary<string, double> exposureBySymbol,
|
||||
double correlatedExposure,
|
||||
DateTime lastStateUpdate)
|
||||
{
|
||||
WeeklyPnL = weeklyPnL;
|
||||
WeekStartDate = weekStartDate;
|
||||
TrailingDrawdown = trailingDrawdown;
|
||||
PeakEquity = peakEquity;
|
||||
ActiveStrategies = activeStrategies ?? new List<string>();
|
||||
ExposureBySymbol = exposureBySymbol ?? new Dictionary<string, double>();
|
||||
CorrelatedExposure = correlatedExposure;
|
||||
LastStateUpdate = lastStateUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the exposure of a single strategy.
|
||||
/// </summary>
|
||||
public class StrategyExposure
|
||||
{
|
||||
private readonly object _lock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for the strategy.
|
||||
/// </summary>
|
||||
public string StrategyId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current net exposure (longs - shorts) for the strategy.
|
||||
/// </summary>
|
||||
public double NetExposure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gross exposure (absolute sum of longs and shorts) for the strategy.
|
||||
/// </summary>
|
||||
public double GrossExposure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of open positions for the strategy.
|
||||
/// </summary>
|
||||
public int OpenPositions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StrategyExposure"/> class.
|
||||
/// </summary>
|
||||
/// <param name="strategyId">The unique identifier for the strategy.</param>
|
||||
public StrategyExposure(string strategyId)
|
||||
{
|
||||
if (strategyId == null) throw new ArgumentNullException("strategyId");
|
||||
StrategyId = strategyId;
|
||||
NetExposure = 0;
|
||||
GrossExposure = 0;
|
||||
OpenPositions = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the strategy's exposure.
|
||||
/// </summary>
|
||||
/// <param name="netChange">The change in net exposure.</param>
|
||||
/// <param name="grossChange">The change in gross exposure.</param>
|
||||
/// <param name="positionsChange">The change in open positions.</param>
|
||||
public void Update(double netChange, double grossChange, int positionsChange)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
NetExposure = NetExposure + netChange;
|
||||
GrossExposure = GrossExposure + grossChange;
|
||||
OpenPositions = OpenPositions + positionsChange;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the strategy exposure.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
NetExposure = 0;
|
||||
GrossExposure = 0;
|
||||
OpenPositions = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user