Skip to main content
NOVOSKY uses 56 features for the signal model and 60 for the position model (56 + 4 position-state features). Feature order is sacred. The StandardScaler and all models require this exact column order as defined in ml_config.json → "features". Never reorder without retraining.

Protected features

These features show near-zero SHAP importance at training time because the Forex Factory calendar only covers the current week — 99.9% of the 2-year training history sees zeros. At inference time, trading.py overwrites them with live values every cycle. Never drop these based on SHAP analysis:
  • is_news_near
  • news_minutes_away
  • news_count_today
  • is_news_risk_window
  • is_london_session
  • is_ny_session
  • is_asian_session

Phase 15 SHAP top features

Top features by SHAP importance at the current phase: h4_rsi_norm, h1_rsi_norm, price_vs_ema50, m30_trend, price_vs_ema200

Full feature reference

#FeatureCategoryWhat it encodes
1bb_upperVolatilityBollinger Band upper level
2bb_lowerVolatilityBollinger Band lower level
3range_positionPrice actionPrice position in 24h range
4price_vs_ema200TrendLong-term trend bias
5atr_14VolatilityVolatility magnitude in $
6drawdown_pctPrice actionDrawdown from recent high
7bb_widthVolatilityBollinger Band width (volatility regime)
8trend_strengthTrendADX-like directional strength
9macd_signalMomentumMACD signal line
10macd_lineMomentumMACD line
11volume_ratioVolumeVolume vs 20-bar average
12price_vs_ema50TrendMedium-term EMA position
13price_vs_ema20TrendShort-term EMA position
14rsi_14MomentumRSI overbought/oversold
15hourly_returnPrice action1-bar return
16daily_range_positionPrice action24h range position
17ema_stackTrendEMA20/50/200 alignment (−1/0/+1)
18candle_directionPrice actionBody/ATR signed ratio
19volume_deltaVolumeBull vs bear volume imbalance
20rsi_slopeMomentumRSI momentum over 5 candles
21consecutive_directionPrice actionConsecutive same-direction candles
22session_hour_sinTimeCyclical time of day (sin)
23session_hour_cosTimeCyclical time of day (cos)
24is_london_sessionSession1 during London session — protected
25is_ny_sessionSession1 during New York session — protected
26atr_percentileVolatilityATR rank in 30-day window
27volume_surgeVolumeVolume spike capped at 5×
28dist_to_round_numberPrice actionDistance to nearest $1,000 BTC level
29near_daily_high_lowPrice actionNear 24h extreme (−1/0/+1)
30h4_ema_biasMulti-timeframeH4 EMA stack direction
31h4_rsi_normMulti-timeframeH4 RSI14 normalized [−1, +1]
32h4_macd_dirMulti-timeframeH4 MACD direction
33d1_trendMulti-timeframeD1 price vs EMA20
34price_vs_d1_openMulti-timeframeH1 close vs daily open
35adx_14TrendWilder’s ADX normalized 0–1 (not 0–100)
36bb_squeezeVolatilityBB width at rolling 20-period low
37price_accelerationMomentum2nd derivative of price
38market_qualityCompositeATR_pct × trend_strength
39momentum_decayMomentumRSI/price divergence
40adverse_candle_ratioPrice action5-bar choppiness (0=trend, 1=chop)
41is_news_nearNews1 if high-impact FF event within ±30 min — protected
42news_minutes_awayNewsMinutes to next event (999 = none) — protected
43news_count_todayNewsHigh-impact event count today (UTC) — protected
44day_of_week_sinTimeCyclical day-of-week (sin)
45day_of_week_cosTimeCyclical day-of-week (cos)
46is_news_risk_windowNewsWed/Fri FOMC/NFP proxy — protected
47is_asian_sessionSession1 during 00:00–09:00 UTC — protected
48spread_normMarketBroker spread as fraction of price
49m30_trendMulti-timeframeM30 price vs M30 EMA20 (−1/0/+1)
50m30_rsi_normMulti-timeframeM30 RSI14 normalized [−1, +1]
51h1_ema_biasMulti-timeframeH1 EMA20/50 stack
52h1_rsi_normMulti-timeframeH1 RSI14 normalized [−1, +1]
53h1_macd_dirMulti-timeframeH1 MACD direction
54news_surpriseNewsNews impact vs expectation
55bars_since_newsNewsBars elapsed since last FF event

ADX normalization

adx_14 is normalized to 0–1, not the traditional 0–100 scale. Any ADX-related filter must use the normalized scale:
"adx_regime_filter": {
  "min_adx": 0.20   // = traditional ADX 20. Passing 20 blocks ALL trades.
}

Position model features (+4)

The position model takes the 56 features above plus these 4 position-state features:
FeatureDescription
bars_held_normNormalized number of M15 bars the position has been open
pnl_pctUnrealized P/L as % of entry price (signed: positive = profit)
r_multipleUnrealized P/L in units of initial SL distance
pos_direction+1.0 for BUY, −1.0 for SELL

Risk model features (7 equity-state)

The risk multiplier model does not use the 56 signal features. It uses a separate set of 7 equity-state features computed from the live account equity curve. These are passed to RiskPredictor.get_multiplier() each cycle before lot sizing.
Feature order here matches ml/risk_predictor.py RISK_FEATURES and ml_config.json → risk_model.features. These must stay in sync — the Three-File Rule applies.
#FeatureWhat it measures
1equity_ratioCurrent equity / starting equity (1.0 = no loss, 0.8 = down 20%)
2drawdown_from_peak(Peak equity − current equity) / peak equity
3rolling_wr_10Win rate of the last 10 closed trades
4rolling_wr_20Win rate of the last 20 closed trades
5rolling_pf_10Profit factor of the last 10 closed trades
6consecutive_lossesCurrent consecutive loss streak (integer)
7atr_normATR at entry / entry price (volatility as fraction of price)
The model output — a multiplier in [0.10, 1.25] — is applied as:
effective_risk_pct = base_risk_pct × multiplier
It never changes SL/TP or confidence thresholds. If the model files are missing, multiplier defaults to 1.0.