Skip to content

Stg -> Main - #77

Merged
lsheva merged 6 commits into
mainfrom
stg
Sep 22, 2026
Merged

lsheva merged 6 commits into
mainfrom
stg

Conversation

@lsheva

@lsheva lsheva commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Market maker fix

shev-titan and others added 6 commits September 20, 2026 17:01
…xchange.

Co-authored-by: Cursor <cursoragent@cursor.com>
Write LMN health-check aliases from titanio-net
… spreads

Quoted spreads were far wider than intended because sigma was overstated by
two independent bugs.

Decimal mismatch in the backfill. OracleTracker seeded its window from the
hashprice subgraph (8 decimals) and then appended live on-chain answers
(6 decimals), so a single ln(1/100) return dominated the window. The history
source now declares the aggregator address and decimals it is reporting, and
OracleTracker reconciles that against the live oracle before rebasing; a
mismatched aggregator skips the backfill instead of poisoning sigma. This
replaces the previous magnitude-based guess at the scale factor.

Wrong estimator for an irregularly sampled feed. volatilityPerSecond divided
each log return by sqrt(dt), which is only valid if the feed samples a
Brownian process at times unrelated to its moves. These oracles publish on a
deviation threshold, so |r| is essentially independent of elapsed time
(measured corr(log dt, log|r|) = -0.13 over a stable day, -0.11 over 96h) and
dividing by sqrt(dt) injects a spurious 1/sqrt(dt) term. It read ~1.74x high
in every period sampled. Replaced with the realized-variance estimator
sqrt(sum r^2 / sum dt), which is unbiased under threshold publication and far
more robust to bursts: rolling sigma spread over 96h was 20x for the old form
versus 4x for the new one. Verified against production in dry run, where
sigma fell from 69 to 41 bps over a 1h horizon.

Also in this change:

- Gate vault deposits on dryRun. CollateralTracker.maybeTopUp() submitted real
  deposits even in dry-run mode.
- Replace oracle.historyLookbackMultiplier with historyMaxAgeSec. The old knob
  scaled the backfill window by pollInterval, which has no bearing on how often
  the oracle updates. Backfill now requests exactly windowSize samples and uses
  the age bound only to keep a stale regime out of sigma.
- Move shared config documentation from the YAML files into the TypeBox schema
  descriptions so hover docs reach every environment, leaving only
  env-specific rationale inline. Corrects a stale claim that hashprice updates
  every ~5 min (measured median is ~3 min) and drops a comment describing a
  tx-weight field that no longer exists.
- Consolidate the three copies of fractionToNumber into math.ts and use it in
  oracleTracker, which was calling Fraction.valueOf() directly and logging
  null for sigma. Sigma is now reported at info level on backfill.
- Finish the migration to unified portfolio.*.yml configs: drop the per-app
  perps/futures configs and the stg variants, retire the matching package
  scripts, and replace the two per-app smoke tests with one portfolio test.
fix(market-maker): correct the realized-volatility estimate inflating spreads
@lsheva
lsheva requested a review from shev-titan September 22, 2026 12:58
@lsheva
lsheva merged commit de2be36 into main Sep 22, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants