| //+------------------------------------------------------------------+
|
| //| MarketContext.mqh |
|
| //| AnimateDread |
|
| //| |
|
| //| WHAT THE TRADER SAW WHEN THEY PRESSED THE BUTTON. |
|
| //| |
|
| //| One fixed-width record of every modality's reading at the signal |
|
| //| bar. It is the single source of truth for three consumers that |
|
| //| used to be three hand-kept lists: the modalities WRITE it, the |
|
| //| trade book PERSISTS it (header and row both come from CtxName()), |
|
| //| and the reviewer BUCKETS it. Add a field once, here, and all |
|
| //| three follow; nothing else spells a column name. |
|
| //| |
|
| //| CTX_NA marks a reading the modality could not produce. It is |
|
| //| never zero: a missing Wyckoff read must not look like "phase 0". |
|
| //+------------------------------------------------------------------+
|
| #ifndef WARRIOR_MARKETCONTEXT_MQH
|
| #define WARRIOR_MARKETCONTEXT_MQH
|
|
|
| #define CTX_NA (-999.0)
|
|
|
| enum ENUM_CTX
|
| {
|
| //--- price shape (ModalityPrice)
|
| CTX_Z = 0, // z-score(20) of the close
|
| CTX_DIST_ATR, // (close - SMA20) / ATR
|
| CTX_RET1_ATR, // last bar's return, in ATR
|
| CTX_DROP5_ATR, // 5-bar return, in ATR
|
| CTX_RANGE_ATR, // bar range, in ATR
|
| CTX_CLOSE_LOC, // where the close sat in its own range, 0..1
|
| CTX_ER, // efficiency ratio (20)
|
| CTX_VR, // variance ratio (60, 5)
|
| CTX_REGIME, // 0 chop / 1 trend / 2 mean-revert
|
| //--- volatility (ModalityPrice)
|
| CTX_VOL_PCT, // expanding-window percentile of Garman-Klass sigma(30)
|
| CTX_ATR_RATIO, // ATR / mean ATR of the last 100 bars
|
| //--- volume, clock removed (ModalityVolume)
|
| CTX_RVOL, // ln(tick volume / same-hour median), level-detrended
|
| CTX_RVOL_RAW, // the same without the detrend
|
| CTX_ABSORB, // effort minus result: rvol - ln(range/ATR). High = volume without progress
|
| //--- Wyckoff structure (ModalityWyckoff)
|
| CTX_WYK_OK, // 1 when the indicators answered
|
| CTX_WYK_PHASE, // phase * direction: +-1..5 = A..E
|
| CTX_WYK_EVENT, // last event within the look-back, signed code (+-1..9)
|
| CTX_WYK_AGE, // bars since that event
|
| CTX_WYK_SPRING, // strongest spring/UTAD grade within the look-back, signed
|
| CTX_WYK_CHAR, // +1 accumulation / -1 distribution / 0 not anchored
|
| CTX_WYK_RANGEPOS, // close inside the open range, 0..1 (NA when no range is open)
|
| CTX_WYK_FAIL, // failed-structure quality, signed
|
| CTX_WYK_BIAS, // the reader's verdict for a LONG, -1..+1
|
| //--- cross-index breadth (ModalityBreadth)
|
| CTX_BREADTH_N, // peers that answered
|
| CTX_BREADTH, // fraction of them at z(20) <= -1
|
| //--- calendar (ModalityCalendar)
|
| CTX_DOW,
|
| CTX_HOUR,
|
| CTX_DOM, // day of month
|
| CTX_TO_MONTH_END, // calendar days to month end
|
| CTX_N
|
| };
|
|
|
| string CtxName(const int i)
|
| {
|
| switch(i)
|
| {
|
| case CTX_Z: return "z20";
|
| case CTX_DIST_ATR: return "dist_sma_atr";
|
| case CTX_RET1_ATR: return "ret1_atr";
|
| case CTX_DROP5_ATR: return "ret5_atr";
|
| case CTX_RANGE_ATR: return "range_atr";
|
| case CTX_CLOSE_LOC: return "close_loc";
|
| case CTX_ER: return "er20";
|
| case CTX_VR: return "vr60_5";
|
| case CTX_REGIME: return "regime";
|
| case CTX_VOL_PCT: return "vol_pct";
|
| case CTX_ATR_RATIO: return "atr_ratio";
|
| case CTX_RVOL: return "rvol_tod";
|
| case CTX_RVOL_RAW: return "rvol_tod_raw";
|
| case CTX_ABSORB: return "absorb";
|
| case CTX_WYK_OK: return "wyk_ok";
|
| case CTX_WYK_PHASE: return "wyk_phase";
|
| case CTX_WYK_EVENT: return "wyk_event";
|
| case CTX_WYK_AGE: return "wyk_event_age";
|
| case CTX_WYK_SPRING: return "wyk_spring";
|
| case CTX_WYK_CHAR: return "wyk_char";
|
| case CTX_WYK_RANGEPOS: return "wyk_range_pos";
|
| case CTX_WYK_FAIL: return "wyk_fail";
|
| case CTX_WYK_BIAS: return "wyk_bias";
|
| case CTX_BREADTH_N: return "breadth_n";
|
| case CTX_BREADTH: return "breadth";
|
| case CTX_DOW: return "dow";
|
| case CTX_HOUR: return "hour";
|
| case CTX_DOM: return "dom";
|
| case CTX_TO_MONTH_END: return "to_month_end";
|
| }
|
| return "?";
|
| }
|
|
|
| struct SMarketContext
|
| {
|
| datetime bar; // open time of the signal bar
|
| double v[CTX_N];
|
| string story; // the same reading, as a trader would say it
|
|
|
| void Reset(const datetime t)
|
| {
|
| bar = t;
|
| story = "";
|
| for(int i = 0; i < CTX_N; i++)
|
| v[i] = CTX_NA;
|
| }
|
| bool Has(const int f) const { return v[f] != CTX_NA; }
|
| };
|
|
|
| //--- The CSV columns for a context, in field order. Header and row are built from the same loop,
|
| //--- so they cannot disagree about width or order.
|
| string CtxHeader(void)
|
| {
|
| string h = "";
|
| for(int i = 0; i < CTX_N; i++)
|
| h += (i > 0 ? "," : "") + CtxName(i);
|
| return h;
|
| }
|
|
|
| string CtxRow(const SMarketContext &c)
|
| {
|
| string r = "";
|
| for(int i = 0; i < CTX_N; i++)
|
| r += (i > 0 ? "," : "") + DoubleToString(c.v[i], 5);
|
| return r;
|
| }
|
| #endif // WARRIOR_MARKETCONTEXT_MQH
|