Confluence Toolkit — Technology Whitepaper
A Wyckoff-confluence trading signal system for OKX perpetual futures
v0.1 — 2026-08-27
This document describes only the technical architecture and methodology of the system. It does not cover any token, tokenomics, fundraising structure, or content that could be read as a financial solicitation. Every performance figure in this document comes from backtests/demo trading, not realized live trading profit — see "Current State & Limitations" at the end.
1. Summary
Confluence Toolkit is a quant trading system for perpetual futures on OKX, combining classical Wyckoff methodology with multi-timeframe confluence scoring and full transaction-cost modeling (fees + funding). The entire pipeline — data ingestion, scoring, backtesting, calibration, and real-time scanning — shares one single scoring logic between backtest and live scanning, so there is never a gap between "what was validated" and "what is actually running."
Core principle: win rate is not the target. The right metrics are expectancy, profit factor (PF), and the R-multiple distribution. A system with a low win rate but a large average win is still better than one with a high win rate but a small average win.
2. System architecture
Candle/funding/OI data (OKX)
→ Wyckoff confluence scoring (scorer.py)
→ Backtest with fees + funding (backtest.py)
→ Walk-forward calibration per coin/side/timeframe (calibrate.py)
→ Real-time scanning (realtime_scan.py)
→ Telegram alerts
→ [optional] Automated position management, with a kill-switch + tiered TP + trailing SL
Runs 24/7 on a dedicated VPS, using the exact same scorer.py for both the backtest path and the live path — any change to the scoring logic automatically propagates to both, with no manual syncing between two parallel codebases.
Data sources
| Source | Data | Role |
|---|---|---|
OKX /market/candles | OHLCV candles, all timeframes | Primary signal data |
OKX /public/funding-rate, /public/open-interest | Funding rate, open interest | Market-regime classification |
OKX /market/history-trades | Real taker CVD | Cross-validation only, not used for signals |
| Binance USDT-M futures | Fallback candles | Only for coins not listed on OKX, scanning/alerts only |
Known limitation: OKX's public candles don't expose real taker buy/sell splits. Delta is approximated with a close-location-value (CLV) formula: delta ≈ volume × (2×(close−low)/(high−low) − 1). Cross-checked against real taker trades (via /market/history-trades), this proxy matches the correct direction only about 33% of the time on the available validation sample — a known-weak proxy, disclosed openly, not a substitute for real CVD.
3. Wyckoff confluence scoring
Every closed bar (never the currently-forming bar, to avoid flickering signals while price is still moving) is evaluated through a multi-factor scoring system, symmetric between long and short.
A signal must converge from multiple independent layers of evidence rather than relying on any single indicator:
- Wyckoff price structure — recognition of classical reversal patterns (Spring/Selling Climax for bottoms, Upthrust/Buying Climax for tops).
- Volume confirmation — a volume spike coinciding with the price structure, not a random spike elsewhere.
- Order-flow confirmation (delta) — signs of buy/sell absorption or exhaustion at a key price level.
- A supporting set of technical indicators (momentum, divergence, volatility bands, medium/long-term trend context) — add confidence but are not individually required.
These layers are combined into a single composite confluence score, bucketed into grades — the higher the grade, the more complete the agreement across evidence layers. The system only auto-pushes alerts for the top grades; lower grades are logged but not proactively surfaced.
A higher-timeframe trend filter can hard-block a signal that runs against the larger structure, independent of its score — a well-converged signal on a lower timeframe is still discarded if it contradicts the higher-timeframe trend.
The minimum number of required evidence layers is calibrated separately per coin/side (see Section 5), not applied as one global threshold — loosening this threshold broadly was measured to be a coin-flip effect that does not generalize across coins.
The specific weighting between evidence layers and the exact score thresholds per grade are implementation details not disclosed in this document.
4. Transaction-cost modeling (cost accounting)
This is the system's central measurement discipline: every backtest result must subtract full round-trip fees and signed funding before it is treated as valid.
- Fees: 0.10% round-trip (taker × 2), calibrated to match real fees measured on the account. Converted into R units: the tighter the stop-loss, the harder fees bite in R terms — a consequence often missed when fees are only viewed as a flat percentage.
- Funding: calibrated from real account data (not the exchange-wide median, which tends to understate the real cost significantly). Signed: long positions pay positive funding, shorts receive it. Computed at fixed daily settlement points, not pro-rated by holding time.
- Every backtest result keeps 4 separate columns: r_gross (before costs), fee_r, funding_r, and r (net — used for every downstream decision). Every public presentation labels gross vs. net explicitly, never blending the two.
A recorded operational lesson: at one point the backtest module computed zero transaction costs while the live position-tracking system recorded PnL that already included real costs — the two sides were measuring with different rulers. Some previously "profitable" results turned out to be a calculation artifact rather than a real edge. After the bug was found and fixed, the entire dataset was re-checked: a meaningful share of configurations that had previously cleared the approval bar turned out to be losing after costs. This is why the system enforces a mandatory costs_included flag on every configuration before it can be considered for live trading.
5. Walk-forward calibration
A grid search over the parameter space (grade thresholds, maximum holding time, higher-timeframe filter mode, volume-climax sensitivity, minimum required evidence layers) is run separately for each coin/side/timeframe — never one shared parameter set across every market.
Process:
- Split price history into multiple time-ordered folds.
- For each candidate configuration, measure performance on the in-sample fold and pick the best one by a risk-adjusted objective.
- Verify on the following out-of-sample fold — a large gap between in-sample and out-of-sample performance is treated as an overfitting signal, not a real edge.
- The selected configuration is recorded together with its full-sample statistics (n, win rate, PF, average R, max drawdown).
Parallelized across CPU cores — cutting a full calibration run from roughly 45–50 minutes down to about 106 seconds on a 22-core machine.
Market-regime segmentation
The system classifies markets by open-interest × funding-rate combinations (SHORT_CROWDED, LONG_CROWDED, LONG_UNWIND, SHORT_COVERING, NEUTRAL) and does not pool setups from different regimes into one calibration — mixing regimes was confirmed to dilute the real signal and mask conditional edges.
Statistical confidence thresholds
- n ≥ 30: no conclusion about the presence or absence of an edge is drawn below this sample size, no matter how attractive the result looks.
- PF > 1 and costs_included = true: the minimum bar a configuration must clear to be considered for the next trading stage.
6. Real-time scanning & noise control
Three noise-control principles apply across the entire market-scanning flow:
- Only closed bars are scored — a still-forming bar has price/volume/delta that keep moving, so scoring it would flip the signal back and forth within the same bar.
- Deduplication keyed on
(instrument, timeframe, side, bar close time)— each signal fires exactly once, at the moment its bar closes, never repeated on later scan cycles. - Only actionable signals are pushed — by default only the top grades trigger a push notification; lower grades are recorded but only shown on explicit request.
7. Position management (when running in automated mode)
Risk-based position sizing
Sizing is based on a percentage of account risk, always rounded down — never rounded up to meet an exchange's minimum order size, which would silently exceed the intended risk budget. If the rounded-down size is zero, the order is skipped rather than inflating the risk to force a fill.
Leverage only affects margin usage and distance to liquidation — mathematically it has no effect on R-multiple or profit factor (it's a scalar rescaling of the same underlying risk), but high leverage can cause a position to be liquidated before it reaches its intended stop-loss — an operational risk that must be managed separately from the strategy's statistical risk.
Tiered exits (take-profit)
Positions are closed through multiple take-profit tiers rather than exiting the whole position at a single point: the first tier closes a portion and moves the stop-loss to breakeven (removing principal risk as early as possible), subsequent tiers close more and progressively lock in the profit already achieved, and the remainder is left open to capture further upside if the trend continues. The first tier's target can be computed dynamically from market structure, with a fixed fallback when no valid dynamic target is available.
A maximum holding-time limit (calibratable per coin/side) forces an exit if neither the stop-loss nor a take-profit tier has been hit within that window.
The exact close percentage at each tier and the exact target R-multiples are implementation details not disclosed in this document.
Operational safeguards
- Daily loss kill-switch: tracks cumulative realized PnL for the day, automatically blocks new entries once a preset daily-loss threshold is hit, and resets automatically at day rollover. It does not block management of already-open positions.
- MAE/MFE tracking (maximum adverse/favorable excursion) on every closed trade — the input for recalibrating stop-loss/take-profit levels over time based on observed behavior, not on initial assumptions.
- Management of open positions runs independently of whether new-signal scanning is paused — pausing new signals does not mean risk management on existing positions stops.
8. Current state & limitations (stated plainly)
This section lists what the system has not yet achieved, in keeping with the principle of not embellishing technical claims:
- No live trading track record yet — every performance figure to date comes from backtests/a demo environment, and does not yet capture every factor of real trading (slippage, real liquidity, operational latency).
- Delta is a weak proxy, not real taker CVD — as noted in Section 2, it matches direction roughly 33% of the time against real taker-trade data.
- Wyckoff auto-detection is a heuristic — the rules for identifying Spring/Upthrust/Climax patterns are an automated model, and may label events differently than a discretionary Wyckoff trader would on the same chart.
- Transaction costs can exceed the statistical edge on short timeframes (15 minutes) — a tight stop-loss requires a larger position size to hold the same risk, so fees on that larger notional can consume most or all of the gross edge measured before costs.
- Sample sizes on higher timeframes (1H/4H) remain limited — it takes longer price history to accumulate enough trades for reliable per-coin/side calibration at these timeframes.
- Part of the historical dataset is still being recomputed on a net-of-costs basis (following the discovery and fix of the cost-accounting bug described in Section 4) — this process is ongoing, not yet complete across the entire dataset.