2026-07-18 15:53:04 -04:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Warrior_EA |
|
|
|
|
|
//| AnimateDread |
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "MoneyRiskBase.mqh"
|
|
|
|
|
#include "..\Variables\ConfidenceBridge.mqh"
|
2026-07-18 17:39:58 -04:00
|
|
|
// Quarter-Kelly: only a quarter of the theoretical edge-optimal fraction is ever applied.
|
|
|
|
|
// Full Kelly is well documented as too volatile for live capital; quarter-Kelly is a
|
|
|
|
|
// conservative institutional default, deliberately chosen here for prop-firm-evaluation-style
|
|
|
|
|
// accounts that also carry hard daily-loss/drawdown limits (Signals\SignalRiskGuard.mqh).
|
|
|
|
|
#define KELLY_FRACTION_MULTIPLIER 0.25
|
|
|
|
|
// Floor so a thin/negative-edge estimate never scales risk% all the way to zero on a trade
|
|
|
|
|
// that already passed the signal's own entry threshold and Min_Risk_Reward_Ratio filter -
|
|
|
|
|
// it only ever gets sized down to a minimum, never fully skipped by Money.
|
|
|
|
|
#define KELLY_MIN_RISK_FRACTION 0.1
|
2026-07-18 15:53:04 -04:00
|
|
|
class CMoneyIntelligent : public CMoneyRiskBase
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2026-07-18 17:39:58 -04:00
|
|
|
bool m_use_ai_lot; // true: scale risk % via the Kelly criterion below
|
2026-07-18 15:53:04 -04:00
|
|
|
int m_confidence_source; // CONFIDENCE_SOURCE underlying int (0=AI, 1=DB, 2=Blended)
|
|
|
|
|
public:
|
|
|
|
|
// Constructor
|
2026-07-18 17:39:58 -04:00
|
|
|
CMoneyIntelligent() : m_use_ai_lot(false), m_confidence_source(0) {}
|
2026-07-18 15:53:04 -04:00
|
|
|
|
|
|
|
|
void UseAIConfidenceLotSizing(bool value) { m_use_ai_lot = value; }
|
|
|
|
|
void ConfidenceSource(int value) { m_confidence_source = value; }
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
//--- CMoneyRiskBase::CalculateLotSize() hook - see CMoneyRiskBase's declaration comment.
|
|
|
|
|
virtual double AdjustRiskAmount(double riskAmount) override;
|
|
|
|
|
};
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-07-18 17:39:58 -04:00
|
|
|
//| Kelly-criterion risk% scaling - only active when Use_AI_Lot_Sizing|
|
|
|
|
|
//| is on. Unifies what used to be two disconnected mechanisms (a |
|
|
|
|
|
//| linear confidence-only scale here, plus an unrelated trade- |
|
|
|
|
|
//| history streak multiplier in a since-removed AdjustLotSize() |
|
|
|
|
|
//| override) into a single edge-based model that uses everything |
|
|
|
|
|
//| the NN and the trade's own risk math already know: |
|
|
|
|
|
//| p = estimated win probability, derived from the empirically |
|
|
|
|
|
//| calibrated AI/DB confidence magnitude (see |
|
|
|
|
|
//| ExpertSignalAIBase::CalibratedConfidenceMagnitude()'s |
|
|
|
|
|
//| m_confidenceCalScale - it's scaled against real OOS accuracy,|
|
|
|
|
|
//| not a raw uncalibrated softmax value) mapped from [0,1] onto |
|
|
|
|
|
//| [0.5,1.0] - zero confidence is a coin flip, full confidence |
|
|
|
|
|
//| is treated as near-certain. |
|
|
|
|
|
//| b = this specific trade's real reward:risk ratio, bridged from |
|
|
|
|
|
//| CExpertSignalCustom::OpenParams() via g_TradeRewardRiskRatio |
|
|
|
|
|
//| (Variables\ConfidenceBridge.mqh) - always >= Min_Risk_Reward |
|
|
|
|
|
//| _Ratio, since OpenParams() rejects thinner setups before |
|
|
|
|
|
//| Money is ever consulted. |
|
|
|
|
|
//| f* = p - (1-p)/b is the Kelly-optimal fraction; only |
|
|
|
|
|
//| KELLY_FRACTION_MULTIPLIER of it is used (see its own comment), |
|
|
|
|
|
//| then clamped to [KELLY_MIN_RISK_FRACTION, 1.0] so this can only |
|
|
|
|
|
//| ever scale the configured Money_Risk_Percent DOWN from its input |
|
|
|
|
|
//| ceiling, never above it - the same invariant this method has |
|
|
|
|
|
//| always guaranteed. |
|
2026-07-18 15:53:04 -04:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
double CMoneyIntelligent::AdjustRiskAmount(double riskAmount)
|
|
|
|
|
{
|
|
|
|
|
if(!m_use_ai_lot)
|
|
|
|
|
return riskAmount;
|
2026-07-18 17:39:58 -04:00
|
|
|
if(g_TradeRewardRiskRatio <= 0.0)
|
|
|
|
|
return riskAmount * KELLY_MIN_RISK_FRACTION; // bridge not populated yet - defensive floor
|
2026-07-18 15:53:04 -04:00
|
|
|
double confidence = CombinedConfidence(m_confidence_source);
|
2026-07-18 17:39:58 -04:00
|
|
|
double p = 0.5 + 0.5 * confidence;
|
|
|
|
|
double b = g_TradeRewardRiskRatio;
|
|
|
|
|
double fKelly = MathMax(0.0, MathMin(1.0, p - (1.0 - p) / b));
|
|
|
|
|
double fraction = MathMax(KELLY_MIN_RISK_FRACTION, MathMin(1.0, fKelly * KELLY_FRACTION_MULTIPLIER));
|
|
|
|
|
return riskAmount * fraction;
|
2026-07-18 15:53:04 -04:00
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|