From f3c2e6254402d23514f4907622381d59ca988ee1 Mon Sep 17 00:00:00 2001 From: Gaurav Agarwal Date: Sat, 8 Aug 2026 12:13:08 +0530 Subject: [PATCH 1/2] docs: add Solana Perps Trader Cookbook Workflow-shaped recipes for traders, copy-traders and strategy builders, each validated against the live endpoint: - copy trading: live fill feed for a wallet, current open book snapshot, trader report card (realized PnL, win rate, liquidation count) - positions & PnL: top unrealized positions/traders via composite limitBy snapshot + fresh marks, funding paid/received per trader - market signals: whale fills, OHLC candles from mark price via interval + argMin/argMax, OI/basis/fee-revenue hourly series (cumulative-counter diff), taker buy/sell order-flow pressure - risk: biggest-liquidations leaderboard Cross-linked from the Perp DEX overview and Phoenix Perpetuals page. Co-Authored-By: Claude Opus 5 --- docs/perpetuals/index.md | 5 +- .../solana/perps-trader-cookbook.md | 355 ++++++++++++++++++ .../solana/phoenix-perpetuals-api.md | 4 + sidebars.js | 5 +- 4 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 docs/perpetuals/solana/perps-trader-cookbook.md diff --git a/docs/perpetuals/index.md b/docs/perpetuals/index.md index 66fdd338..248d8197 100644 --- a/docs/perpetuals/index.md +++ b/docs/perpetuals/index.md @@ -145,7 +145,10 @@ subscription { - **Market-maker monitoring** — follow order lifecycle and AMM-vs-book fill share Start with the [Phoenix Perpetuals API](/docs/perpetuals/solana/phoenix-perpetuals-api) -page — it documents every cube with working queries and streams. +page — it documents every cube with working queries and streams. Then jump to the +[Perps Trader Cookbook](/docs/perpetuals/solana/perps-trader-cookbook) for +workflow-shaped recipes: copy-trading a wallet, trader win-rate report cards, top +unrealized positions, whale fills, OHLC candles, open-interest and order-flow series. 0` tells you how +they treat risk. Add a `Block: { Time: { since: … } }` filter to score a recent window +instead of all time. + +## Positions & PnL + +### Top unrealized positions and traders + +Unrealized PnL is `(mark − entry) × size` over each trader's latest open position. +One request returns both the position snapshot and fresh marks: + +```graphql +query { + Solana { + openPositions: PerpetualPositions( + limitBy: { by: [Position_Trader, Position_Asset_Id], count: 1 } + orderBy: { descending: Block_Time } + limit: { count: 3000 } + where: { Position: { TraderIsAmm: false } } + ) { + Block { Time } + Position { + Trader + Asset { Id Symbol } + Position { EntryPrice Size } + MarkPrice + } + } + marks: PerpetualPrices( + limitBy: { by: Price_Asset_Id, count: 1 } + orderBy: { descending: Block_Time } + limit: { count: 200 } + ) { + Price { Asset { Id Symbol } Mark } + } + } +} +``` + +Then a few lines client-side: + +```python +marks = {m["Price"]["Asset"]["Id"]: m["Price"]["Mark"] for m in d["marks"]} +open_pos = [] +for r in d["openPositions"]: + p = r["Position"]; size = p["Position"]["Size"] + if size == 0: + continue # flat = closed + mark = marks.get(p["Asset"]["Id"]) or p["MarkPrice"] + upnl = (mark - p["Position"]["EntryPrice"]) * size # signed Size handles shorts + open_pos.append((p["Trader"], p["Asset"]["Symbol"], size, upnl)) + +top_positions = sorted(open_pos, key=lambda x: x[3], reverse=True) +``` + +Sum per `Trader` for a whale-exposure leaderboard. Prefer the `marks` alias over the +position row's own `MarkPrice` — the latter is denormalized and can be `0`. + +### Funding a trader has paid or received + +Funding settlements are their own rows — `Funding` non-zero, size unchanged: + +```graphql +query { + Solana { + PerpetualPositions( + limit: { count: 100 } + orderBy: { descending: Block_Time } + where: { + Position: { + Trader: { is: "DUGirckBgoaW3zoEPhTVVo68pZpXrTKuJrsLBLWcZQo2" } + Funding: { ne: 0 } + } + } + ) { + Block { Time } + Position { Asset { Symbol } Funding } + } + } +} +``` + +Positive = received, negative = paid. Replace the field list with +`total: sum(of: Position_Funding)` for the net carry cost of holding their positions. + +## Market signals + +### Whale fills + +Every fill above a notional threshold — as history or a live tape: + +```graphql +subscription { + Solana { + PerpetualFills(where: { Fill: { Amount: { Quote: { gt: 5000 } } } }) { + Block { Time } + Fill { + Asset { Symbol } + Side + ExecutionPrice + Amount { Filled Quote } + Trader + Liquidation + } + } + } +} +``` + +As a `query`, add `orderBy: { descending: Block_Time }` and a `limit` for the recent +whale prints. + +### OHLC candles from the mark price + +Strategy builders and backtesters: bucket `PerpetualPrices` into intervals and take +argMin/argMax aggregates — + +```graphql +query { + Solana { + PerpetualPrices( + where: { Price: { Asset: { Symbol: { is: "BTC" } } } } + orderBy: { ascendingByField: "Block_Time" } + limit: { count: 96 } + ) { + Block { Time(interval: { in: minutes, count: 15 }) } + Price { + open: Mark(minimum: Block_Time) + high: Mark(maximum: Price_Mark) + low: Mark(minimum: Price_Mark) + close: Mark(maximum: Block_Time) + } + } + } +} +``` + +`Mark(minimum: Block_Time)` reads "the Mark at the earliest time in the bucket" — +open; `Mark(maximum: Price_Mark)` is the bucket's high. Price rows are emitted on +trading activity, so an interval with no trades produces no candle (no +zero-filled bars). + +### Open interest, basis and fee revenue over time + +One query per market gives an OI series, the perp-vs-spot basis, and — because +`TakerFees`/`MakerFees` are cumulative counters — per-bucket fee revenue as +end-minus-start: + +```graphql +query { + Solana { + PerpetualMarketSummaries( + where: { MarketSummary: { Asset: { Symbol: { is: "SOL" } } } } + orderBy: { ascendingByField: "Block_Time" } + limit: { count: 168 } + ) { + Block { Time(interval: { in: hours, count: 1 }) } + MarketSummary { + oi: OpenInterest(maximum: Block_Time) + mark: Mark(maximum: Block_Time) + spot: SpotIndex(maximum: Block_Time) + takerFeesEnd: TakerFees(maximum: Block_Time) + takerFeesStart: TakerFees(minimum: Block_Time) + } + } + } +} +``` + +Basis = `mark − spot`; hourly taker fees = `takerFeesEnd − takerFeesStart`. Rising OI +with a widening basis is the classic crowded-longs signal. + +### Order-flow pressure — taker buys vs sells + +Conditional sums split taker volume by side per bucket: + +```graphql +query { + Solana { + PerpetualFills( + where: { Fill: { Asset: { Symbol: { is: "SOL" } } } } + orderBy: { ascendingByField: "Block_Time" } + limit: { count: 168 } + ) { + Block { Time(interval: { in: hours, count: 1 }) } + buyVol: sum(of: Fill_Amount_Quote, if: { Fill: { Side: { is: "bid" } } }) + sellVol: sum(of: Fill_Amount_Quote, if: { Fill: { Side: { is: "ask" } } }) + trades: count + } + } +} +``` + +`(buyVol − sellVol) / (buyVol + sellVol)` is a ready order-flow-imbalance series. + +## Risk + +### Biggest liquidations + +Rank forced closes by what they took: + +```graphql +query { + Solana { + PerpetualPositions( + limit: { count: 20 } + orderBy: { descendingByField: "lost" } + where: { Position: { Type: { is: "Liquidation" } } } + ) { + Position { Trader Asset { Symbol } } + lost: sum(of: Position_LiquidatedQuote) + events: count + } + } +} +``` + +For the live feed version and the multi-row anatomy of a liquidation, see the +[liquidation section](/docs/perpetuals/solana/phoenix-perpetuals-api#positions-pnl--liquidations--perpetualpositions) +of the Phoenix page. + +--- + +Every `query` above becomes a live stream by switching to `subscription` and removing +`limit`/`orderBy`/`limitBy` — except the snapshot and interval recipes, which are +inherently query-shaped. Run them over Kafka instead with the +[`solana.perpetual.proto` topic](/docs/streams/protobuf/chains/Solana-perpetual-protobuf) +when you need the full firehose. diff --git a/docs/perpetuals/solana/phoenix-perpetuals-api.md b/docs/perpetuals/solana/phoenix-perpetuals-api.md index 3d6991ea..53fb2f8f 100644 --- a/docs/perpetuals/solana/phoenix-perpetuals-api.md +++ b/docs/perpetuals/solana/phoenix-perpetuals-api.md @@ -508,6 +508,10 @@ subscription { ## Ideas to build +Worked, runnable versions of the recipes below — copy-trade feeds, trader report +cards, unrealized-PnL rankings, OHLC candles, OI/basis series, order-flow pressure — +live in the [Perps Trader Cookbook](/docs/perpetuals/solana/perps-trader-cookbook). + - **Liquidation alerts** — the subscription above, pushed to Telegram/Discord. - **PnL leaderboard** — aggregate `RealizedPnl` by `Trader` over `PerpetualPositions`, excluding `TraderIsAmm: true`. diff --git a/sidebars.js b/sidebars.js index 4ab63159..709b8a73 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1090,7 +1090,10 @@ const sidebars = { type: "doc", id: "perpetuals/index", }, - items: ["perpetuals/solana/phoenix-perpetuals-api"], + items: [ + "perpetuals/solana/phoenix-perpetuals-api", + "perpetuals/solana/perps-trader-cookbook", + ], }, { type: "category", From e9d6c551ceda448edc136d527c4c3e6014814e34 Mon Sep 17 00:00:00 2001 From: Gaurav Agarwal Date: Sat, 8 Aug 2026 12:20:04 +0530 Subject: [PATCH 2/2] docs: SEO audit fixes for cookbook and Kafka stream pages - trim both meta descriptions to under 160 chars - add FAQPage JSON-LD to the cookbook (copy trading, trader ranking, unrealized PnL, OHLC, whales, order flow), matching sibling pages - target verified-volume keywords: crypto copy trading, copy trading bot, order flow imbalance; mention copy-trading bot in body copy Co-Authored-By: Claude Opus 5 --- .../solana/perps-trader-cookbook.md | 23 +++++++++++++++---- .../chains/Solana-perpetual-protobuf.md | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/perpetuals/solana/perps-trader-cookbook.md b/docs/perpetuals/solana/perps-trader-cookbook.md index 0e6cafd8..d6cec978 100644 --- a/docs/perpetuals/solana/perps-trader-cookbook.md +++ b/docs/perpetuals/solana/perps-trader-cookbook.md @@ -2,9 +2,11 @@ title: "Solana Perps Trader Cookbook — Copy Trading, PnL & Signals" sidebar_label: "Trader Cookbook" sidebar_position: 3 -description: "Ready-to-run queries for Solana perps: copy-trade a wallet, rank traders by PnL and win rate, top unrealized positions, whale fills, OHLC candles, open interest and order-flow signals." +description: "Ready-to-run Solana perps queries: copy-trade a wallet, rank traders by PnL and win rate, unrealized positions, whale fills, OHLC, open interest, order flow." keywords: - copy trading api solana + - crypto copy trading + - copy trading bot - solana perps signals - track perp trader wallet - perp trader pnl api @@ -13,13 +15,15 @@ keywords: - whale trades solana - perps ohlc candles api - open interest chart api - - order flow imbalance api + - order flow imbalance - funding payments api - liquidation leaderboard - solana trading strategy data - perp dex analytics queries --- +import FAQ from "@site/src/components/FAQ"; + # Solana Perps Trader Cookbook Ready-to-run recipes for the questions traders, copy-traders and strategy builders @@ -41,8 +45,8 @@ Two rules apply to almost every recipe: ### Follow a trader's every fill, live -Stream each execution of a wallet you follow — the copy-trade signal, including the -position it produced: +Stream each execution of a wallet you follow — the signal feed a copy-trading bot +subscribes to, including the position each fill produced: ```graphql subscription { @@ -353,3 +357,14 @@ Every `query` above becomes a live stream by switching to `subscription` and rem inherently query-shaped. Run them over Kafka instead with the [`solana.perpetual.proto` topic](/docs/streams/protobuf/chains/Solana-perpetual-protobuf) when you need the full firehose. + + diff --git a/docs/streams/protobuf/chains/Solana-perpetual-protobuf.md b/docs/streams/protobuf/chains/Solana-perpetual-protobuf.md index 5ef0a9fb..1eba310d 100644 --- a/docs/streams/protobuf/chains/Solana-perpetual-protobuf.md +++ b/docs/streams/protobuf/chains/Solana-perpetual-protobuf.md @@ -1,7 +1,7 @@ --- title: "Solana Perpetuals Kafka Stream — solana.perpetual.proto" sidebar_label: "Solana Perpetuals Stream" -description: "Consume Solana perpetual futures data over Kafka: orders, fills, positions, PnL, liquidations, prices and open interest as protobuf messages on solana.perpetual.proto." +description: "Solana perpetual futures over Kafka: orders, fills, positions, PnL, liquidations, prices and open interest as protobuf on the solana.perpetual.proto topic." keywords: - solana perpetuals kafka - solana.perpetual.proto