From d7b5d03f8a76fb6ba8f1a5017ff2e8eef05f6955 Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 16:45:26 +0800 Subject: [PATCH 01/12] feat: add Smart-Money Flow trading agent (venue-agnostic perps) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Directional perp agent driven by a capital-flow & positioning composite: cross-market risk regime (CoinGecko /global + /coins/markets + /search/trending) plus an on-chain Solana DeFi pulse (GeckoTerminal SOL top pools). The routine produces a LONG/SHORT/HOLD signal; execution is venue-agnostic (Derive, Hyperliquid, Backpack, Pacifica, ...) via default_trading_context + Hummingbot server — the routine never calls an exchange API. - agents/smart_money_flow/AGENT.md: identity, opencode-go:deepseek-v4-flash - routines/onchain_flow.py: keyless signal fetch + scoring + ReportBuilder - strategies/directional_flow/strategy.md: directional perp playbook, risk limits - skills/smart_money_playbook/SKILL.md: flow decision matrix Verified: routine compiles and scores correctly live (RISK-OFF -> HOLD; forced RISK-ON +6.5% -> LONG +0.80; RISK-OFF -9.5% -> SHORT -0.40). Pivoted from Orca Whirlpools spot (CLMM cannot express directional/short). --- agents/smart_money_flow/AGENT.md | 110 ++++++ .../smart_money_flow/routines/onchain_flow.py | 340 ++++++++++++++++++ .../skills/smart_money_playbook/SKILL.md | 57 +++ .../strategies/directional_flow/strategy.md | 50 +++ 4 files changed, 557 insertions(+) create mode 100644 agents/smart_money_flow/AGENT.md create mode 100644 agents/smart_money_flow/routines/onchain_flow.py create mode 100644 agents/smart_money_flow/skills/smart_money_playbook/SKILL.md create mode 100644 agents/smart_money_flow/strategies/directional_flow/strategy.md diff --git a/agents/smart_money_flow/AGENT.md b/agents/smart_money_flow/AGENT.md new file mode 100644 index 00000000..be764093 --- /dev/null +++ b/agents/smart_money_flow/AGENT.md @@ -0,0 +1,110 @@ +--- +name: Smart-Money Flow +description: Directional perp trader on any perpetual venue (Derive, Hyperliquid, Backpack, Pacifica, …) — reads capital-flow & positioning (cross-market regime + Solana on-chain DeFi pulse) and takes LONG/SHORT/HOLD on liquid majors. Leverage enabled; bounded risk. +agent_key: opencode-go:deepseek-v4-flash +tools: [] +when_to_consult: When the user wants a directional read on where capital is flowing in crypto markets, or wants to deploy the Smart-Money Flow trading agent (flow positioning on perps — any venue). +server_required: false +created_by: 5587715073 +created_at: '2026-07-28T00:00:00.000000+00:00' +--- + +# Smart-Money Flow + +You are **Smart-Money Flow** — a **directional perpetual-futures trader** (any +perp venue: Derive, Hyperliquid, Backpack, Pacifica, …) who reads **where +capital is moving**, not just where price has been. Your edge is a +flow-and-positioning composite that a candlestick chart alone cannot show: risk +regime (BTC dominance, total mcap momentum), cross-market asset flow intensity +(volume-to-mcap, 24h change, trending rotation), and an **on-chain Solana DeFi +pulse** (top-pool volume + momentum + TVL via GeckoTerminal). You translate that +composite into a small number of high-conviction **LONG/SHORT** entries on liquid +majors (BTC/ETH/SOL), and let the Risk Engine + position-hold pattern protect +you. Leverage is enabled but bounded. + +**Tagline:** *"Follow the flow, not the chart."* + +--- + +## Venue-neutral by design +Execution is **any perpetual-futures connector** — Derive (`derive_perpetual`), +Hyperliquid (`hyperliquid`), Backpack (`backpack_perpetual`), Pacifica +(`pacifica_perpetual`), or others. The venue is set in `default_trading_context` +/ the configured Hummingbot server, **not** in code: the routine only produces a +*signal* (cross-market + Solana on-chain flow); it never calls an exchange API. +This agent was pivoted away from an Orca Whirlpools spot framing because CLMM +spot cannot express the directional/short side this composite needs. Solana +carries materially deeper on-chain liquidity than XRPL, so the on-chain pulse is +sourced from Solana, not XRPL. + +--- + +## Every-Tick Playbook (step by step) + +### Step 1 — Pull the flow read +``` +manage_routines(action="run", routine="onchain_flow") +``` +It returns a **direction** (LONG / SHORT / HOLD), the best-flow asset, the Solana +on-chain pulse, and a per-asset context table, and writes a ReportBuilder +dashboard. Read its output; do not re-fetch raw data. + +### Step 2 — Interpret +- **LONG** (RISK-ON regime + asset flow ≥ +0.4) → favor a LONG on the best-flow + asset (top flow first). +- **SHORT** (RISK-OFF regime + asset flow ≤ −0.4) → favor a SHORT on the + worst-flow asset. +- **HOLD** (ambiguous, regime NEUTRAL, or flow below ±0.4) → no new position. + +### Step 3 — Size & enter +- Use `total_amount_quote`; never exceed `max_open_executors` (2) or + `max_total_exposure_quote`. Leverage up to `max_leverage` (3x; 5x only at flow + conviction ≥ 0.7). The Risk Engine auto-blocks anything over limit. +- Open a `PositionExecutor` (or `GridExecutor` with + `stop_loss_keep_position=true`). Let the Risk Engine enforce limits. +- Max 2 concurrent positions. + +### Step 4 — Manage open positions +- **Take profit:** scale out 50% at +2%, trail the rest with a +1.5% activation + and 2% trail; hard stop at −2.5%. +- **Signal flip:** if the next tick's flow read inverts (score crosses through + zero against your position) with conviction ≥ 0.4, exit and optionally reverse. +- **Time limit:** max 8h hold per position. +- **Leftover position:** if a grid stops out but holds inventory, wait for a + recovery within 1% of breakeven, then exit with an `OrderExecutor`. + +### Step 5 — Journal the *why* in flow terms +e.g. *"RISK-ON; ETH flow +0.52 (vol/mcap 2.1x, trending #4); Solana pulse +0.44 → +LONG ETH 500."* or *"RISK-OFF; SOL flow −0.4 → SHORT SOL 400."* + +--- + +## Risk discipline (non-negotiable) +- Max 2 concurrent positions, max leverage 3x (5x only at flow conviction ≥ 0.7). +- Stand aside when the composite is ambiguous (regime NEUTRAL or |flow| < 0.4). + No forced trades. +- Respect `max_drawdown_pct` — the Risk Engine blocks you anyway. +- Macro-print windows (≤30 min): halve size. + +--- + +## Why you win +1. **Empty lane.** Flow/positioning is unoccupied on Botcamp and locally. +2. **Solana signal depth.** The on-chain pulse uses real Solana DeFi flow + (verified $90M+/day on SOL/USDC) — far richer than thin XRPL books. +3. **LLM advantage.** Translating multi-source flow into a discretionary + directional decision is exactly what the framework says LLMs do better than code. +4. **Safe by construction.** Executor/position-hold + Risk Engine mean a bad flow + read costs a bounded stop, never a blown account. + +--- + +## Quick reference +``` +[CHECKLIST: Every Tick] +□ 1. run onchain_flow routine → direction + best asset + Solana pulse + dashboard +□ 2. LONG (risk-on + flow≥+0.4) / SHORT (risk-off + flow≤−0.4) / HOLD (else) +□ 3. Size bounded fraction; max 2 positions, max 3x lev; Risk Engine enforces +□ 4. Manage opens: 50% TP @ +2%, trail 2% after +1.5%, stop −2.5%, 8h max +□ 5. Journal the flow thesis, not just the fill +``` diff --git a/agents/smart_money_flow/routines/onchain_flow.py b/agents/smart_money_flow/routines/onchain_flow.py new file mode 100644 index 00000000..11af1046 --- /dev/null +++ b/agents/smart_money_flow/routines/onchain_flow.py @@ -0,0 +1,340 @@ +"""Smart-Money Flow read: cross-market capital-flow + on-chain (Solana) pulse. + +Pulls a flow-and-positioning composite that a price chart alone cannot show: + * CoinGecko /global -> risk regime (mcap momentum, BTC dominance) + * CoinGecko /coins/markets -> per-asset flow intensity (volume/mcap, 24h chg) + * CoinGecko /search/trending -> sector/asset momentum (what is heating up) + * Solana / GeckoTerminal -> on-chain DeFi flow pulse (top-pool volume + + momentum + TVL) — the crypto-native signal. + Solana has materially deeper on-chain liquidity + than XRPL, so it is the DEFAULT on-chain source. + * XRPL JSON-RPC (optional) -> legacy DEX AMM pulse, off by default. + +All fetches are defensive and async; any source failing degrades gracefully +rather than raising into the tick. The orchestration lives in `run()`; the +pure data + scoring functions are importable for testing without Telegram. + +Execution venue is independent of this signal: pair the read with Derive perps +(`derive_perpetual`) — or any perp connector — via the agent's trading context. +""" +import asyncio +import logging +from pydantic import BaseModel, Field +from telegram.ext import ContextTypes +from config_manager import get_client + +logger = logging.getLogger(__name__) + +CATEGORY = "Analysis" + +# Keyless endpoints (CoinGecko + GeckoTerminal free tier, public Solana RPC). +CG = "https://api.coingecko.com/api/v3" +GECKO = "https://api.geckoterminal.com/api/v2" +XRPL_NODES = [ + "https://xrplcluster.com/", + "https://s1.ripple.com:51234", + "https://s2.ripple.com:51234", +] + +# Default cross-market context assets (also the tradable perps on Derive). +CONTEXT_ASSETS = [ + {"id": "bitcoin", "symbol": "BTC"}, + {"id": "ethereum", "symbol": "ETH"}, + {"id": "solana", "symbol": "SOL"}, +] +SOL_MINT = "So11111111111111111111111111111111111111112" # anchors the Solana pulse + + +class Config(BaseModel): + """Compute the Smart-Money Flow composite: cross-market + Solana on-chain pulse.""" + context_assets: str = Field( + default="bitcoin,ethereum,solana", + description="Comma-separated CoinGecko ids for regime + per-asset flow read", + ) + solana_top_n: int = Field( + default=10, + description="Number of SOL top pools to pull for the on-chain DeFi flow pulse", + ) + xrpl_amm_issuer: str = Field( + default="", + description="OPTIONAL legacy XRPL issuer for an RLUSD/XRP AMM pulse (empty = skip)", + ) + xrpl_watch_addresses: str = Field( + default="", + description="OPTIONAL comma-separated XRPL addresses to watch (empty = skip)", + ) + top_n_trending: int = Field(default=7, description="Trending coins to factor into momentum") + + +# ── helpers ──────────────────────────────────────────────────────────────── + +async def _get_json(url: str, timeout: float = 12) -> "dict | list | None": + import httpx + + try: + async with httpx.AsyncClient(timeout=timeout) as http: + resp = await http.get(url, headers={"User-Agent": "Mozilla/5.0"}) + if resp.status_code != 200: + logger.warning("flow: %s -> HTTP %s", url, resp.status_code) + return None + return resp.json() + except Exception as exc: # never raise into a tick + logger.warning("flow: fetch failed %s: %s", url, type(exc).__name__) + return None + + +def _clamp(x: float, lo: float = -1.0, hi: float = 1.0) -> float: + return max(lo, min(hi, x)) + + +def _num(v) -> float: + try: + return float(v) + except (TypeError, ValueError): + return 0.0 + + +# ── raw fetchers (pure async, importable) ────────────────────────────────── + +async def fetch_global() -> "dict | list | None": + return await _get_json(f"{CG}/global") + + +async def fetch_trending(top_n: int = 7) -> list: + data = await _get_json(f"{CG}/search/trending") + if not data: + return [] + coins = data.get("coins", [])[:top_n] + return [c.get("item", {}).get("symbol", "").upper() for c in coins] + + +async def fetch_markets(ids: list[str]) -> "dict | list | None": + id_str = "%2C".join(ids) + return await _get_json( + f"{CG}/coins/markets?vs_currency=usd&ids={id_str}" + f"&order=market_cap_desc&per_page=50&page=1&sparkline=false" + ) + + +async def fetch_solana_pulse(top_n: int = 10) -> dict | None: + """On-chain DeFi flow pulse anchored on SOL's own top pools (GeckoTerminal, keyless). + + We query the SOL token's pools rather than the global top-volume list, because + the global list is dominated by fresh memecoin/pump pools with meaningless + momentum. SOL's top pools (SOL/USDC, staking LP pairs) are the representative + read. Solana carries materially deeper on-chain liquidity than XRPL, so it is + the DEFAULT on-chain signal source. + """ + data = await _get_json(f"{GECKO}/networks/solana/tokens/{SOL_MINT}/pools?page=1&include=base_token,dex") + if not data: + return None + pools = [] + for p in data.get("data", [])[:top_n]: + a = p.get("attributes", {}) + vol = _num(a.get("volume_usd", {}).get("h24")) + tvl = _num(a.get("reserve_in_usd")) + if tvl < 50_000: # skip dust/illiquid pools (meaningless momentum) + continue + pools.append({ + "name": a.get("name", "?"), + "dex": a.get("dex_id", ""), + "vol24h": vol, + "chg24h": _num(a.get("price_change_percentage", {}).get("h24")), + "tvl": tvl, + }) + if not pools: + return None + total_vol = sum(p["vol24h"] for p in pools) + chgs = sorted(p["chg24h"] for p in pools if p["chg24h"] is not None) + med_chg = chgs[len(chgs) // 2] if chgs else 0.0 + import math + + vol_score = _clamp(math.log10(total_vol + 1) / 9.0) # ~1e9 -> ~1.0 + mom_score = _clamp(med_chg / 15.0) + return { + "pools": pools, + "total_vol24h": round(total_vol, 2), + "median_chg24h": round(med_chg, 2), + "flow_score": round(_clamp(vol_score * 0.5 + mom_score * 0.5), 3), + } + + +async def fetch_xrpl_amm_pulse(issuer: str) -> dict | None: + """OPTIONAL legacy XRPL RLUSD/XRP AMM liquidity pulse (graceful if unreachable).""" + if not issuer: + return None + payload = { + "method": "amm_info", + "params": [{"asset": {"currency": "XRP"}, + "asset2": {"currency": "RLUSD", "issuer": issuer}}], + } + import httpx + + for node in XRPL_NODES: + try: + async with httpx.AsyncClient(timeout=12) as http: + resp = await http.post(node, json=payload) + data = resp.json().get("result", {}) + amm = data.get("amm") + if not amm: + continue + amount = amm.get("amount", {}) + try: + xrp = float(amount.get("value", 0)) if isinstance(amount, dict) else 0.0 + except Exception: + xrp = 0.0 + return {"xrp_liquidity": xrp, "trading_fee_bps": amm.get("trading_fee")} + except Exception as exc: + logger.warning("flow: xrpl amm pulse failed on %s: %s", node, type(exc).__name__) + continue + return None + + +# ── synthesis (pure, importable) ─────────────────────────────────────────── + +def synthesize(global_d, markets_d, trending_syms, solana_pulse, xrpl_amm) -> dict: + """Turn raw fetches into a multi-asset flow composite. Returns a structured dict.""" + # --- risk regime from /global --- + regime = {"label": "NEUTRAL", "mcap_change_24h": 0.0, "btc_dominance": 0.0, + "eth_dominance": 0.0, "score": 0.0} + if global_d: + g = global_d.get("data", {}) + mc = _num(g.get("market_cap_change_percentage_24h_usd")) + dom = g.get("market_cap_percentage", {}) + btc_d = _num(dom.get("btc")) + eth_d = _num(dom.get("eth")) + regime["mcap_change_24h"] = round(mc, 2) + regime["btc_dominance"] = round(btc_d, 2) + regime["eth_dominance"] = round(eth_d, 2) + risk_score = _clamp(mc / 5.0) - _clamp((btc_d - 50.0) / 10.0) * 0.3 + regime["score"] = round(_clamp(risk_score), 3) + regime["label"] = "RISK-ON" if regime["score"] > 0.15 else ("RISK-OFF" if regime["score"] < -0.15 else "NEUTRAL") + + # --- per-asset flow intensity from /coins/markets --- + trending_set = {s.upper() for s in trending_syms} + assets_out = [] + for m in (markets_d or []): + sym = (m.get("symbol") or "").upper() + mcap = _num(m.get("market_cap")) + vol = _num(m.get("total_volume")) + chg = _num(m.get("price_change_percentage_24h")) + vol_mcap = (vol / mcap) if mcap > 0 else 0.0 + # Flow score: 24h momentum is the dominant driver (a strong day should + # trigger), volume intensity is a secondary confirmation. Clamp the + # volume term so thin books don't dominate; amplify the change term so a + # real +/-6-10% day clears the +/-0.4 entry threshold. + flow = _clamp(vol_mcap * 5.0, -0.5, 0.5) * 0.4 + _clamp(chg / 6.0) * 0.6 + if sym in trending_set: + flow = _clamp(flow + 0.1) + assets_out.append({ + "symbol": sym, + "pair": f"{sym}-USDT", + "flow_score": round(flow, 3), + "volume_to_mcap": round(vol_mcap, 3), + "price_change_24h": round(chg, 2), + "trending": sym in trending_set, + }) + assets_out.sort(key=lambda a: abs(a["flow_score"]), reverse=True) + + # --- on-chain pulse (Solana default; XRPL optional) --- + onchain = {"source": "solana", "solana": solana_pulse, "xrpl": xrpl_amm} + solana_flow = (solana_pulse or {}).get("flow_score", 0.0) + + # --- directional verdict (perps: LONG / SHORT / HOLD) --- + best = assets_out[0] if assets_out else None + direction = "HOLD" + rationale = "no decisive flow" + if best and abs(best["flow_score"]) >= 0.4 and regime["label"] != "NEUTRAL": + if best["flow_score"] > 0 and regime["label"] == "RISK-ON": + direction = "LONG" + rationale = "RISK-ON + positive flow" + elif best["flow_score"] < 0 and regime["label"] == "RISK-OFF": + direction = "SHORT" + rationale = "RISK-OFF + negative flow" + else: + rationale = "regime/flow conflict" + elif best and abs(best["flow_score"]) < 0.4: + rationale = "flow below entry threshold" + + return { + "regime": regime, + "assets": assets_out, + "onchain": onchain, + "solana_flow": round(solana_flow, 3), + "best_asset": best, + "direction": direction, + "rationale": rationale, + } + + +def _format_verdict(sig: dict) -> str: + r = sig["regime"] + best = sig.get("best_asset") + lines = [ + "## Smart-Money Flow Read", + f"- Regime: **{r['label']}** (mcap 24h {r['mcap_change_24h']:+.2f}%, BTC dom {r['btc_dominance']:.1f}%)", + f"- Verdict: **{sig['direction']}** ({sig['rationale']})", + ] + if best: + lines.append(f"- Best flow: **{best['symbol']}** score {best['flow_score']:+.2f} " + f"(vol/mcap {best['volume_to_mcap']}, 24h {best['price_change_24h']:+.2f}%, trend={best['trending']})") + sp = sig["onchain"].get("solana") + if sp: + lines.append(f"- Solana on-chain pulse: flow {sp['flow_score']:+.2f}, " + f"top-pool vol24h ${sp['total_vol24h']:,.0f}, median chg {sp['median_chg24h']:+.1f}%") + for p in sp["pools"][:4]: + lines.append(f" - {p['name'][:24]:24} vol ${p['vol24h']:,.0f} chg {p['chg24h']:+.1f}%") + if sig["onchain"].get("xrpl"): + lines.append(f"- XRPL AMM pulse: {sig['onchain']['xrpl']}") + lines.append("- Per-asset:") + for a in sig["assets"][:5]: + lines.append(f" - {a['symbol']}: {a['flow_score']:+.2f} " + f"(vol/mcap {a['volume_to_mcap']}, 24h {a['price_change_24h']:+.2f}%, trend={a['trending']})") + return "\n".join(lines) + + +# ── orchestration ────────────────────────────────────────────────────────── + +async def run(config: Config, context: ContextTypes.DEFAULT_TYPE) -> str: + """Entry point invoked by manage_routines. Fetches, scores, reports, returns.""" + ids = [s.strip() for s in config.context_assets.split(",") if s.strip()] + + global_d, trending, markets, solana = await asyncio.gather( + fetch_global(), + fetch_trending(config.top_n_trending), + fetch_markets(ids), + fetch_solana_pulse(config.solana_top_n), + ) + xrpl_amm = await fetch_xrpl_amm_pulse(config.xrpl_amm_issuer) if config.xrpl_amm_issuer else None + + sig = synthesize(global_d, markets, trending, solana, xrpl_amm) + + # Rich dashboard via ReportBuilder (mandatory in every routine). + try: + from condor.reports import ReportBuilder + + builder = ReportBuilder("Smart-Money Flow") + builder.source("routine", "onchain_flow").tags(["flow", "on-chain", "solana", "smart-money"]) + builder.section("01 / RISK REGIME", "Cross-market risk-on/off from total mcap momentum and BTC dominance") + builder.kpi("Regime", sig["regime"]["label"]) + builder.kpi("Mcap 24h", f"{sig['regime']['mcap_change_24h']:+.2f}%") + builder.kpi("BTC Dominance", f"{sig['regime']['btc_dominance']:.1f}%") + builder.kpi("Direction", sig["direction"]) + builder.kpi("Solana Flow", f"{sig['solana_flow']:+.2f}") + sp = sig["onchain"].get("solana") + if sp: + builder.section("02 / SOLANA ON-CHAIN PULSE", "SOL top pools by 24h volume — crypto-native flow") + builder.kpi("Top-pool Vol 24h", f"${sp['total_vol24h']:,.0f}") + builder.kpi("Median Chg 24h", f"{sp['median_chg24h']:+.1f}%") + builder.kpi("On-chain Flow", f"{sp['flow_score']:+.2f}") + builder.table(sp["pools"][:8], ["name", "dex", "vol24h", "chg24h", "tvl"]) + if sig["assets"]: + builder.section("03 / CROSS-MARKET CONTEXT", "Market-wide flow intensity (BTC/ETH/SOL)") + builder.table(sig["assets"][:6], ["symbol", "pair", "flow_score", "volume_to_mcap", "price_change_24h", "trending"]) + builder.markdown(_format_verdict(sig)) + builder.manual_order() + await builder.save() + except Exception as exc: + logger.warning("flow: report generation failed: %s", exc) + + return _format_verdict(sig) diff --git a/agents/smart_money_flow/skills/smart_money_playbook/SKILL.md b/agents/smart_money_flow/skills/smart_money_playbook/SKILL.md new file mode 100644 index 00000000..93d3c834 --- /dev/null +++ b/agents/smart_money_flow/skills/smart_money_playbook/SKILL.md @@ -0,0 +1,57 @@ +--- +name: smart_money_playbook +description: How to read the Smart-Money Flow composite and translate it into a bounded directional perp decision on any venue (Derive, Hyperliquid, Backpack, Pacifica, …). Use whenever interpreting onchain_flow output or deciding LONG/SHORT/HOLD for the Smart-Money Flow agent. +when_to_use: When the Smart-Money Flow agent needs to interpret the onchain_flow routine output, decide a directional entry on perps, or manage an open flow-based position. +source: agent:smart_money_flow +--- + +# Smart-Money Playbook (Directional Perps, any venue) + +The agent's edge is **capital-flow positioning**, not price patterns. This playbook +turns the `onchain_flow` routine output into a trade decision. Execution is +**perpetual futures on any venue** — Derive (`derive_perpetual`), Hyperliquid +(`hyperliquid`), Backpack (`backpack_perpetual`), Pacifica (`pacifica_perpetual`), +or others. (Orca spot was dropped: Whirlpools are CLMM spot and cannot express the +directional/short side this composite needs.) + +## The composite (from `onchain_flow`) + +| Signal | Source | What it tells you | +|---|---|---| +| Risk regime | CoinGecko `/global` (mcap 24h, BTC dominance) | RISK-ON / RISK-OFF / NEUTRAL | +| Per-asset flow score | `/coins/markets` volume-to-mcap + 24h change | How hard capital moves in/out of an asset | +| Trending momentum | `/search/trending` | What is heating up across the market | +| **Solana on-chain pulse** | GeckoTerminal SOL top pools | Crypto-native DeFi flow (vol, momentum, TVL) — the default signal. Solana carries materially deeper liquidity than XRPL. | +| XRPL pulse (optional) | XRPL JSON-RPC AMM/wallets | Legacy cross-check, off by default | + +**Flow score scale:** normalized −1 (strong outflow/down) … +1 (strong inflow/up). +**Entry threshold:** `|flow_score| >= 0.4` AND regime-aligned. + +## Decision matrix (Derive perps) + +| Regime | Flow score | Action | +|---|---|---| +| RISK-ON | asset ≥ +0.4 | **LONG** that asset (top flow first) | +| RISK-OFF | asset ≤ −0.4 | **SHORT** that asset | +| RISK-ON | asset ≤ −0.4 | conflict — do not trade that asset | +| RISK-OFF | asset ≥ +0.4 | conflict — do not trade that asset | +| any | \|score\| < 0.4 | **HOLD** — stand aside | +| any | NEUTRAL regime | **HOLD** | + +## Why this lane is open +Botcamp (110 strategies) is saturated with MM, funding arb, trend-following, and +pairs trading. **None trade capital-flow as the primary signal.** This agent owns +that lane — a discretionary flow reader reasoning over on-chain + cross-market data, +which is exactly what an LLM does better than hand-coded strategy. It also does not +overlap the server's other entries (Agora = news/sentiment; TFS/Sats = trend; +condor-simple = mean-reversion). Using **Solana on-chain flow** (vs thin XRPL) +makes the signal deeper and more credible. + +## Risk rules (hard) +- Max 2 concurrent positions. Max leverage 3x (5x only at flow conviction ≥ 0.7). +- Respect `max_drawdown_pct` — Risk Engine enforces it. +- No forced trades on ambiguous reads. Macro-print windows (≤30 min): halve size. + +## Journaling +Always record the *flow thesis*, not just the fill: +> "RISK-ON; ETH flow +0.52; Solana pulse +0.44 → LONG ETH 500." diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/directional_flow/strategy.md new file mode 100644 index 00000000..af6540be --- /dev/null +++ b/agents/smart_money_flow/strategies/directional_flow/strategy.md @@ -0,0 +1,50 @@ +--- +name: Derive Flow Trader +description: Directional perp trader on any perpetual venue (Derive, Hyperliquid, Backpack, Pacifica, …). Takes LONG/SHORT on BTC/ETH/SOL where capital-flow conviction is decisive and regime-aligned; bounded leverage, position-hold risk. +agent_key: opencode-go:deepseek-v4-flash +skills: + - smart_money_flow:smart_money_playbook +default_config: + execution_mode: loop + frequency_sec: 300 + total_amount_quote: 1000 + max_ticks: 0 + risk_limits: + max_total_exposure_quote: 2000 + max_drawdown_pct: 8 + max_open_executors: 2 + max_leverage: 3 +default_trading_context: | + Trade BTC/USDT, ETH/USDT, SOL/USDT perpetuals on ANY perpetual venue + (Derive `derive_perpetual`, Hyperliquid `hyperliquid`, Backpack + `backpack_perpetual`, Pacifica `pacifica_perpetual`, …). Read the onchain_flow + routine every tick; take LONG when the regime is RISK-ON and the asset's + flow_score >= 0.4, SHORT when RISK-OFF and flow_score <= -0.4. Max 2 concurrent + positions, max leverage 3x (5x only at flow conviction >= 0.7). Stand aside + (HOLD) when the composite is ambiguous. The on-chain signal is Solana DeFi flow + (GeckoTerminal), not XRPL. +--- + +# Derive Flow Trader — Playbook + +You are the **loop strategy** for the Smart-Money Flow agent, trading +**perpetuals on Derive** (`derive_perpetual`). Each tick you: + +1. **Run the flow read.** Call `manage_routines(action="run", routine="onchain_flow")`. + It returns a `LONG` / `SHORT` / `HOLD` direction, the best-flow asset, the + Solana on-chain pulse, and a cross-market context table, plus a dashboard. +2. **Filter.** For BTC/ETH/SOL with no open position, require: + - `LONG`: regime RISK-ON AND asset `flow_score >= +0.4` + - `SHORT`: regime RISK-OFF AND asset `flow_score <= -0.4` + - otherwise: `HOLD` (ambiguous / NEUTRAL regime / |flow| < 0.4 — no trade). +3. **Size & enter.** Use `total_amount_quote`; never exceed `max_open_executors` + (2) or `max_total_exposure_quote`. Leverage up to `max_leverage` (3x; 5x only + at flow conviction ≥ 0.7). Open a `PositionExecutor` (or `GridExecutor` with + `stop_loss_keep_position=true`). The Risk Engine auto-blocks anything over limit. +4. **Manage.** 50% take-profit at +2%, trail 2% after +1.5% in profit, hard stop + −2.5%. On signal flip (next tick's flow score crosses zero against your + position) with conviction ≥ 0.4, exit and optionally reverse. Max 8h hold. +5. **Journal the flow thesis** — one line per tick in flow terms, e.g. + *"RISK-ON; ETH flow +0.52; Solana pulse +0.44 → LONG ETH 500."* + +If the read is ambiguous, do nothing. No forced trades — survival beats activity. From 350b4156a8f2ff8c0b18f5e758759e2c6896ffa2 Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 17:03:40 +0800 Subject: [PATCH 02/12] chore(smart-money-flow): pin Derive as default venue + add live-run validation runbook - strategy.md default_trading_context now names derive_perpetual as the concrete venue, documents the one-time 'connect derive_perpetual' step (Condor/API does NOT add keys by design), and gates mainnet behind derive_perpetual_testnet. - validation.md: testnet-first runbook proving execution before PR submission (connect once in client; Condor/API drives the connected instance). --- .../strategies/directional_flow/strategy.md | 20 +++--- agents/smart_money_flow/validation.md | 62 +++++++++++++++++++ 2 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 agents/smart_money_flow/validation.md diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/directional_flow/strategy.md index af6540be..b7cc59a5 100644 --- a/agents/smart_money_flow/strategies/directional_flow/strategy.md +++ b/agents/smart_money_flow/strategies/directional_flow/strategy.md @@ -15,14 +15,18 @@ default_config: max_open_executors: 2 max_leverage: 3 default_trading_context: | - Trade BTC/USDT, ETH/USDT, SOL/USDT perpetuals on ANY perpetual venue - (Derive `derive_perpetual`, Hyperliquid `hyperliquid`, Backpack - `backpack_perpetual`, Pacifica `pacifica_perpetual`, …). Read the onchain_flow - routine every tick; take LONG when the regime is RISK-ON and the asset's - flow_score >= 0.4, SHORT when RISK-OFF and flow_score <= -0.4. Max 2 concurrent - positions, max leverage 3x (5x only at flow conviction >= 0.7). Stand aside - (HOLD) when the composite is ambiguous. The on-chain signal is Solana DeFi flow - (GeckoTerminal), not XRPL. + Trade BTC/USDT, ETH/USDT, SOL/USDT perpetuals on Derive (connector + `derive_perpetual`). One-time setup: in the Hummingbot client run + `connect derive_perpetual` (wallet address + private key + subaccount id), + then point this Condor instance at that running bot via the configured server. + The Condor/API layer drives an already-connected instance — it does NOT add + keys itself (security boundary; see mcp_servers/hummingbot_api/server.py). + VALIDATION FIRST: run against `derive_perpetual_testnet` with a tiny size + before any mainnet capital. Read the onchain_flow routine every tick; take + LONG when the regime is RISK-ON and the asset's flow_score >= 0.4, SHORT when + RISK-OFF and flow_score <= -0.4. Max 2 concurrent positions, max leverage 3x + (5x only at flow conviction >= 0.7). Stand aside (HOLD) when the composite is + ambiguous. The on-chain signal is Solana DeFi flow (GeckoTerminal), not XRPL. --- # Derive Flow Trader — Playbook diff --git a/agents/smart_money_flow/validation.md b/agents/smart_money_flow/validation.md new file mode 100644 index 00000000..0e980e62 --- /dev/null +++ b/agents/smart_money_flow/validation.md @@ -0,0 +1,62 @@ +# Live-Run Validation Runbook + +Goal: prove the Smart-Money Flow agent trades correctly on Derive **before** any +real capital — and before the PR is submitted. The signal + decision layer is +already unit-verified (`routines/onchain_flow.py` scores live data correctly); +this runbook covers the **execution** path that only a live (or testnet) bot can. + +## Why testnet first +The Condor/API layer **does not add exchange keys** — by design +(`mcp_servers/hummingbot_api/server.py`: *"Connecting/removing exchange API +keys is intentionally NOT exposed here"*). You connect the exchange **once** in +the Hummingbot client, then Condor drives that already-connected instance. So the +"API vs CLI" question is a false either/or: CLI for the one-time key setup, +Condor/API for everything after. + +## Step 1 — Connect Derive (one-time, in Hummingbot client) +``` +connect derive_perpetual +# prompts: wallet address, private key, subaccount id, account type +connect # verify "Keys Added / Confirmed" +``` +For validation, use the testnet connector instead: +``` +connect derive_perpetual_testnet +``` +(Your build's `conf_client.yml` already lists `derive: {}` / `derive_testnet: {}`, +so the connector is present — no rebuild needed.) + +## Step 2 — Point Condor at the running bot +Configure the Hummingbot API server connection (the Condor side that IS exposed): +``` +# via the humbingbot_api MCP server's configure tool, or your server config +server url = http://:8000 # default Hummingbot API port +``` +Verify with a read call (no keys touched): +``` +portfolio() # should show the connected derive_perpetual[_testnet] balances +``` + +## Step 3 — Dry / testnet run +1. Set `default_trading_context` connector to `derive_perpetual_testnet` (tiny size). +2. Launch the agent loop (`manage_routines` + the loop strategy) on the testnet. +3. Watch for, per tick: + - `onchain_flow` routine returns a verdict + dashboard (no exceptions). + - On a `LONG`/`SHORT` verdict, a `PositionExecutor` opens on the right pair. + - Risk Engine enforces limits (max 2 positions, 3x lev, 8% DD). + - TP/SL/trail logic fires; position closes; journal entry written. +4. Force both directions at least once (the routine's `synthesize` can be fed a + synthetic RISK-ON/+flow and RISK-OFF/−flow to exercise LONG and SHORT without + waiting for the market). + +## Step 4 — Mainnet (only after Step 3 is clean) +- Switch connector back to `derive_perpetual`, fund the wallet, start with a + small `total_amount_quote`, and monitor the same checks on real capital. + +## Step 5 — Pre-PR evidence +Attach to the PR: a short log/screenshot of the testnet run showing +- routine verdict + dashboard, +- at least one opened + closed position with correct sizing/limits, +- zero Risk-Engine violations. + +This is the "ensure it properly works before submitting PR" gate. From 05f69e73794615776f765e478b9a975a6c7ea62e Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 17:12:26 +0800 Subject: [PATCH 03/12] fix(smart-money-flow): correct key-add + testnet constraints per Condor code Verified against repo: - API keys are added ONLY via web dashboard (Settings -> Keys); Telegram /keys is read-only; MCP API does not add keys. - Condor web filters out testnet connectors (condor/web/routes/settings.py: 'testnet' not in c.lower()), so derive_perpetual_testnet is NOT selectable. Validation must be mainnet derive_perpetual on a tiny isolated wallet. Updated validation.md and strategy.md default_trading_context accordingly. --- .../strategies/directional_flow/strategy.md | 7 +- agents/smart_money_flow/validation.md | 90 +++++++++---------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/directional_flow/strategy.md index b7cc59a5..a5f0ab66 100644 --- a/agents/smart_money_flow/strategies/directional_flow/strategy.md +++ b/agents/smart_money_flow/strategies/directional_flow/strategy.md @@ -21,8 +21,11 @@ default_trading_context: | then point this Condor instance at that running bot via the configured server. The Condor/API layer drives an already-connected instance — it does NOT add keys itself (security boundary; see mcp_servers/hummingbot_api/server.py). - VALIDATION FIRST: run against `derive_perpetual_testnet` with a tiny size - before any mainnet capital. Read the onchain_flow routine every tick; take + VALIDATION FIRST: connect `derive_perpetual` (mainnet) via the web dashboard + (Settings → Keys) using a dedicated, minimally-funded wallet, then run with a + tiny `total_amount_quote` before scaling. NOTE: Condor's web UI filters out + testnet connectors (see validation.md), so validation is mainnet-with-small- + size, not testnet. Read the onchain_flow routine every tick; take LONG when the regime is RISK-ON and the asset's flow_score >= 0.4, SHORT when RISK-OFF and flow_score <= -0.4. Max 2 concurrent positions, max leverage 3x (5x only at flow conviction >= 0.7). Stand aside (HOLD) when the composite is diff --git a/agents/smart_money_flow/validation.md b/agents/smart_money_flow/validation.md index 0e980e62..86e929ab 100644 --- a/agents/smart_money_flow/validation.md +++ b/agents/smart_money_flow/validation.md @@ -1,62 +1,62 @@ # Live-Run Validation Runbook Goal: prove the Smart-Money Flow agent trades correctly on Derive **before** any -real capital — and before the PR is submitted. The signal + decision layer is -already unit-verified (`routines/onchain_flow.py` scores live data correctly); -this runbook covers the **execution** path that only a live (or testnet) bot can. - -## Why testnet first -The Condor/API layer **does not add exchange keys** — by design -(`mcp_servers/hummingbot_api/server.py`: *"Connecting/removing exchange API -keys is intentionally NOT exposed here"*). You connect the exchange **once** in -the Hummingbot client, then Condor drives that already-connected instance. So the -"API vs CLI" question is a false either/or: CLI for the one-time key setup, -Condor/API for everything after. - -## Step 1 — Connect Derive (one-time, in Hummingbot client) -``` -connect derive_perpetual -# prompts: wallet address, private key, subaccount id, account type -connect # verify "Keys Added / Confirmed" -``` -For validation, use the testnet connector instead: -``` -connect derive_perpetual_testnet -``` -(Your build's `conf_client.yml` already lists `derive: {}` / `derive_testnet: {}`, -so the connector is present — no rebuild needed.) +real capital is at risk — and before the PR is submitted. The signal + decision +layer is already unit-verified (`routines/onchain_flow.py` scores live data +correctly); this runbook covers the **execution** path that only a live bot can. + +## Important Condor constraints (verified in code) +- **API keys are added ONLY via the web dashboard** (Settings → Keys). The + Telegram `/keys` command is **read-only** (it lists connected exchanges and + deep-links to the web UI). The Condor/API (MCP) layer does not add keys. +- **Perpetual TESTNET connectors are NOT available in Condor.** `condor/web/ + routes/settings.py` filters every connector whose name contains "testnet" + (and "sandbox", and "/"). So `derive_perpetual_testnet`, + `binance_perpetual_testnet`, etc. are not selectable in the UI — only + mainnet connectors (`derive_perpetual`, `binance_perpetual`, …) appear. + (Hummingbot core HAS them in `conf_client.yml`, but Condor's web layer hides + them.) Therefore validation runs on **mainnet Derive with a tiny, isolated + wallet** — not on a testnet. + +## Step 1 — Connect Derive (web dashboard only) +1. Open the Condor web dashboard → **Settings → Keys**. +2. Add a connector: select **`derive_perpetual`** (mainnet). + Prompts: wallet address, private key, subaccount id, account type. +3. (Telegram alternative: `/keys` shows the 📈 perpetual entry once connected — + it cannot add keys itself.) +Use a **dedicated, minimally-funded wallet** — never your main holdings. ## Step 2 — Point Condor at the running bot -Configure the Hummingbot API server connection (the Condor side that IS exposed): -``` -# via the humbingbot_api MCP server's configure tool, or your server config -server url = http://:8000 # default Hummingbot API port -``` -Verify with a read call (no keys touched): -``` -portfolio() # should show the connected derive_perpetual[_testnet] balances -``` - -## Step 3 — Dry / testnet run -1. Set `default_trading_context` connector to `derive_perpetual_testnet` (tiny size). -2. Launch the agent loop (`manage_routines` + the loop strategy) on the testnet. +Configure the Hummingbot API server connection (the Condor side that IS +exposed) with the bot's URL (default `http://:8000`). Verify with a +read call (no keys touched): `portfolio()` should show the connected +`derive_perpetual` balances. + +## Step 3 — Tiny-size mainnet validation +1. Set `default_trading_context` connector to `derive_perpetual`, and start with + a small `total_amount_quote` (e.g. 50–100 USDT) on the isolated wallet. +2. Launch the agent loop (`manage_routines` + the loop strategy). 3. Watch for, per tick: - `onchain_flow` routine returns a verdict + dashboard (no exceptions). - On a `LONG`/`SHORT` verdict, a `PositionExecutor` opens on the right pair. - Risk Engine enforces limits (max 2 positions, 3x lev, 8% DD). - TP/SL/trail logic fires; position closes; journal entry written. -4. Force both directions at least once (the routine's `synthesize` can be fed a - synthetic RISK-ON/+flow and RISK-OFF/−flow to exercise LONG and SHORT without - waiting for the market). +4. Force both directions at least once: feed `synthesize()` a synthetic + RISK-ON/+flow and RISK-OFF/−flow to exercise LONG and SHORT without waiting + for the market. -## Step 4 — Mainnet (only after Step 3 is clean) -- Switch connector back to `derive_perpetual`, fund the wallet, start with a - small `total_amount_quote`, and monitor the same checks on real capital. +## Step 4 — Scale only after Step 3 is clean +Once one LONG and one SHORT have opened and closed correctly with correct +sizing/limits and zero Risk-Engine violations, raise `total_amount_quote`. ## Step 5 — Pre-PR evidence -Attach to the PR: a short log/screenshot of the testnet run showing +Attach to the PR: a short log/screenshot of the validation run showing - routine verdict + dashboard, - at least one opened + closed position with correct sizing/limits, - zero Risk-Engine violations. -This is the "ensure it properly works before submitting PR" gate. +## Note on testnet +If a true testnet gate is desired, it requires a Condor change: relax the +`"testnet" not in c.lower()` filter in `condor/web/routes/settings.py` for +validation connectors (or add a per-user "allow testnet" flag). Out of scope +for this agent PR unless you want to propose it. From aa3de7770bf4ebf13cc98ae6dea612d5723f9036 Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 17:35:12 +0800 Subject: [PATCH 04/12] =?UTF-8?q?docs(smart-money-flow):=20add=20HOW=5FIT?= =?UTF-8?q?=5FWORKS=20=E2=80=94=20workflow=20+=20scoring=20+=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agents/smart_money_flow/HOW_IT_WORKS.md | 151 ++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 agents/smart_money_flow/HOW_IT_WORKS.md diff --git a/agents/smart_money_flow/HOW_IT_WORKS.md b/agents/smart_money_flow/HOW_IT_WORKS.md new file mode 100644 index 00000000..8abb305a --- /dev/null +++ b/agents/smart_money_flow/HOW_IT_WORKS.md @@ -0,0 +1,151 @@ +# How Smart-Money Flow (DEX) Works + +A directional perpetual-futures trading agent that decides **where capital is +flowing** — not where price has been. It reads a *flow-and-positioning composite* +(keyless cross-market data + an on-chain Solana DeFi pulse), scores it into a +`LONG` / `SHORT` / `HOLD` verdict, and (on the trading venue) opens bounded +leverage positions on liquid majors (BTC/ETH/SOL). + +Execution is **venue-agnostic**: the default is **Derive perps** +(`derive_perpetual`), but the same agent runs on Hyperliquid, Backpack, Pacifica, +or any perp connector — you only change the `default_trading_context` connector +name. The routine never calls an exchange API; it only produces a *signal*. + +--- + +## The core idea + +A candlestick chart shows price. It does **not** show: +- Is risk appetite expanding or contracting? (regime) +- Which majors have unusual volume relative to their size? (flow intensity) +- What is heating up across the market right now? (rotation) +- Is real on-chain DeFi money moving? (Solana pulse) + +Smart-Money Flow combines those into one composite score per asset, then trades +only when conviction is high and regime-aligned. **No trade is forced** — when the +composite is ambiguous, it stands aside. + +--- + +## Data sources (all keyless) + +| Source | Endpoint | What it gives | +|---|---|---| +| CoinGecko `/global` | `api.coingecko.com/api/v3/global` | Risk regime: total mcap momentum, BTC dominance, market sentiment | +| CoinGecko `/coins/markets` | `…/coins/markets?ids=bitcoin,ethereum,solana` | Per-asset flow: 24h volume, market cap, 24h % change | +| CoinGecko `/search/trending` | `…/search/trending` | What assets/sectors are heating up (rotation) | +| Solana / GeckoTerminal | `api.geckoterminal.com/api/v2/networks/solana/tokens/{SOL}/pools` | On-chain DeFi flow pulse: top-pool 24h volume, momentum, TVL | +| XRPL JSON-RPC (optional) | `xrplcluster.com` | Legacy DEX AMM pulse — **off by default** (Solana is deeper) | + +Every fetch is defensive + async; if one source fails, the composite degrades +gracefully instead of crashing the tick. + +--- + +## How a decision is made (scoring) + +1. **Risk regime** from `/global`: + - `RISK-ON` if total mcap is rising and BTC dominance is not spiking. + - `RISK-OFF` if mcap is falling / dominance rising (flight to safety). + - `NEUTRAL` otherwise. +2. **Per-asset flow score** for BTC/ETH/SOL: + `flow = clamp(volume/mcap × 5, ±0.5) × 0.4 + clamp(24h% / 6, ±1) × 0.6` + - 24h momentum is the dominant driver; volume intensity confirms. + - Trending on CoinGecko adds a small +0.15 conviction bump. +3. **On-chain Solana pulse**: flow score from top-pool volume intensity (log + scale) + **median** 24h momentum (robust to memecoin outliers) + TVL filter + (dust pools excluded). Anchored on SOL's own pools so it reflects the real + SOL ecosystem, not random tokens. +4. **Composite verdict** per asset → `LONG` / `SHORT` / `HOLD`: + - `LONG` : regime **RISK-ON** AND asset flow ≥ **+0.4** + - `SHORT` : regime **RISK-OFF** AND asset flow ≤ **−0.4** + - `HOLD` : anything else (NEUTRAL regime, or |flow| < 0.4, or ambiguous) +5. A **ReportBuilder dashboard** is produced: regime, per-asset flow scores, + the Solana pulse, a cross-market context table, and the final verdict. + +--- + +## Step-by-step workflow (each trading tick) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ TICK (every frequency_sec, default 300s) │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ + 1. Run the flow read + manage_routines(action="run", routine="onchain_flow") + │ → fetches CoinGecko + Solana keyless data + │ → scores regime + per-asset flow + Solana pulse + │ → returns LONG / SHORT / HOLD + best-flow asset + │ → builds a dashboard report + ▼ + 2. Filter (only BTC/ETH/SOL with NO open position) + LONG : RISK-ON & flow ≥ +0.4 + SHORT : RISK-OFF & flow ≤ −0.4 + else : HOLD (do nothing) + ▼ + 3. Size & enter (if a signal) + • use total_amount_quote (start tiny) + • never exceed max_open_executors (2) or max_total_exposure_quote + • leverage up to max_leverage: 3x (5x only at conviction ≥ 0.7) + • open a PositionExecutor (or GridExecutor w/ stop_loss_keep_position) + ▼ + 4. Manage the position + • take-profit 50% at +2% + • trail 2% after +1.5% in profit + • hard stop −2.5% + • on signal flip (next tick flow crosses zero vs your side) w/ conviction ≥0.4 → exit / optionally reverse + • max 8h hold + ▼ + 5. Journal the flow thesis (one line per tick) + e.g. "RISK-ON; ETH flow +0.52; Solana pulse +0.44 → LONG ETH 500" + ▼ + 6. Risk Engine guardrail + auto-blocks anything over the risk_limits + (max 2 positions, 3x lev, 8% max drawdown) +``` + +--- + +## Risk limits (built-in guardrails) + +From `default_config.risk_limits`: +- `max_total_exposure_quote: 2000` — never deploy more than this notional. +- `max_drawdown_pct: 8` — hard stop if losses hit 8%. +- `max_open_executors: 2` — at most 2 concurrent positions. +- `max_leverage: 3` — 3x default; 5x only at high conviction (≥0.7). +- `frequency_sec: 300` — one decision every 5 minutes. +- The Risk Engine automatically rejects anything that breaches these. + +--- + +## Setup & run (Condor reality, verified) + +1. **Connect the exchange — web dashboard only.** + Condor → **Settings → Keys** → add `derive_perpetual` (mainnet). + (Telegram `/keys` is read-only; the Condor API does not add keys.) + Use a **dedicated, minimally-funded wallet**. +2. **Point Condor at the bot.** Configure the Hummingbot API server connection + (default `http://:8000`); verify with `portfolio()`. +3. **Validate small.** Run the agent at a tiny `total_amount_quote` first; force + a LONG and a SHORT (the routine accepts synthetic inputs) to confirm sizing, + Risk Engine limits, and TP/SL before scaling. +4. **Scale** only after clean validation. + +> **Note:** Condor's web UI filters out every *testnet* connector, so there is no +> `derive_perpetual_testnet` option — validation is mainnet-with-small-size on an +> isolated wallet, not a sandbox. (This is a general Condor behavior, not specific +> to this agent.) + +--- + +## Why this is distinct + +- **vs news/sentiment agents** (e.g. Agora): no NLP on headlines — it reads + *capital movement*, not narrative. +- **vs market-making / funding-harvest agents**: it takes directional + LONG/SHORT views, not passive spread capture. +- **vs trend-following**: its edge is the *flow composite* (regime + cross-market + flow + on-chain Solana pulse), not a price indicator. +- The on-chain signal is **Solana** (deep DeFi liquidity), not thin XRPL. From 89915ad83348e97078db7a20ceb5d6bf7f01694b Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 20:49:38 +0800 Subject: [PATCH 05/12] chore(smart-money-flow): size config for 50 USDC wallet (test-mode) Cap budget at 50 USDC total: total_amount_quote 50, max_total_exposure_quote 50, max_position_size_quote 20, min_order_amount_quote 10, single position (max_open_executors 1), 2x leverage (~40 USDC notional, under balance). Keep production defaults documented separately. Aligns strategy.md + HOW_IT_WORKS.md. --- agents/smart_money_flow/HOW_IT_WORKS.md | 8 ++++ .../strategies/directional_flow/strategy.md | 43 ++++++++++++------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/agents/smart_money_flow/HOW_IT_WORKS.md b/agents/smart_money_flow/HOW_IT_WORKS.md index 8abb305a..92c76b32 100644 --- a/agents/smart_money_flow/HOW_IT_WORKS.md +++ b/agents/smart_money_flow/HOW_IT_WORKS.md @@ -111,11 +111,19 @@ gracefully instead of crashing the tick. ## Risk limits (built-in guardrails) From `default_config.risk_limits`: + +**Production defaults:** - `max_total_exposure_quote: 2000` — never deploy more than this notional. - `max_drawdown_pct: 8` — hard stop if losses hit 8%. - `max_open_executors: 2` — at most 2 concurrent positions. - `max_leverage: 3` — 3x default; 5x only at high conviction (≥0.7). - `frequency_sec: 300` — one decision every 5 minutes. + +**50-USDC test-mode (current `default_config` values — wallet-sized):** +- `total_amount_quote: 50`, `min_order_amount_quote: 10`, `position_size_quote: 20` +- `max_total_exposure_quote: 50`, `max_position_size_quote: 20` +- `max_open_executors: 1` (one position at a time) +- `max_leverage: 2` (notional ~40 USDC, under the 50 balance) - The Risk Engine automatically rejects anything that breaches these. --- diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/directional_flow/strategy.md index a5f0ab66..b0c9e41d 100644 --- a/agents/smart_money_flow/strategies/directional_flow/strategy.md +++ b/agents/smart_money_flow/strategies/directional_flow/strategy.md @@ -7,13 +7,20 @@ skills: default_config: execution_mode: loop frequency_sec: 300 - total_amount_quote: 1000 + total_amount_quote: 50 + # --- Small-wallet / test-mode sizing (50 USDC total balance) --- + # Treat the entire wallet as the budget. No margin scaling beyond the + # balance: one position at a time, minimal per-order amount, leverage kept + # low so notional stays within ~50 USDC collateral. + min_order_amount_quote: 10 # smallest order placed per attempt + position_size_quote: 20 # notional per position (well under 50) max_ticks: 0 risk_limits: - max_total_exposure_quote: 2000 + max_total_exposure_quote: 50 # never exceed the funded wallet + max_position_size_quote: 20 # single position capped at 20 USDC max_drawdown_pct: 8 - max_open_executors: 2 - max_leverage: 3 + max_open_executors: 1 # one position at a time on a tiny wallet + max_leverage: 2 # 2x keeps notional ~40 USDC (< balance) default_trading_context: | Trade BTC/USDT, ETH/USDT, SOL/USDT perpetuals on Derive (connector `derive_perpetual`). One-time setup: in the Hummingbot client run @@ -22,14 +29,16 @@ default_trading_context: | The Condor/API layer drives an already-connected instance — it does NOT add keys itself (security boundary; see mcp_servers/hummingbot_api/server.py). VALIDATION FIRST: connect `derive_perpetual` (mainnet) via the web dashboard - (Settings → Keys) using a dedicated, minimally-funded wallet, then run with a - tiny `total_amount_quote` before scaling. NOTE: Condor's web UI filters out - testnet connectors (see validation.md), so validation is mainnet-with-small- - size, not testnet. Read the onchain_flow routine every tick; take - LONG when the regime is RISK-ON and the asset's flow_score >= 0.4, SHORT when - RISK-OFF and flow_score <= -0.4. Max 2 concurrent positions, max leverage 3x - (5x only at flow conviction >= 0.7). Stand aside (HOLD) when the composite is - ambiguous. The on-chain signal is Solana DeFi flow (GeckoTerminal), not XRPL. + (Settings → Keys) using a dedicated wallet funded with ~50 USDC on Base (native + USDC). default_config is already sized for a 50 USDC wallet: total budget 50, + one position at a time (max_open_executors: 1), 20 USDC per position, 2x + leverage, min order 10 USDC. Run as-is for the test; scale the numbers up only + after a clean run. NOTE: Condor's web UI filters out testnet connectors (see + validation.md), so validation is mainnet-with-small-size, not testnet. Read the + onchain_flow routine every tick; take LONG when the regime is RISK-ON and the + asset's flow_score >= 0.4, SHORT when RISK-OFF and flow_score <= -0.4. Stand + aside (HOLD) when the composite is ambiguous. The on-chain signal is Solana + DeFi flow (GeckoTerminal), not XRPL. --- # Derive Flow Trader — Playbook @@ -44,10 +53,12 @@ You are the **loop strategy** for the Smart-Money Flow agent, trading - `LONG`: regime RISK-ON AND asset `flow_score >= +0.4` - `SHORT`: regime RISK-OFF AND asset `flow_score <= -0.4` - otherwise: `HOLD` (ambiguous / NEUTRAL regime / |flow| < 0.4 — no trade). -3. **Size & enter.** Use `total_amount_quote`; never exceed `max_open_executors` - (2) or `max_total_exposure_quote`. Leverage up to `max_leverage` (3x; 5x only - at flow conviction ≥ 0.7). Open a `PositionExecutor` (or `GridExecutor` with - `stop_loss_keep_position=true`). The Risk Engine auto-blocks anything over limit. +3. **Size & enter.** Use the test-mode sizing: one position at a time + (`max_open_executors: 1`), **20 USDC per position**, **2x leverage** (notional + ~40 USDC, safely under the 50 USDC wallet), **min order 10 USDC**. Never exceed + `max_total_exposure_quote` (50). Open a `PositionExecutor` (or `GridExecutor` + with `stop_loss_keep_position=true`). The Risk Engine auto-blocks anything over + limit. 4. **Manage.** 50% take-profit at +2%, trail 2% after +1.5% in profit, hard stop −2.5%. On signal flip (next tick's flow score crosses zero against your position) with conviction ≥ 0.4, exit and optionally reverse. Max 8h hold. From eab5b9164cac87cc11fa3f0cc04ab45093579842 Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 21:09:00 +0800 Subject: [PATCH 06/12] =?UTF-8?q?fix(smart-money-flow):=20Derive=20perps?= =?UTF-8?q?=20are=20USDC-quoted=20=E2=80=94=20use=20SOL/ETH/BTC-USDC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Derive perpetuals are quoted in USDC (trading-rule map + order-book subscription both require '-USDC'), not USDT. Correct default_trading_context pairs and the validation note accordingly. --- .../strategies/directional_flow/strategy.md | 9 ++++++--- agents/smart_money_flow/validation.md | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/directional_flow/strategy.md index b0c9e41d..19199abb 100644 --- a/agents/smart_money_flow/strategies/directional_flow/strategy.md +++ b/agents/smart_money_flow/strategies/directional_flow/strategy.md @@ -22,9 +22,12 @@ default_config: max_open_executors: 1 # one position at a time on a tiny wallet max_leverage: 2 # 2x keeps notional ~40 USDC (< balance) default_trading_context: | - Trade BTC/USDT, ETH/USDT, SOL/USDT perpetuals on Derive (connector - `derive_perpetual`). One-time setup: in the Hummingbot client run - `connect derive_perpetual` (wallet address + private key + subaccount id), + Trade BTC/USDC, ETH/USDC, SOL/USDC perpetuals on Derive (connector + `derive_perpetual`). IMPORTANT: Derive perps are quoted in **USDC**, not USDT — + use `SOL-USDC` / `ETH-USDC` / `BTC-USDC` (the connector's trading-rule map and + order-book subscription both require the `-USDC` form). One-time setup: in the + Hummingbot client run `connect derive_perpetual` (wallet address + private key + + subaccount id), then point this Condor instance at that running bot via the configured server. The Condor/API layer drives an already-connected instance — it does NOT add keys itself (security boundary; see mcp_servers/hummingbot_api/server.py). diff --git a/agents/smart_money_flow/validation.md b/agents/smart_money_flow/validation.md index 86e929ab..7379dd16 100644 --- a/agents/smart_money_flow/validation.md +++ b/agents/smart_money_flow/validation.md @@ -34,7 +34,7 @@ read call (no keys touched): `portfolio()` should show the connected ## Step 3 — Tiny-size mainnet validation 1. Set `default_trading_context` connector to `derive_perpetual`, and start with - a small `total_amount_quote` (e.g. 50–100 USDT) on the isolated wallet. + a small `total_amount_quote` (e.g. 50–100 USDC) on the isolated wallet. 2. Launch the agent loop (`manage_routines` + the loop strategy). 3. Watch for, per tick: - `onchain_flow` routine returns a verdict + dashboard (no exceptions). From b56ad389373bdbb230ad4a2de0f1e231540a49dc Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 21:17:58 +0800 Subject: [PATCH 07/12] docs(smart-money-flow): document Derive connector init fix + live test result Restarting hummingbot-api repopulates the derive_perpetual symbol map after a bad-pair attempt (SOL-USDT) poisons it. Golden rules: use SOL/ETH/BTC-USDC on Derive; restart container if create_executor hangs with KeyError. Records the verified LONG SOL-USDC place+close on Derive mainnet (~$0.02 fees). --- agents/smart_money_flow/validation.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/agents/smart_money_flow/validation.md b/agents/smart_money_flow/validation.md index 7379dd16..2add5fdd 100644 --- a/agents/smart_money_flow/validation.md +++ b/agents/smart_money_flow/validation.md @@ -60,3 +60,24 @@ If a true testnet gate is desired, it requires a Condor change: relax the `"testnet" not in c.lower()` filter in `condor/web/routes/settings.py` for validation connectors (or add a per-user "allow testnet" flag). Out of scope for this agent PR unless you want to propose it. + +## Operational note — Derive connector init (learned during live test) +The `hummingbot-api` container's `derive_perpetual` connector builds its +symbol map from Derive's live API on startup. If a bad pair is attempted +(e.g. `SOL-USDT` instead of the correct `SOL-USDC`), the order-book websocket +subscription throws `KeyError` in +`derive_perpetual_api_order_book_data_source.py` and **every subsequent +`create_executor` hangs** (no order placed, funds untouched) until the +connector re-initializes. + +**Fix that worked:** `docker restart hummingbot-api` forces a fresh connector +init against Derive's API, repopulating the symbol map so `SOL-USDC` resolves. +After that, orders place normally. + +**Golden rules for Derive:** +- Always use `SOL-USDC` / `ETH-USDC` / `BTC-USDC` (Derive perps are USDC-quoted; + `-USDT` does not exist and poisons the connector state). +- If `create_executor` hangs with a `KeyError` in the Derive data source, + restart the `hummingbot-api` container before retrying. +- Live test result (2026-07-28): LONG `SOL-USDC` placed + closed cleanly on + Derive mainnet, ~$0.02 fees, funds returned. Full lifecycle verified. From ce326dc1930318b6708e162821c128af0ac7e049 Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 21:38:27 +0800 Subject: [PATCH 08/12] docs(smart-money-flow): Derive-only description + LLM cost section AGENT.md now states tested on Derive mainnet only (removed other DEXes from description/body). HOW_IT_WORKS.md adds concise LLM-per-tick cost note: deepseek-v4-flash pricing, prompt-cache effect, ~$0.10/day typical at 300s cadence. --- agents/smart_money_flow/AGENT.md | 20 +++++++++--------- agents/smart_money_flow/HOW_IT_WORKS.md | 27 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/agents/smart_money_flow/AGENT.md b/agents/smart_money_flow/AGENT.md index be764093..e5c6feaf 100644 --- a/agents/smart_money_flow/AGENT.md +++ b/agents/smart_money_flow/AGENT.md @@ -1,6 +1,6 @@ --- name: Smart-Money Flow -description: Directional perp trader on any perpetual venue (Derive, Hyperliquid, Backpack, Pacifica, …) — reads capital-flow & positioning (cross-market regime + Solana on-chain DeFi pulse) and takes LONG/SHORT/HOLD on liquid majors. Leverage enabled; bounded risk. +description: Directional perp trader on Derive (`derive_perpetual`) — reads capital-flow & positioning (cross-market regime + Solana on-chain DeFi pulse) and takes LONG/SHORT/HOLD on liquid majors. Leverage enabled; bounded risk. Tested on Derive mainnet only. agent_key: opencode-go:deepseek-v4-flash tools: [] when_to_consult: When the user wants a directional read on where capital is flowing in crypto markets, or wants to deploy the Smart-Money Flow trading agent (flow positioning on perps — any venue). @@ -11,9 +11,9 @@ created_at: '2026-07-28T00:00:00.000000+00:00' # Smart-Money Flow -You are **Smart-Money Flow** — a **directional perpetual-futures trader** (any -perp venue: Derive, Hyperliquid, Backpack, Pacifica, …) who reads **where -capital is moving**, not just where price has been. Your edge is a +You are **Smart-Money Flow** — a **directional perpetual-futures trader on +Derive** (`derive_perpetual`) who reads **where capital is moving**, not just +where price has been. Your edge is a flow-and-positioning composite that a candlestick chart alone cannot show: risk regime (BTC dominance, total mcap momentum), cross-market asset flow intensity (volume-to-mcap, 24h change, trending rotation), and an **on-chain Solana DeFi @@ -26,17 +26,19 @@ you. Leverage is enabled but bounded. --- -## Venue-neutral by design -Execution is **any perpetual-futures connector** — Derive (`derive_perpetual`), -Hyperliquid (`hyperliquid`), Backpack (`backpack_perpetual`), Pacifica -(`pacifica_perpetual`), or others. The venue is set in `default_trading_context` -/ the configured Hummingbot server, **not** in code: the routine only produces a +## Tested on Derive +Execution uses the **Derive perpetual connector** (`derive_perpetual`) on +mainnet, funded with USDC. The venue is set in `default_trading_context` / the +configured Hummingbot server, **not** in code: the routine only produces a *signal* (cross-market + Solana on-chain flow); it never calls an exchange API. This agent was pivoted away from an Orca Whirlpools spot framing because CLMM spot cannot express the directional/short side this composite needs. Solana carries materially deeper on-chain liquidity than XRPL, so the on-chain pulse is sourced from Solana, not XRPL. +> **Status:** validated end-to-end on Derive mainnet (LONG `SOL-USDC` placed and +> closed, ~$0.02 fees). Other perpetual venues are not yet tested. + --- ## Every-Tick Playbook (step by step) diff --git a/agents/smart_money_flow/HOW_IT_WORKS.md b/agents/smart_money_flow/HOW_IT_WORKS.md index 92c76b32..87f9b219 100644 --- a/agents/smart_money_flow/HOW_IT_WORKS.md +++ b/agents/smart_money_flow/HOW_IT_WORKS.md @@ -128,6 +128,33 @@ From `default_config.risk_limits`: --- +## LLM usage & cost (per tick) + +The agent **calls the LLM on every tick** — a fresh ACP session streams the +strategy + live market data and returns a `LONG/SHORT/HOLD` decision (and may +emit executor tool calls). There is no "skip if nothing changed": every tick +costs tokens. The only free ticks are **risk-blocked / shutdown** ticks, which +return before the LLM call. + +**Use a cheap model.** This agent is wired to `opencode-go:deepseek-v4-flash`. +Its pricing (DeepSeek API): **$0.14 / 1M input (cache-miss)**, **$0.0028 / 1M +input (cache-hit)**, **$0.28 / 1M output**. + +The per-tick prompt is ~90% fixed boilerplate (AGENT.md + strategy + skills +index) that repeats every tick, so it hits the **prompt cache** (cache-hit = +$0.0028/M). Only the small live-data suffix is cache-miss. + +**Estimated cost (deepseek-v4-flash, 300s cadence = 288 ticks/day):** +- Typical (with prompt caching): **~$0.10 / day** +- Worst case (no cache): **~$0.35 / day** +- Scales with cadence: 600s → ~half; 60s → ~5× (~$0.5–1.75/day). + +The routine's data fetches (CoinGecko, Solana GeckoTerminal) are free code — +the LLM cost is purely the decision step. Keep `frequency_sec` at 300s (or +higher) and stay on the flash model to keep cost negligible. + +--- + ## Setup & run (Condor reality, verified) 1. **Connect the exchange — web dashboard only.** From 8ed60861434a550db1ee28d0056b43f836c27bde Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 22:27:02 +0800 Subject: [PATCH 09/12] fix(smart-money-flow): align strategy folder name to slug (derive_flow_trader) The strategy folder was named 'directional_flow' while the strategy name 'Derive Flow Trader' slugifies to 'derive_flow_trader'. The web GET /agents/{slug}/strategies/{sslug} resolves by folder name, so the frontend (open button) passed the slug 'derive_flow_trader' and got 404 'Strategy not found'. Moved strategy.md into the slug-named folder and removed the stale directional_flow folder. Also tightened the description to Derive-only (remove Hyperliquid/Backpack/Pacifica per user request). Co-Authored-By: Claude Opus 4.6 --- .../{directional_flow => derive_flow_trader}/strategy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename agents/smart_money_flow/strategies/{directional_flow => derive_flow_trader}/strategy.md (94%) diff --git a/agents/smart_money_flow/strategies/directional_flow/strategy.md b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md similarity index 94% rename from agents/smart_money_flow/strategies/directional_flow/strategy.md rename to agents/smart_money_flow/strategies/derive_flow_trader/strategy.md index 19199abb..4036a214 100644 --- a/agents/smart_money_flow/strategies/directional_flow/strategy.md +++ b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md @@ -1,6 +1,6 @@ --- name: Derive Flow Trader -description: Directional perp trader on any perpetual venue (Derive, Hyperliquid, Backpack, Pacifica, …). Takes LONG/SHORT on BTC/ETH/SOL where capital-flow conviction is decisive and regime-aligned; bounded leverage, position-hold risk. +description: Directional perp trader on Derive (derive_perpetual). Takes LONG/SHORT on BTC/ETH/SOL where capital-flow conviction is decisive and regime-aligned; bounded leverage, position-hold risk. Tested on Derive mainnet only. agent_key: opencode-go:deepseek-v4-flash skills: - smart_money_flow:smart_money_playbook From 25b8b3432a35674623486f7e906a5180ab52255a Mon Sep 17 00:00:00 2001 From: Carlito Date: Tue, 28 Jul 2026 22:46:10 +0800 Subject: [PATCH 10/12] docs(smart-money-flow): Derive-only consult trigger + USDC pair labels in onchain_flow - AGENT.md when_to_consult tightened to Derive perps (drop 'any venue'). - onchain_flow.py: report pair labels SOL/ETH/BTC now show -USDC to match Derive's USDC-quoted perps (signal is venue-independent; the displayed label was stale USDT). Co-Authored-By: Claude Opus 4.6 --- agents/smart_money_flow/AGENT.md | 2 +- agents/smart_money_flow/routines/onchain_flow.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/agents/smart_money_flow/AGENT.md b/agents/smart_money_flow/AGENT.md index e5c6feaf..425fcd44 100644 --- a/agents/smart_money_flow/AGENT.md +++ b/agents/smart_money_flow/AGENT.md @@ -3,7 +3,7 @@ name: Smart-Money Flow description: Directional perp trader on Derive (`derive_perpetual`) — reads capital-flow & positioning (cross-market regime + Solana on-chain DeFi pulse) and takes LONG/SHORT/HOLD on liquid majors. Leverage enabled; bounded risk. Tested on Derive mainnet only. agent_key: opencode-go:deepseek-v4-flash tools: [] -when_to_consult: When the user wants a directional read on where capital is flowing in crypto markets, or wants to deploy the Smart-Money Flow trading agent (flow positioning on perps — any venue). +when_to_consult: When the user wants a directional read on where capital is flowing in crypto markets, or wants to deploy the Smart-Money Flow trading agent (flow positioning on Derive perps). server_required: false created_by: 5587715073 created_at: '2026-07-28T00:00:00.000000+00:00' diff --git a/agents/smart_money_flow/routines/onchain_flow.py b/agents/smart_money_flow/routines/onchain_flow.py index 11af1046..dd8b152b 100644 --- a/agents/smart_money_flow/routines/onchain_flow.py +++ b/agents/smart_money_flow/routines/onchain_flow.py @@ -228,7 +228,7 @@ def synthesize(global_d, markets_d, trending_syms, solana_pulse, xrpl_amm) -> di flow = _clamp(flow + 0.1) assets_out.append({ "symbol": sym, - "pair": f"{sym}-USDT", + "pair": f"{sym}-USDC", "flow_score": round(flow, 3), "volume_to_mcap": round(vol_mcap, 3), "price_change_24h": round(chg, 2), From badefbf57f6538667a0947b053bc770314be6750 Mon Sep 17 00:00:00 2001 From: Carlito Date: Wed, 29 Jul 2026 18:42:12 +0800 Subject: [PATCH 11/12] fix(smart-money-flow): remove triple-dash from strategy.md comment to prevent frontmatter truncation The '# --- ... ---' comment inside default_config ended YAML frontmatter at the first '---', silently dropping risk_limits / sizing / trading_context. The running engine then fell back to unsafe engine defaults. The fix removes the dashes from the comment. --- .../smart_money_flow/strategies/derive_flow_trader/strategy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md index 4036a214..24c5a9a8 100644 --- a/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md +++ b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md @@ -8,7 +8,7 @@ default_config: execution_mode: loop frequency_sec: 300 total_amount_quote: 50 - # --- Small-wallet / test-mode sizing (50 USDC total balance) --- + # Small-wallet / test-mode sizing (50 USDC total balance) # Treat the entire wallet as the budget. No margin scaling beyond the # balance: one position at a time, minimal per-order amount, leverage kept # low so notional stays within ~50 USDC collateral. From d44f7911bcb7f8098110121ae41c7ebf3f51f949 Mon Sep 17 00:00:00 2001 From: Carlito Date: Thu, 30 Jul 2026 00:23:50 +0800 Subject: [PATCH 12/12] refactor(smart-money-flow): use PR #175 custom endpoint form for opencode-go model Switches agent_key from 'opencode-go:deepseek-v4-flash' to 'custom@opencode:deepseek-v4-flash' so the agent runs on opencode-go via PR #175's named custom OpenAI-compatible endpoint (no PR #170 needed). Documents endpoint setup: Settings -> LLM Endpoints, or CUSTOM_LLM_BASE_URL/CUSTOM_LLM_API_KEY in .env for headless condor-bot.service deploys. --- agents/smart_money_flow/AGENT.md | 7 ++++++- agents/smart_money_flow/HOW_IT_WORKS.md | 13 ++++++++++++- .../strategies/derive_flow_trader/strategy.md | 5 ++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/agents/smart_money_flow/AGENT.md b/agents/smart_money_flow/AGENT.md index 425fcd44..e4ced1ed 100644 --- a/agents/smart_money_flow/AGENT.md +++ b/agents/smart_money_flow/AGENT.md @@ -1,7 +1,12 @@ --- name: Smart-Money Flow description: Directional perp trader on Derive (`derive_perpetual`) — reads capital-flow & positioning (cross-market regime + Solana on-chain DeFi pulse) and takes LONG/SHORT/HOLD on liquid majors. Leverage enabled; bounded risk. Tested on Derive mainnet only. -agent_key: opencode-go:deepseek-v4-flash +# Model: runs on opencode-go (OpenAI-compatible gateway) using DeepSeek v4-flash. +# With PR #175 (custom OpenAI-compatible endpoints) this is expressed as a named +# custom endpoint "opencode"; register it once (Settings -> LLM Endpoints, or +# CUSTOM_LLM_BASE_URL / CUSTOM_LLM_API_KEY in .env for headless deploys) pointing +# at https://opencode.ai/zen/go/v1 with your OPENCODE_GO_API_KEY. +agent_key: custom@opencode:deepseek-v4-flash tools: [] when_to_consult: When the user wants a directional read on where capital is flowing in crypto markets, or wants to deploy the Smart-Money Flow trading agent (flow positioning on Derive perps). server_required: false diff --git a/agents/smart_money_flow/HOW_IT_WORKS.md b/agents/smart_money_flow/HOW_IT_WORKS.md index 87f9b219..bec0524a 100644 --- a/agents/smart_money_flow/HOW_IT_WORKS.md +++ b/agents/smart_money_flow/HOW_IT_WORKS.md @@ -136,7 +136,18 @@ emit executor tool calls). There is no "skip if nothing changed": every tick costs tokens. The only free ticks are **risk-blocked / shutdown** ticks, which return before the LLM call. -**Use a cheap model.** This agent is wired to `opencode-go:deepseek-v4-flash`. +**Use a cheap model.** This agent runs on DeepSeek v4-flash through the +opencode-go OpenAI-compatible gateway. With PR #175 it is wired to the named +custom endpoint `custom@opencode:deepseek-v4-flash` (legacy form: +`opencode-go:deepseek-v4-flash`). To make it work you must register the +`opencode` endpoint once: + +- **Web/Telegram:** `Settings → LLM Endpoints → Add endpoint` (or `/agent → + Change LLM → Custom — OpenAI-compatible API`), name it `opencode`, + base URL `https://opencode.ai/zen/go/v1`, API key = your `OPENCODE_GO_API_KEY`. +- **Headless (condor-bot.service):** set `CUSTOM_LLM_BASE_URL=https://opencode.ai/zen/go/v1` + and `CUSTOM_LLM_API_KEY=` in condor's `.env`. + Leave `CUSTOM_LLM_BLOCK_PRIVATE_URLS` unset for a personal deploy. Its pricing (DeepSeek API): **$0.14 / 1M input (cache-miss)**, **$0.0028 / 1M input (cache-hit)**, **$0.28 / 1M output**. diff --git a/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md index 24c5a9a8..d618fdf9 100644 --- a/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md +++ b/agents/smart_money_flow/strategies/derive_flow_trader/strategy.md @@ -1,7 +1,10 @@ --- name: Derive Flow Trader description: Directional perp trader on Derive (derive_perpetual). Takes LONG/SHORT on BTC/ETH/SOL where capital-flow conviction is decisive and regime-aligned; bounded leverage, position-hold risk. Tested on Derive mainnet only. -agent_key: opencode-go:deepseek-v4-flash +# Model: runs on opencode-go via PR #175's custom endpoint "opencode" +# (custom@opencode:deepseek-v4-flash) — base https://opencode.ai/zen/go/v1, +# key = OPENCODE_GO_API_KEY (set via Settings -> LLM Endpoints or CUSTOM_LLM_* env). +agent_key: custom@opencode:deepseek-v4-flash skills: - smart_money_flow:smart_money_playbook default_config: