Skip to content

nullfox/chart-extraction-techniques

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chart-extraction-techniques

Two techniques, extracted and sanitized, from a companion trading UI I built solo — a browser extension that lived inside a charting web app, read the same live data the chart saw, and turned a trader's annotated chart screenshots into structured price levels. The strategy-specific scoring is gone; these are the parts worth reading on their own. There's a longer writeup in WRITEUP.md.

Provenance. Lifted from a private codebase. The reusable mechanics are intact; the trading edge — scoring weights, thresholds, model prompts, and the signal source — is removed. No secrets, and no network calls in the tested path.

1. Main-world WebSocket interception — src/websocket-intercept.ts

The app streams quotes over a WebSocket with its own private framing. I already had the exact ticks landing in the tab in front of me — I just needed to see them, and a content script in the extension's isolated world (same DOM, separate JS heap) can't touch the page's own objects. So the interceptor injects into the page's main world at document_start, before the app opens a socket, and wraps the WebSocket constructor itself rather than any one instance. The parts I'd point at:

  • Wrap the constructor, not an instance (interceptWebSocket) — every socket the page ever opens is covered, and you get an uninstall back that restores the native constructor.
  • Preserve the prototype and readyState constants — a naïve wrap breaks every instanceof WebSocket check in the host app, and those failures surface a hundred lines away in code you don't own.
  • The handler can't throw into the host loop — it's wrapped so an interceptor bug can never wedge someone else's app. Observe, never interfere.
  • Generic de-framing (deframe) — the ~m~<len>~m~<payload> transport is de-framed on its own; which message type carries a quote and where the price sits in the envelope stays in your onMessage, not baked into the library.

See examples/content-script.ts for the full main-world / isolated-world wiring.

2. Recovering and verifying chart geometry — src/fib-verifier.ts

A vision model reads Fibonacci retracement levels off an annotated chart reliably, but the swing high/low those levels hang from are usually unlabeled — so it guesses them, badly. It doesn't have to: the endpoints are fully determined by algebra from any two levels. The parts I'd point at:

  • The verifier, not the solve (recoverSwing) — after solving for the swing from one pair of levels, every other level is reconstructed from it, and the whole result is thrown out unless they all reconcile within tolerance. You get exact endpoints or null — never a plausible-looking guess.
  • Solve from the widest ratio gap (widestPair) — the most numerically stable pair to derive the range from.
  • A probabilistic extractor behind a deterministic gate — the model proposes, the solver disposes. It's the pattern I'd reuse for anything checkable an LLM hands you: amounts that must sum, dates that must order, geometry that must close.

Pure functions, no I/O. The tests spell out the behavior — consistent levels solve, an inconsistent one rejects, and the tolerance is tunable.

Running

pnpm install
pnpm test        # vitest — no DOM, no keys, no network
pnpm build       # tsc → dist/ with type declarations

No runtime dependencies. TypeScript, ESM.

License

MIT — see LICENSE.

About

Two dependency-free browser/LLM techniques: intercept a page's own WebSocket feed from the main world, and recover + verify structured geometry from partial model output.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors