diff --git a/codex/economy/flip-candidates.yaml b/codex/economy/flip-candidates.yaml new file mode 100644 index 0000000..c32b0d1 --- /dev/null +++ b/codex/economy/flip-candidates.yaml @@ -0,0 +1,248 @@ +id: flip-candidates +title: GE Flipping (margin trading) +domain: economy +tags: [flipping, merchanting, ge, money-making, hybrid] +status: verified +version: 1 +updated: "2026-08-27" # ISO dates must stay quoted — YAML 1.1 parses bare dates to datetime.date + +summary: > + Buy-and-sell Grand Exchange margin flipping: place resting buy offers at + the low edge of an item's price band and resting sell offers at the high + edge, harvesting the spread on high-volume items. There are no skill or + quest requirements — capital breadth and slot discipline are the whole game. + +accounts: + membership: hybrid # flipping works on F2P and members accounts alike + min_level: 3 # post-Tutorial Island baseline; no skill requirement + requires_quest: [] + requires_other: + - "Post-Tutorial Island account with Grand Exchange access (no skill or quest requirement)" + +best_practice: + equipment: + - item: cash stack (flip capital) + why: "Gross margin per item is a few gp, so profit scales with quantity and the 4h + buy-limit window caps per-item volume — capital breadth (more candidates/slots + covered) matters more than any gear. Bulk flipping at scale needs ~20M+ cash." + source: "OSRS wiki — Merchanting (Bulk quantity flipping)" + techniques: + - name: flip the spread, not the trend + why: "Flipping profit is the buy/sell spread between pending offers (the impatience + premium), NOT price movement; it is safer when the item has high trade volume." + source: "OSRS wiki — Merchanting (Flipping)" + - name: prefer dynamic-price items, avoid static-price items + why: "Static-price items have no spread to harvest; only dynamic-price items carry + an exploitable margin." + source: "OSRS wiki — Merchanting (flipping guidance: 'strongly recommended to not + flip static-price items')" + - name: quote at the band edges, never instant-buy/sell + why: "Instant matching pays the standing offer's price (the market's impatience + price); a resting offer fills when a matching offer appears at or better than your + price. The 2% convenience fee makes sub-2%-spread staples unprofitable at band + edges outright, so the edges are where the margin lives." + source: "OSRS wiki — Merchanting (How the Grand Exchange works); OSRS wiki — Grand Exchange + (2% tax since 2025-05-29, capped 5M/item)" + - name: pace quotes inside the 4h buy-limit window, watch connected limits + why: "The buying rate is restricted to a set quantity every 4 hours per player, and + some items share a connected limit with related items — treat those as one bucket + when filling slots." + source: "OSRS wiki — Grand Exchange (Buy limits; Grand Exchange/Buying limits)" + +economy: + # Model (documented, reproducible from the snapshot): + # per slot: buy `limit` units at the low edge, sell at the high edge. + # net_pu = 0.98 * sell - buy (2% convenience fee on the sale; the 5M/item cap and + # the sub-50gp rounding exemption are not hit at these prices) + # 4h/slot = net_pu * limit (buy-limit window caps per-4h volume) + # Snapshot 2026-08-27: prices.runescape.wiki mapping + latest; limits cross-checked + # against Module:Exchange/ (all agree). Top 8 by 4h/slot below in profit_drivers. + item: Rune arrowtips # anchor: top candidate by modeled 4h/slot (members) + item_id: 44 + cost_per_cycle: 223 # buy @ low edge per unit (snapshot 2026-08-27) + income_per_cycle: 244 # sell @ high edge per unit, gross (snapshot 2026-08-27) + net_per_cycle: 16.12 # 0.98 * 244 - 223 (2% fee applied to the sale) + gp_per_hour_low: 69000 # 50% of the top-8 modeled upper bound — partial fills/drift + gp_per_hour_high: 138000 # top-8 modeled upper bound: sum(4h/slot) / 4 (8 slots, full fills) + xp_per_hour: 0 # flipping awards no XP + supplies: + - item: Rune arrowtips # canonical wiki names per action-grammar conventions + qty_per_cycle: 1 + source: ge + ge_limit: 10000 # mapping + Module:Exchange agree + - item: Iron bar + qty_per_cycle: 1 + source: ge + ge_limit: 10000 + - item: Cosmic rune + qty_per_cycle: 1 + source: ge + ge_limit: 18000 + profit_drivers: + - "Spread per unit x trade volume; volume is the safety factor (high-volume items fill faster and drift less)" + - "Slot breadth: cover as many net-positive candidates as capital allows (standard 8 slots)" + - "Snapshot 2026-08-27 top 8 by modeled 4h/slot: Rune arrowtips 161,200 (buy 223 / sell 244 / limit 10000); Iron bar 88,600 (145/157/10000); Cosmic rune 61,920 (122/128/18000); Magic logs 61,680 (772/793/12000); Silver ore 57,460 (73/79/13000); Mud rune 53,640 (96/101/18000); Raw swordfish 41,100 (206/213/15000); Raw lobster 27,000 (106/110/15000)" + - "Post-2%-fee reality: 11 of 21 classic staples are net-positive at band edges; sub-2%-spread items (law/chaos/blood runes, dragon bones, adamantite/mithril bars) need sub-low buys or above-high sells" + +state_machine: + initial: idle + terminal: [complete, failed] + states: + idle: + goal: be logged in at a bank with a GE booth, capital >= floor + next: [scan, complete, failed] + scan: + goal: read the current high/low band for every candidate + next: [buy, idle] + buy: + goal: place one resting buy offer per slot at or below the low edge + next: [wait_fill, collect, idle] + wait_fill: + goal: hold offers; re-quote any approaching the 4h window lapse + next: [sell, buy, collect] + sell: + goal: place one sell offer per filled slot at or above the high edge + next: [wait_fill, collect] + collect: + goal: collect proceeds, deposit coins, log the cycle + next: [scan, complete, idle] + complete: + goal: session GP target reached + failed: + goal: hard failure — stop, log ERROR sentinel, alert + transitions: + - from: idle + when: "capital below floor OR session target reached" + to: complete + - from: scan + when: "no candidate net-positive at band edges on 3 consecutive scans" + to: idle + - from: buy + when: "all slots quoted" + to: wait_fill + - from: wait_fill + when: "all pending buys filled" + to: sell + - from: wait_fill + when: "4h window lapse with unfilled offers" + to: collect + - from: sell + when: "sells placed" + to: wait_fill + - from: collect + when: "session GP target reached" + to: complete + - from: collect + when: "rotation done and window open" + to: scan + +actions: + - id: a1 + step: reach-ge + verb: move_to + target: "bank with Grand Exchange booth" + params: + location: "Grand Exchange (Varrock) area bank" + method: [teleport, walk] + on_fail: retry + anti_ban: + delay: [400, 1600] + + - id: a2 + step: open-ge + verb: ge_open + target: grand-exchange + params: + booth: "GE counter or bank booth" + on_fail: retry + anti_ban: + delay: [800, 1800] + + - id: a3 + step: scan-bands + verb: ge_check_price + target: "current candidates" + params: + items: "top-N candidates from the entry table" + band: "high and low edge per item" + on_fail: skip + anti_ban: + delay: [1200, 2800] + + - id: a4 + step: place-buys + verb: ge_buy + target: grand-exchange + params: + item: "per candidate slot" + qty: "min(remaining 4h limit, slot capacity)" + price: "low edge (rounded down)" + max_price: "low edge — never instant" + on_fail: skip + anti_ban: + delay: [900, 2700] + + - id: a5 + step: hold-fills + verb: sleep + params: + delay: [6000, 12000] + until: "ge_offers_done changes or 4h window lapse" + on_fail: retry + anti_ban: + delay: [300, 900] + + - id: a6 + step: place-sells + verb: ge_sell + target: grand-exchange + params: + item: "per filled slot" + qty: "filled quantity" + price: "high edge (rounded up)" + on_fail: skip + anti_ban: + delay: [900, 2700] + + - id: a7 + step: collect-and-log + verb: ge_collect + target: grand-exchange + params: + deposit: "coins to bank" + log: "RESULT item, qty, net gp per slot" + on_fail: alert + anti_ban: + delay: [600, 1400] + +run_control: + iteration: "one full buy -> fill -> sell -> collect rotation across all slots" + max_iterations: null + break: + every: [6, 10] # rotations + for: [60, 240] # seconds of idle AFK + stop_conditions: + - "session GP target reached" + - "capital under floor" + - "no net-positive candidates on 3 consecutive scans" + - "3 consecutive aborted offers (client issue — do not loop)" + +risk: + ban_level: low + notes: + - "Flipping is standard gameplay; the detectable signal is quote churn — keep per-offer pacing humanised, never instant-buy/sell loops." + - "The 2% fee (since 2025-05-29) and 5M/item cap make sub-2%-spread staples unprofitable at band edges; re-scan before every rotation." + - "Thin/volatile items: a resting offer can sit for hours — cap quote lifetime to the 4h window and re-quote rather than chase." + +sources: + - "OSRS wiki — Grand Exchange (2% convenience fee since 2025-05-29, capped 5M/item, sub-50gp effectively untaxed, tax-exempt low-value items; buying rate restricted per 4h; connected limits; verified 2026-08-27)" + - "OSRS wiki — Grand Exchange/Buying limits (4h window mechanics)" + - "OSRS wiki — Merchanting (flipping = spread exploitation; high trade volume = safety; bulk flipping needs ~20M+ cash; avoid static-price items; offer matching at or better than your price)" + - "prices.runescape.wiki/api/v1/osrs/mapping (item ids, members flags, limits — limits cross-checked against Module:Exchange/, all agree)" + - "prices.runescape.wiki/api/v1/osrs/latest (high/low price band snapshot 2026-08-27)" +verified: "2026-08-27" # keep quoted (YAML 1.1 date parsing) + +related: + - low-alch-f2p + - f2p-alch-catalog + - mule-topup