| TIME | USER | TIER | ACTION | OBJECT |
|---|---|---|---|---|
| 14:31 | eric.nguyen | T2 | backtest.run | vn30f-mom-v2 · spec@v1.4 |
| 14:08 | c.le | T3 | signal.approve | vnindex-breadth-osc → production |
| 13:55 | huyen.pham | T1 | data.query | vn30 daily 2024-01..2026-05 |
| 13:42 | tan.do | T2 | signal.create | btc-perp-basis-z (dev) |
| 13:11 | eric.nguyen | T2 | tearsheet.export | vn100-port-rebal · run_id 8a9c |
| 12:55 | khoa.tran | T2 | wiki.interview | model: vnindex-long · 90 min |
| 12:14 | data-eng-bot | SVC | data.ingest | hose intraday 1m · 248k rows |
| 11:48 | huyen.pham | T1 | signal.read | vn30f-mom-v2 (name+desc only) |
| 11:02 | c.le | T3 | access.grant | tan.do : T1→T2 |
| 10:30 | eric.nguyen | T2 | spec.commit | vn30f-mom-v2 spec → v1.4 |
| NAME | MARKET | SCHEMA | FREQ | COVERAGE | ROWS | LAST INGEST | QC | PIT | OWNER |
|---|---|---|---|---|---|---|---|---|---|
| vn.equities.bars.daily | VN | v3 | 1D | 2010-01-04 → 2026-05-14 | 14,802,318 | 05:12 | PASS | PIT | data-eng |
| vn.equities.bars.intraday | VN | v2 | 1m | 2022-01-04 → 2026-05-14 | 3,940,128,442 | 15:01 | PASS | PIT | data-eng |
| vn.equities.fundamentals | VN | v4 | Q | 2010Q1 → 2026Q1 | 128,402 | 02:00 | PASS | PIT/AS-REP | data-eng |
| vn.equities.corp_actions | VN | v2 | EVENT | 2010 → live | 28,941 | 04:30 | PASS | PIT | data-eng |
| vn.equities.foreign_room | VN | v1 | 1D | 2015 → live | 2,408,112 | 04:45 | WARN | PIT | data-eng |
| vn.equities.ceiling_floor | VN | v1 | 1D | 2010 → live | 14,792,000 | 05:18 | PASS | PIT | data-eng |
| vn.indices.membership | VN | v2 | EVENT | 2012 → live | 418 | 06:00 | PASS | PIT/SURV-FREE | quant-po |
| vn.derivs.vn30f.bars | VN | v1 | 1m | 2017 → live | 241,890,200 | 15:01 | PASS | PIT | data-eng |
| crypto.spot.binance | XCRY | v3 | 1m | 2018 → live | 12,408,109,221 | 14:59 | PASS | PIT | data-eng |
| crypto.spot.okx | XCRY | v3 | 1m | 2019 → live | 9,108,228,001 | 14:59 | PASS | PIT | data-eng |
| crypto.spot.bybit | XCRY | v2 | 1m | 2020 → live | 7,418,022,910 | 14:59 | WARN | PIT | data-eng |
| crypto.perp.funding | XCRY | v2 | 8h | 2019 → live | 7,802,180 | 14:00 | PASS | PIT | data-eng |
| ref.calendar.vn | VN | v1 | STATIC | 2010 → 2030 | 7,305 | — | PASS | STATIC | platform-po |
| fx.usd.vnd | FX | v1 | 1D | 2010 → live | 5,840 | 06:00 | PASS | PIT | data-eng |
# pip install qrp-client==0.4.2 from qrp import data, auth auth.login() # SSO via Keycloak; token stored in ~/.qrp/ # Point-in-time query — survivorship-bias free, look-ahead free df = data.bars( universe="vn30", fields=["open","close","volume","foreign_room"], start="2024-01-01", end="2026-05-14", freq="1d", asof="2026-05-14", # PIT replay: data as known on this date snapshot_id="snap-2026-05-14T05:18Z", ) # Two researchers running this exact call get byte-identical results. # Query logged: user=eric.nguyen dataset=vn.equities.bars.daily rows=14802 # Crypto cross-venue with funding btc = data.bars(symbols=["BTCUSDT"], venues=["binance","okx","bybit"], fields=["close","funding_8h"], freq="1h") # Source reconciliation — both raw values + canonical resolution recon = data.reconciliation(symbol="MSB", date="2026-05-14") # → {ssi: 12450.0, dnse: 12455.0, canonical: 12450.0, rule: "prefer_ssi"}
| SYMBOL | FIELD | SOURCE A | VALUE A | SOURCE B | VALUE B | Δ BPS | RULE | CANONICAL | STATUS |
|---|---|---|---|---|---|---|---|---|---|
| MSB | close | SSI | 12,450.00 | DNSE | 12,455.00 | +4.0 | prefer_ssi | 12,450.00 | REVIEW |
| VJC | close | SSI | 98,200.00 | VND | 98,200.00 | 0.0 | prefer_ssi | 98,200.00 | OK |
| VHM | foreign_room | HOSE | 412,082,118 | SSI | 412,080,118 | ±0.0 | prefer_hose | 412,082,118 | OK |
| BTCUSDT | close.1m@14:30 | BINANCE | 71,238.50 | OKX | 71,251.00 | +1.7 | vwap_3venue | 71,243.10 | OK |
| SOLUSDT | funding | BINANCE | +0.0102% | BYBIT | +0.0118% | +15.6% | venue_native | venue_native | OK |
| FPT | div_announce | HOSE | 2026-05-21 | FIINPRO | 2026-05-22 | date | prefer_hose | 2026-05-21 | REVIEW |
strategy: name: vn30f-mom-v2 market: vn-derivatives version: 1.4.0 author: eric.nguyen spec_schema: 1.4 universe: instrument: VN30F1M # nearest-month future roll: 5d_before_expiry signals: # refs into P3 signal library; pinned by version - id: vn30.momo.20d version: 2.1.0 - id: vn30.breadth.osc version: 1.0.4 - id: vnindex.regime version: 1.2.0 entry: long_when: "momo_20d > 0 AND breadth_osc > 0.55 AND regime != 'bear'" short_when: "momo_20d < 0 AND breadth_osc < 0.45" exit: stop_loss: 2.0% take_profit: 5.5% time_stop: 10d sizing: method: vol_target target_vol: 12% leverage_cap: 2.0 costs: # VN derivatives realistic cost model commission_bp: 0.4 tax_bp: 0.3 slippage_model: vwap_pct_adv slippage_pct_adv: 0.05 capital: initial: 5e9 VND capacity_check: true # warn if size > 0.5% ADV backtest: start: 2018-01-01 end: 2026-04-30 data_snapshot_id: snap-2026-05-01T05:00Z walk_forward: true oos_split: 0.3
| RUN_ID | STRATEGY | USER | SHARPE | CAGR | MAX DD | SNAPSHOT | STATUS |
|---|---|---|---|---|---|---|---|
| 8a9c3f12 | vn30f-mom-v2 @ 1.4 | eric.nguyen | 1.84 | +22.4% | -11.8% | snap-05-01 | DONE |
| 8a9c2e88 | vn30f-mom-v2 @ 1.3 | eric.nguyen | 1.62 | +19.1% | -13.2% | snap-05-01 | DONE |
| 8a9c1d04 | vn100-port-rebal | tan.do | 1.41 | +17.8% | -9.4% | snap-05-01 | DONE |
| 8a9c0a91 | vnindex-long | eric.nguyen | 1.28 | +15.2% | -14.0% | snap-05-01 | DONE |
| 8a9bf208 | btc-funding-fade | c.le | 2.04 | +38.1% | -18.7% | snap-04-30 | DONE |
| 8a9be7c1 | vn30-port-defensive | khoa.tran | 0.94 | +9.8% | -7.2% | snap-04-30 | DONE |
| 8a9bd520 | vn30f-mom-v2 @ 1.2 | eric.nguyen | — | — | — | snap-04-29 | FAIL |
| 8a9bc91e | eth-basis-spread | tan.do | 1.71 | +24.0% | -12.1% | snap-04-29 | DONE |
| VaR 95% (1d) | -1.18% | parametric |
| VaR 99% (1d) | -1.92% | parametric |
| CVaR 95% (1d) | -1.71% | expected shortfall |
| Skew | +0.18 | positive tail |
| Excess kurtosis | 2.84 | fat-tailed |
| Worst day | -3.41% | 2022-05-12 |
| Worst week | -6.72% | 2022-W19 |
| Calmar | 1.90 | cagr / |maxdd| |
| Annual turnover | 412% |
| Avg holding period | 6.4 days |
| Capacity estimate | ~80B VND |
| Cost drag · commission | -1.8%/yr |
| Cost drag · tax | -1.4%/yr |
| Cost drag · slippage | -2.2%/yr |
| Total cost drag | -5.4%/yr |
| REGIME | DAYS | SHARPE | CAGR | HIT |
|---|---|---|---|---|
| BULL | 812 | 2.42 | +34.1% | 62% |
| SIDEWAYS | 948 | 0.84 | +8.4% | 52% |
| BEAR | 421 | 1.62 | +18.7% | 59% |
run_id: 8a9c3f12-1f4d-4a02-9c41-aa018d git_sha: a1b2c3d4e5f6789012345678901234567890abcd spec_hash: sha256:9f8a02... spec_path: strategies/vn30f-mom-v2/spec.yaml@v1.4.0 data_snapshot_id: snap-2026-05-01T05:00:00Z image: qrp/backtester:0.4.2-py3.11 started_at: 2026-05-15T14:31:08Z finished_at: 2026-05-15T14:33:42Z walltime_sec: 154 workers: 8 determinism: byte-identical replay verified ✓ # Re-run anytime: qrp bt replay 8a9c3f12 → identical bytes
| SIGNAL ID | FAMILY | MARKET | VER | STATUS | AUTHOR | USED BY | DECAY (BARS→0.5α) | MAX |ρ| | UPDATED |
|---|---|---|---|---|---|---|---|---|---|
| vn30.momo.20d | momentum | VN | 2.1.0 | PROD | eric.nguyen | 3 strats | 28 | 0.42 | 2026-04-22 |
| vn30.breadth.osc | breadth | VN | 1.0.4 | PROD | c.le | 2 strats | 14 | 0.31 | 2026-03-18 |
| vnindex.regime | regime | VN | 1.2.0 | PROD | c.le | 5 strats | 62 | 0.18 | 2026-02-04 |
| vn100.qual.composite | quality | VN | 3.0.1 | PROD | khoa.tran | 2 strats | 220 | 0.27 | 2026-01-30 |
| vn.flow.foreign.5d | flow | VN | 1.1.2 | PROD | tan.do | 2 strats | 9 | 0.38 | 2026-04-08 |
| vn.value.ev_ebitda.qcz | value | VN | 2.2.0 | PROD | khoa.tran | 1 strat | 410 | 0.22 | 2026-01-12 |
| btc.funding.zscore.8h | funding | XCRY | 1.4.0 | PROD | c.le | 1 strat | 12 | 0.46 | 2026-04-29 |
| btc.basis.perp_spot | basis | XCRY | 1.0.2 | STAGE | tan.do | staging | 7 | 0.51 | 2026-05-02 |
| eth.depth.imbalance.1m | microstructure | XCRY | 0.3.1 | DEV | tan.do | research | 2 | 0.61 | 2026-05-11 |
| vn.macro.ndr.curve | macro | VN | 0.1.0 | DEV | khoa.tran | research | — | — | 2026-05-09 |
| vn.flow.proprietary.X | flow | VN | — | RETIRED | c.le | none | — | — | 2024-09-12 |
# vn30.momo.20d @ 2.1.0 — 20-day price momentum, vol-normalized def compute(bars: DataFrame) -> Series: px = bars["close"].adjust("corp_actions") # PIT-adjusted ret_20 = px.pct_change(20) vol_20 = bars["close"].pct_change().rolling(20).std() return (ret_20 / (vol_20 * math.sqrt(20))).clip(-3, 3)
| vn30.momo.20d | price momentum (assigned) |
| ██████████ | ██████ ██████ |
| ██████████ | ██████ ██████ |
| ██████████ | ██████ ██████ |
| vn30.momo.20d | full formula + decay + ρ matrix |
| vn30.breadth.osc | full formula + decay + ρ matrix |
| btc.funding.zscore | full formula + decay + ρ matrix |
| vnindex.regime | full formula + decay + ρ matrix |
| all of T2 | + deployment approval |
| access.grant | tan.do : T1→T2 (today) |
| access.revoke | immediate effect |
| deal financials | SPV / Q-capital cap table |
| MODEL | STATUS | MARKET | OWNER | HYP | SIG-DEF | DATA-DEPS | RULES | PERF | FAILURE | % |
|---|---|---|---|---|---|---|---|---|---|---|
| vnindex-long | LIVE | VN | eric.nguyen | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 100% |
| vn30f-mom-v2 | LIVE | VN | eric.nguyen | ✓ | ✓ | ✓ | ✓ | ✓ | … | 90% |
| vn100-port-rebal | LIVE | VN | tan.do | ✓ | ✓ | ✓ | ✓ | ✓ | … | 88% |
| vn30-port-defensive | LIVE | VN | khoa.tran | ✓ | ✓ | ✓ | ✓ | … | ✗ | 70% |
| btc-funding-fade | LIVE | XCRY | c.le | ✓ | ✓ | … | ✗ | ✗ | ✗ | 38% |
| eth-basis-spread | STAGE | XCRY | tan.do | ✓ | ✓ | ✓ | ✓ | … | … | 78% |
| vn.flow.proprietary.X | RETIRED | VN | c.le | … | ✗ | ✗ | ✗ | ✗ | ✗ | 14% |
| vn30-pairs-mean-rev | PAUSED | VN | khoa.tran | ✓ | ✓ | … | … | ✗ | ✗ | 48% |
Hypothesis & economic rationale. VNINDEX exhibits persistent positive drift in regimes characterized by (a) breadth above the 200-day median and (b) foreign-room buy pressure positive over 5 days. Drift compensates risk-takers when cross-sectional dispersion is low — a structural feature of a frontier market with concentrated institutional flow.
Signal definition. See vnindex.regime @ 1.2.0 + vn.flow.foreign.5d @ 1.1.2. Composite long-only score; threshold ≥ 0.55 enters, < 0.40 exits.
Data dependencies. vn.indices.membership v2 (PIT, survivorship-free), vn.equities.foreign_room v1, vn.equities.bars.daily v3.
Universe & filters. VNINDEX (cash equity proxy, no derivative). Excluded: index-add days T-1..T+1 to avoid mechanical noise.
Entry / exit / sizing. Long when composite ≥ 0.55. Exit on composite < 0.40 OR drawdown > 8% from local peak. Sizing: 100% notional, leverage cap 1.0x.
Historical performance. Sharpe 1.28 · CAGR +15.2% · MaxDD -14.0% (2018-01 → 2026-04 backtest, run_id 8a9c0a91).
Known failure modes. Underperforms in violent reversal weeks (e.g., 2022-W19 covid-rebound flush). Foreign-room signal stale during ETF rebalance windows.
Where it runs. Telegram channel @vni_trading_bot. Monitored by eric.nguyen; backstop reviewer c.le.
| T0 investors · auditors |
T1 junior · interns |
T2 senior researchers |
T3 eric · c · head-of-research |
|
|---|---|---|---|---|
| Aggregate performance & risk | ✓ | ✓ | ✓ | ✓ |
| Process integrity reports | ✓ | ✓ | ✓ | ✓ |
| P1 data layer · query API | — | ✓ | ✓ | ✓ |
| Author research (sandboxed) | — | ✓ (sandbox) | ✓ | ✓ |
| Run assigned backtests | — | ✓ | ✓ | ✓ |
| Signal library · enumerate | — | limited | ✓ (full) | ✓ |
| Signal source code | — | — | ✓ | ✓ |
| Other researchers' in-flight work | — | — | ✓ | ✓ |
| Propose strategy → production | — | — | ✓ (proposes) | ✓ |
| Approve production deployment | — | — | — | ✓ |
| Grant/revoke T2 access | — | — | — | ✓ |
| Infrastructure modification | — | — | — | ✓ (with audit) |
| Deal-level financials (SPV / cap table) | — | — | — | ✓ |
| USER | TIER | SINCE | LAST |
|---|---|---|---|
| eric.nguyen | T3 | 2024-01 | now |
| c.le | T3 | 2024-01 | 14:08 |
| eric.nguyen (research) | T2 | 2024-01 | now |
| tan.do | T2 | 2024-09 (granted today) | 13:42 |
| khoa.tran | T2 | 2024-04 | 12:55 |
| huyen.pham | T1 | 2026-02 | 13:55 |
| minh.vu (intern) | T1 | 2026-04 | yest |
| auditor.kpmg | T0 | 2026-03 | 3d ago |
# last 5 entries — sha256(prev_hash || event) block #14392 9f8a02bcd1...4f12 ✓ block #14391 7c1882af40...a801 ✓ block #14390 4d20cc88f2...7b04 ✓ block #14389 2a91dd0be8...c1f9 ✓ block #14388 81ff401cae...0042 ✓ # integrity verified · 14,392 events · 0 gaps
> go data switch to P1 Data Layer > bt vn30f-mom-v2 run backtest on this strategy > sig vn30.momo.20d open signal detail > user tan.do open user profile > tier grant t2 tan.do T3 only > audit last 1h filter audit log > px VCB MSB FPT ticker quotes > help
| P | CRITERION | STATUS | NOTE |
|---|---|---|---|
| P1 | Researcher can query VN30 universe as of any past date — no surv. / look-ahead bias | PASS | PIT verified for 2,184 dates |
| P1 | Crypto OHLCV across ≥2 exchanges + funding | PASS | 3 venues · funding 8h |
| P1 | Two researchers same query → byte-identical | PASS | verified hash on 14 datasets |
| P1 | QC dashboard 7-day visible | PASS | F2 → QC panel |
| P1 | No ad-hoc CSV loads anywhere | PASS | audit policy enforced |
| P2 | One live strategy migrated within tolerance (Sharpe ±0.1, CAGR ±0.5%) | PASS | vnindex-long Δsharpe 0.04 |
| P2 | Same spec twice → identical tear sheet | PASS | verified daily |
| P2 | Spec written Nov re-runs in Mar identically (PIT end-to-end) | IN-TEST | verification scheduled M4 |
| P3 | All live signals registered with metadata | PARTIAL | 9/14 registered |
| P3 | T1 cannot enumerate library; T2 can | PASS | verified in F4 access preview |
| P3 | Backtest signal version == live computation result | IN-TEST | unit-test suite drafted |