Skip to content

Feat/peg deviation alerts - #322

Open
p70436464-prog wants to merge 3 commits into
Divinity-Labs:mainfrom
p70436464-prog:feat/peg-deviation-alerts
Open

p70436464-prog wants to merge 3 commits into
Divinity-Labs:mainfrom
p70436464-prog:feat/peg-deviation-alerts

Conversation

@p70436464-prog

Copy link
Copy Markdown

Closes #288

Summary

Implements a peg-deviation alert in src/alerts/ through the existing alerts path to monitor stablecoins and pegged assets leaving and returning to their peg.

What was built

  • Peg Deviation Tracker (PegDeviationTracker, checkPegDeviation): Evaluates price ticks against a configurable target price and deviation band (band, bandBps, bandPct).
  • Sustained Duration Requirement: Requires deviation to persist for sustainedDurationMs across multiple samples before raising an alert, ensuring a single bad tick does not fire.
  • Recovery Event: Emits a dedicated recovery event when price recovers within the peg band, detailing recoveredAt, deviationStartedAt, and total durationMs.
  • Venue & Provenance Tracking: Carries all observed venues (venues: string[]) and full provenance ({ venues, sampleCount, freshnessMs }).
  • Honest Answers: Non-positive and non-finite prices are discarded rather than treated as a valid zero price.
  • Alerts Delivery: Seamlessly integrates with deliverJsonWithRetries for HMAC-signed webhook delivery.

Testing

  • tests/pegDeviation.test.ts: Added test suite proving that:
    • Band and sustained duration requirements are respected.
    • A single outlier tick does not fire.
    • Recovery raises its own event with complete duration and recovery timestamp.
    • Venues observed across the deviation are carried in the alert payloads.

…s venues

- Calculate proportions per venue for a given size that minimise total slippage
- Return split proportions only when splitting beats the single-venue route
- Include single-venue alternative comparison in response
- Add GET /price/:assetA/:assetB/split route filtering on and echoing network
- Fully declare /price/{assetA}/{assetB}/split and schemas in openapi.yaml and openapi.json
- Add vitest tests covering size where splitting wins and where it does not
@drips-wave

drips-wave Bot commented Oct 16, 2026

Copy link
Copy Markdown

@p70436464-prog Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Miracle656

Copy link
Copy Markdown
Collaborator

CI is red, and both of your open PRs fail on the same file for the same reason — src/__tests__/splitRoute.test.ts:

Error: [vitest] There was an error when mocking a module. If you are using "vi.mock" factory,
make sure there are no top level variables inside, since this call is hoisted to top of the file.
 ❯ src/aggregator/splitRoute.ts:1:1
   1| import { Asset } from '@stellar/stellar-sdk'

vi.mock is hoisted above the imports, so a factory that closes over a top-level variable runs before that variable exists. The usual fix in this repo is vi.hoisted:

const { mockThing } = vi.hoisted(() => ({ mockThing: vi.fn() }))
vi.mock('../network/clients', () => ({ getHorizonServer: mockThing }))

src/__tests__/priceHistoryNetwork.test.ts, merged earlier today in #308, is a working example in this repo.

There is a second trap behind this one, specific to mocking @stellar/stellar-sdk: spreading the module namespace drops non-enumerable bindings, so Networks disappears and the failure looks unrelated to your mock. PR #158 fixes exactly that and is in my queue — if your mock still misbehaves after the vi.hoisted change, read #158 before spending time on it.

Separately: #320 and #322 both carry splitRoute. If #322 is meant to build on #320, say so in its description and base it on that branch, otherwise whichever merges second will conflict with itself.

Miracle656 added a commit that referenced this pull request Oct 22, 2026
  tsc --noEmit   clean
  vitest         97 files, 1135 passing
  dropped-tests  none

  #311  adaptive slippage impact endpoint
  #323  trade size and volume concentration metrics

#320 and #322 screened clean individually but conflict once #311 and #323 are
in -- all four touch the same routing and pricing surface. They need a rebase
rather than a fix; noted on both.

Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB

@Miracle656 Miracle656 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a rebase. This screened clean on its own — tsc --noEmit passes against main as it was — but conflicts once #311 (adaptive slippage) and #323 (trade size and volume concentration) are in, and those landed as b906b47.

All four touch the same routing and pricing surface, which is why they collided rather than merged. Nothing is wrong with the code.

Rebase on current main and re-run npx vitest run before re-requesting. Two things worth checking while you are there, because both have caught PRs in this repo today:

  • the logging-hygiene test forbids console.* in non-test source — use createLogger (three PRs tripped this in two batches)
  • tests/openapi.test.ts fails if you document a route without registering it in src/app.ts, or the reverse

Happy to take it as soon as it is green.

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.

A depegging asset raises no alarm

2 participants