SKY TERMINAL
FeaturesPricingProduct PreviewSignal TransparencySupport
Log inRegister
SKY TERMINAL · See the market before the move.TermsPrivacyMembershipPayments & RefundsRisk DisclosureData SourcesSupportX

Sky Terminal provides market information, research tools, alerts and simulations. It is not an exchange, broker or custodian, does not hold funds and does not execute trades. Nothing here is financial advice. Cryptocurrency futures are highly volatile and leveraged trading can lose more than your initial margin. Exchange data is attributed to its source and may be delayed or incomplete.

Signal methodology and Signal Transparency Lab metrics

Code: src/lib/signals/engine.ts (rules + lifecycle), src/lib/signals/store.ts (persistence), src/lib/signals/metrics.ts (metrics).

Classification taxonomy

Every signal row carries exactly one classification (enforced by a CHECK constraint):

ClassificationMeaning
livePublished in real time and acted on with real orders. Sky Terminal does not currently produce these.
paperPublished in real time with a defined entry, stop, targets and exit rules; outcomes are derived from exchange candles. No order is executed.
backtestGenerated after the fact by running rules over historical data. Subject to look-ahead and overfitting risk.
historicalReal-time signals from an earlier system/version whose records are complete and kept as published.
importedBrought in from an external export (importLegacySignals). Timestamps, prices and reported results are preserved as given and not independently verified.

Metrics can be broken down by classification (byClassification); never mix them without saying so.

Integrity rules

  • signals rows are immutable: database triggers reject UPDATE and DELETE. A signal is written once, at generation time, with its entry, stop, targets, entry conditions, closure criteria, data sources, timeframe and market regime.
  • Lifecycle is the append-only signal_events log, one row per state per signal (opened, tp1, tp2, stopped, trail_exit, expired, closed, invalidated). The current state is the latest event.
  • Admin corrections go to the append-only signal_corrections table (field, old value, new value, reason, actor, time). The original row is never changed; corrections are shown next to it. Metrics are computed from the original record.
  • Losing signals are never deleted, hidden or filtered. Imports bring in losses exactly like winners.

Strategy sky-capitulation version 1.0.0 (paper)

Parameters are stored in signal_strategies (engine, version, params JSON). The engine refuses to run if the stored parameters for a version differ from the code: any parameter change requires a new version.

Universe: Binance USD-M perpetuals, the top 120 by 24h quote volume with at least $20M volume, from the latest market snapshot (must be < 15 min old).

Trigger — evaluated once per hour on the most recently closed 1h candle:

  1. Close is at least 15 % below the highest high of the prior 24 candles.
  2. Candle quote volume is at least 3× the median quote volume of the prior 24 candles.
  3. Lower wick (min(open, close) − low) is at least 50 % of the candle range (high − low).
  4. No open signal from this strategy on the symbol.
  5. No new signal on a symbol within 72 h of a stopped event on that symbol (any stop, including a breakeven one).

The scan runs only within 15 minutes after the candle closes; a missed hour is not backfilled (no retroactive signals). Signal ids are deterministic (engine|version|symbol|candle time), so re-running is idempotent.

Market regime at generation: BTCUSDT 24h change > +3 % → risk_on, < −3 % → risk_off, otherwise neutral (unknown if unavailable). Timeframe is 1h.

Plan (long only):

LevelAction
Entry / reference1h candle closefull position
Stopentry × 0.88 (−12 %)exit everything remaining
TP1entry × 1.10 (+10 %)close 1/3
TP2entry × 1.20 (+20 %)close 1/3, move stop to entry
Trailmax(entry, highest high since TP2 × 0.92)exit last 1/3 (trail_exit)
Max hold7 days from the candle closeexit remaining at the next 5m open (expired)

Note: once TP2 is reached the trail level is at least 1.20 × 0.92 = 1.104 × entry, so the trail always dominates the breakeven stop in this version.

Lifecycle resolution (advanceOpenSignals): 5m Binance candles from the last state change onward are walked in time order. Only closed candles are used. Rules inside one candle:

  • The stop is checked first. If a candle touches both the stop and a target, the stop is assumed to have hit first (conservative).
  • A candle that opens through the stop fills at its open (gap), not at the stop.
  • Targets fill at the target price. TP1 and TP2 may hit in the same candle.
  • The trailing stop is enforced from the candle after the TP2 candle; the TP2 candle's high seeds the trail.
  • If no market data arrives for 24 h after expiry, the signal is marked invalidated and excluded from metrics with that reason.

Event timestamps of tp1/tp2/exits are the open time of the 5m candle where the level was touched.

Costs: 0.05 % fee + 0.05 % slippage per side on every fill (entry, each partial exit, final exit), as a percentage of that fill's notional relative to the entry notional:

gross%     = Σ fraction_i × (exit_i / entry − 1) × 100
sides      = 1 + Σ fraction_i × exit_i / entry
fees%      = 0.05 × sides
slippage%  = 0.05 × sides
net%       = gross% − fees% − slippage%

The result is stored on the closed event with gross, fees, slippage, fills, exit reason and holding time.

Caveat on entry: the reference entry is the 1h close. The signal becomes visible a few minutes later (at generation). A reader acting on it would usually get a different price.

Opens and closes are published to Sky Feed (category = signal, source = signals, entitlement = premium, dedupe key signal:{id}:{state}). The engine is disabled by the signals.engine flag.

Metric definitions (computeMetrics)

All P&L metrics are equal-weighted (each signal = one unit of notional), unleveraged (percent of entry notional, not of margin) and net of fees and slippage as recorded in each signal's result.

MetricDefinition
totalall signals passed in, including excluded ones
openincluded signals without a realized result
closedincluded signals with a realized net result and close time
winsclosed with net result > 0
lossesclosed with net result ≤ 0 — breakeven counts as a non-win/loss
win ratewins / closed (closed only; null if none)
average gain / lossmean net % of wins / of losses
average holding periodmean of closed.at − opened.at
profit factorΣ net % of wins /Σ net % of losses; null with a note when there are no losses (or nothing closed) rather than ∞
max drawdownlargest peak-to-trough fall of the cumulative sum of per-signal net %, ordered by close time (ties by id), with the peak starting at 0. Units: percentage points
R distributionrealized net % ÷ planned stop distance % (`entry − stop/ entry), bucketed < −1R, −1R–0R, 0R–1R, 1R–2R, 2R–3R, ≥ 3R. Signals without a stop are counted in rUnavailable`
breakdownsby symbol, strategy+version, timeframe, market regime and classification

Exclusions are surfaced in excluded: [{ id, reason }], never dropped silently:

  • alert-only records (signal_type alert) — no defined entry/exit methodology;
  • missing entry price;
  • invalidated signals (with their reason);
  • closed without a realized result, or without a close time;
  • terminal exit state without a closed result.

What is NOT claimed

  • No independent verification. Results are computed by Sky Terminal from public exchange candles and its own records. No third party has audited them.
  • Not executed trades. paper signals are not orders. Real fills, partial fills, queue position, funding payments, liquidation risk, outages and latency are not modelled beyond the flat fee/slippage assumption.
  • Imported results are as reported by the source and may be gross of fees.
  • Past results do not predict future results. A small sample can look very good or very bad by chance.
  • Nothing here is investment advice or a recommendation to trade.