AGENT SKILL

senpi-trade

Execute a DIRECT trade with the user — a one-off manual position (open / edit / close) or mirroring a specific Hyperliquid trader — ONE decision at a time. Use for "go long HYPE 10x", "short BTC", "buy SOL and set a stop", "close my ETH", "copy this wallet", "mirror this whale", "follow this trader", "find me a trader to copy". Both paths can carry protection and it is OPTIONAL: bare, a static stop/TP, or a profit-lock trailing ladder (`ratchet_stop_add`, no runtime) — but that ladder is profit-lock ONLY (no downside floor); the full two-phase DSL (a ratcheting max-loss floor + the profit locks) is runtime-only, so route to a managed strategy for real two-sided protection. Any question about a stop or a ladder, and any change to one, runs the protection protocol: read it in the same turn, quote the engine's floor (never compute one), say what a change replaces and get a yes, read it back. Steer users to a MANAGED strategy when they want ongoing autonomy — senpi-strategy-author builds their own (a managed mirror included: sized to the user, DSL on every fill), forking the closest template when one fits. Pairs with senpi-trader-research, which finds and vets the trader (this skill runs the mirror once one is chosen). NOT for authoring a strategy or deploying a template yourself.

License 许可
Apache-2.0
最近更新
2026-11-15
Stars
★ 81
Forks
17

01 前言 Front Matter

name
senpi-trade
license
Apache-2.0
metadata
{ "author": "Senpi", "version": "1.12.0", "exchange": "hyperliquid", "platform": "senpi", "requires": [ "senpi-trader-research", "senpi-strategy-discover" ] }
description
Execute a DIRECT trade with the user — a one-off manual position (open / edit / close) or mirroring a specific Hyperliquid trader — ONE decision at a time. Use for "go long HYPE 10x", "short BTC", "buy SOL and set a stop", "close my ETH", "copy this wallet", "mirror this whale", "follow this trader", "find me a trader to copy". Both paths can carry protection and it is OPTIONAL: bare, a static stop/TP, or a profit-lock trailing ladder (`ratchet_stop_add`, no runtime) — but that ladder is profit-lock ONLY (no downside floor); the full two-phase DSL (a ratcheting max-loss floor + the profit locks) is runtime-only, so route to a managed strategy for real two-sided protection. Any question about a stop or a ladder, and any change to one, runs the protection protocol: read it in the same turn, quote the engine's floor (never compute one), say what a change replaces and get a yes, read it back. Steer users to a MANAGED strategy when they want ongoing autonomy — senpi-strategy-author builds their own (a managed mirror included: sized to the user, DSL on every fill), forking the closest template when one fits. Pairs with senpi-trader-research, which finds and vets the trader (this skill runs the mirror once one is chosen). NOT for authoring a strategy or deploying a template yourself.

02 资源文件 7

03 SKILL.md 正文

Senpi Trade — execute a direct trade with the user, one decision at a time

This skill runs the two direct trade paths: a manual one-off position (open / edit / close) and a mirror of a specific trader. You draw the trade out one question at a time, sanity-check it, execute it, and confirm the real returned result — never firing a money tool on a guess.

Protection is OPTIONAL — and know exactly what a raw position can carry

A manual position or a raw mirror can run bare, with a static stop/TP, or with a profit-lock trailing ladder (ratchet_stop_add) — all with no runtime. But be precise about that ladder: it is profit-lock ONLY. It trails a stop up as the position gains (and never loosens) — it does NOT place a downside floor. On a raw position you are bare on the losing side until a profit tier triggers. (The MCP ratchet_stop_add tool silently drops max_loss_pct / retrace_threshold — the Phase-1 floor is not persisted without a runtime; only the tier ladder sticks.)

So without a runtime, "protection" is one of two things, never a pair you can promise: the profit-lock ladder (ratchets up as you win) or a static SL (edit_position — fixed, does not ratchet). A position has one stop order, and once a ratchet is active the engine owns it: ratchet_stop_add REPLACES a static SL. Name the stop the user gives up, get a yes, then read strategy_get_open_orders back and report what actually rests. Don't call either one "DSL."

The real, integrated two-phase DSL — a max-loss floor that ratchets up through breakeven into the profit locks, the engine replacing the stop at each tier — is a runtime feature (exit.dsl_preset); a managed strategy has it built in and auto-applies it on every fill. Don't tell a user a raw position "can't be protected" (it can — profit-lock + a static SL), but don't oversell it as DSL either. When they want a true two-sided ratcheting stop → a managed strategy (author).

The protection protocol — reading and changing a stop on a position

Every question about a stop or a ladder ("show my DSL levels", "is it protected", "which is tighter") and every change to one runs the same six rules. Each one was broken on a live short, and it was the user's own arithmetic that caught it.

  1. Read in the same turn, or say you haven't. A claim about a live stop or ladder needs ratchet_stop_get (the ratchet) and strategy_get_open_orders (what actually rests) in the turn that makes the claim. Never describe a ladder from memory, from an earlier turn, or from a rule that says one "should" exist. status: DELETED (or no row) means no ratchet protection: no tier, no floor, no order — say exactly that; PAUSED means the engine has stopped updating it — what still rests is whatever strategy_get_open_orders shows.
  2. Quote, never compute. The floor is tierFloorPrice. lockRoe is a share of the high-water ROE (floorRoe = highWaterRoe × lockRoe / 100) — never a share of margin, never an absolute ROE. Dollars kept at a stop are (entry − stop) × size for a short and (stop − entry) × size for a long, nothing else. If the engine did not print a number, do not print it either.
  3. A short's stop sits above the price. Closer to the price is tighter, so for a short a LOWER trigger is tighter and keeps more; a higher trigger is looser and keeps less. A long is the mirror image. Before any "tighter / looser / locks more" sentence, work out which trigger the price reaches first.
  4. Leverage is the exchange's. strategy_get_clearinghouse_state → leverage.value and .type, never the strategy's name or a stale ratchet record; say it when they differ. The engine's ROE is on notional ÷ that leverage, not on the margin actually posted — name the base whenever you quote ROE.
  5. A change is read → say → yes → act → read back. State what will change and what it replaces (a ratchet replaces a static SL; a leverage change does not move a stop), get an explicit yes, act, then read strategy_get_open_orders and ratchet_stop_get again and quote them. The read-back is the confirmation; a tool's success: true is not.
  6. Consent comes from this conversation. A saved instruction ("always add the ratchet", "mandatory on every position") is neither evidence a ratchet exists nor consent to add one — it is a reminder to ask. A spoken "no DSL" / "forget about it unless I ask" stands until the user says otherwise, in any later session. A status check ("did you finish?", "how's it going?", "run a health check") is not a yes, and a health check never changes protection.

Worked example, a short: entry $80,890, price $77,300, manual stop $77,500, ratchet floor $78,370. The price reaches $77,500 first, so the manual stop is the tighter one and it keeps (80,890 − 77,500) × size; the floor keeps less. Adding the ratchet would replace that stop — say so before it happens. The five regression cases behind these rules, with the expected answers, are in references/protection-cases.md.

When a managed strategy / template IS the better answer — steer there for the real reasons, which now explicitly include integrated two-phase DSL (a raw position gets only profit-lock + an uncoordinated static SL, per above):

  • they want it managed for them going forward — DSL auto-attached to every new fill without you babysitting, budget-relative sizing (and, if they want it, fresh-entry-only — no chasing a runner). A raw mirror
    • per-position DSL means you wrap each new fill by hand; a managed strategy does all of it automatically.
  • they want to mirror more than one trader at once, by signal — a managed strategy can position by where the smart-money cohort leans (the aggregate of many proven traders), not copy one trader's book. A raw mirror is strictly 1:1; multi-trader, signal-driven copying is only possible with a runtime strategy.
The user wants… Route to Why (real reason)
Ongoing, hands-off, protected-on-every-fill senpi-strategy-author (their own runtime) continuous management + DSL on every fill
To browse what's already built senpi-strategy-discover DSL + risk gates + budget-relative sizing built in
To copy / mirror a trader, managed senpi-strategy-author → a managed mirror of their own (author forks the closest template when one fits) budget-relative sizing, auto-DSL, fresh-entry-only if they want
A genuine one-off, or to mirror one specific trader hands-on stay here direct execution the user is driving

Offer the managed option once, then respect a "no." For mirror, a managed mirror fixes the exact pains a raw mirror causes (tiny size, stale entries) — offer to build one before you reach for a raw strategy_create.


Branch A — Manual position (open / edit / close)

Opening is a FORK — ask which product, never assume

On "go long HYPE 10x" / "buy BTC" / "short NVDA", do not just place it. Ask which:

  • (A) A managed strategy — named, supervised, auto-DSL. → hand to senpi-strategy-author. Stop here.
  • (B) A one-off position — you place it, protection is your call. → proceed below.

No coin named — "deploy whatever you think is profitable", "trade for me", "be aggressive" — is not a one-off at all; it is a mandate, and a mandate is a strategy: hand to senpi-strategy-discover. Never pick the coins yourself and open them here.

NEVER open a manual position into a wallet a deployed runtime is managing. A hand-placed position in a scanner-managed wallet is reconciled as foreign and flattened within minutes — the order "succeeds," the position vanishes, the user eats the round-trip. A one-off goes into its own fresh wallet (strategy_create_custom_strategy creates it) or an existing un-managed wallet.

The interview (one question at a time; pre-fill anything already said)

  1. Asset & direction — turn what the user said into a ticker (Nvidia → NVDA, gold → GOLD), then look it up: market_list_instruments(query="<ticker>", fields=["max_leverage","only_isolated"]). Always pass query — the no-argument list is cut off long before the XYZ rows (stocks, metals, indices), so "not in the list I got" proves nothing. query matches tickers only, any case, with or without the prefix; a company name matches nothing. Copy the returned name verbatim into every later call — the other tools need it exact (kPEPE not KPEPE, xyz:NVDA not NVDA). Zero matches → one more lookup with a shorter or alternate ticker; only then say it isn't listed. A row with is_delisted: true is not tradeable — say so, never open it. More than one live match and none equal to the ticker → ask which one; never pick for the user. Never call an asset unavailable — or a whole class, like stocks — without a query lookup that came back empty. A name a tool rejected as unknown is never retried as-is.
  2. Size & leverage — you set marginAmount (USD collateral) + leverage; the engine derives size (notional = marginAmount × leverage). Min notional $10 (auto-bumped to $12). Look up max_leverage per asset — never hardcode. Never invent the amount — if unstated, ASK; don't default to the balance. Then the three numbers, before the replay: the share of the account this margin takes (marginAmount ÷ withdrawable), the dollars at the stop (|entry − stop| × size, and as a share of the account), and the leverage that will actually apply (the asset's max_leverage when it is lower than asked — say the clip; never name a strategy after a leverage the venue will not give). Above 50% of the account in one position or 20% of the account at the stop, put the number in its own sentence and get a fresh yes to that sentence — a yes to the setup is not a yes to the concentration. Re-run the three numbers on every add, every stop move and every leverage change, not only at open.
  3. Entry — MARKET (immediate, taker) or FEE_OPTIMIZED_LIMIT (maker, cheaper; add ensureExecutionAsTaker for a guaranteed fill).
  4. Protection — OPTIONAL, offer all three: (a) none, (b) a static stop/TP (stopLoss/takeProfit, percentage XOR price; margin-relative %; one fixed trigger, won't trail), or (c) a profit-lock ladder via ratchet_stop_add (tiered locks that trail up as you gain — profit-lock only; NO downside floor without a runtime; it replaces (b) if one exists — say so). Explain the difference in one line; let them pick. A price you send must be on the correct side of the live mark — check before the call. A long's stop sits BELOW the mark and a short's ABOVE; a take-profit is the mirror. The venue refuses the wrong side (SL trigger price 56.695 >= current price 56.180 for LONG position - would execute immediately), and on edit_position the size change commits first, so a refused stop leaves the position open and UNPROTECTED — the error says so in its own last line. Read the mark price from strategy_get_asset_trading_limits (wallet + coin) at the moment you build the call, never from entry, a percentage you applied in your head, or a price quoted earlier in the conversation. Re-sending the same price is the one thing that cannot work; recompute it from the mark. percentage picks the side but is measured from ENTRY, so once the mark is already past that level it is refused too — say so, and let the user choose between closing and a stop on the right side of the mark.

Then replay the full spec, get an explicit "yes", and place.

Execute & manage

  • Open: strategy_create_custom_strategy (fresh wallet + position [+ static SL/TP]) or create_position (into an existing un-managed wallet) — and always pass skillName + skillVersion (real params on both; strategy_create_custom_strategy creates a wallet outside deploy.py, so without them the position is orphaned / unattributed per CLAUDE.md). Async — report the real returned status, never assume success. Poll strategy_list to ACTIVE only when a next step needs the new wallet live: you will create_position into it, protect or read back the position it opened (below), or the user asked to wait. Never poll just to confirm the create.
  • Protect (if chosen): ratchet_stop_add on the open position (asset + tier config; it auto-reads the live position).
  • Read back the leverage: the position's leverage.value from strategy_get_clearinghouse_state is the one that applies — quote it, not the request; when the venue clipped it, say so and fix any name or label that carries the asked-for number.
  • "Watch it for me" on a raw position is the ladder, never a cron: ratchet_stop_add is the engine-side watcher at zero model cost (profit-lock only — say it has no downside floor without a runtime); a cron is a full agent turn per firing, and it is not a stop.
  • Edit: edit_position — targetMargin is absolute, not a delta; a direction flip does NOT carry SL/TP over. Partial close = edit_position with a lower targetMargin.
  • Close: close_position (full only; best-effort cancels resting SL/TP + DSL).
  • "Why did it close?" is a record question. Read the close before naming a reason — execution_get_closed_position_details, or the wallet's discovery_get_trader_history. A position you closed with close_position did not hit its take-profit: an agent close, a stop fill and a TP fill are three different outcomes and only the record says which. Never report a TP or stop as "hit" from the protection you configured, or from what you remember doing — a realized return far below the TP you set is the tell that something else closed it.

Branch B — Mirror a specific trader

0. Own the PICK — the user usually wants YOU to find the trader

The #1 real ask is "find me someone worth copying," not an address. Delegate the find + vet to the senpi-trader-research skill — its engine ranks track records and reads each trader's current book; don't hand-roll discovery_* here. Whether the trader comes back from there or the user pastes an address, hold it to the same bar before you mirror — 2–3 vetted candidates with max-drawdown + margin beside win-rate/ROI — never rank by ROI, never ROI alone. Two things the data will try to fool you on:

  • A 100% win rate is a warning, not a credential — it usually means near-zero closed trades or hidden unrealised drawdown. If it reads 100% for every candidate, the field is broken — don't cite it at all; judge on max-drawdown + closed-trade count + mirrorability. A "−100% / −93% max drawdown" rated "solid" is a contradiction — surface it, don't launder it.
  • Mirrorability is the go/no-go — check it before you recommend anyone. Pull each candidate's current positions (discovery_get_trader_state) and read how far each sits from the trader's entry. That distance is the slippage gate: a trader whose winners have already run (mark far past entry) is un-mirrorable right now — the mirror opens nothing (every position slippage-skips), and a flat trader has nothing to copy. The "best track record" is often the worst mirror today for exactly this reason. When the book has already moved, lead with a managed mirror that waits for the trader's next open instead of copying the old book (built with author) — or find a trader entering now. A mirror of the current book is a valid copy style but not the fix for an already-run book — don't sell it as one.

If the user pasted an address, still run both checks on it before mirroring.

Steer the product FIRST — the copy questionnaire (lead with capital use)

Before you run a raw mirror, find the right shape. Ask one at a time, pre-fill from the opening ask; the goal is to land them on a raw mirror or a managed mirror they build — recommend the fit.

  1. Capital use — ask this first; it is the #1 pain. "Do you want to use most of your capital in a few concentrated positions, or replicate the trader's exact proportional book?"
    • "use most of my funds / a few big orders / not 5% sitting idle" → a budget-relative managed mirror (built with author) — it sizes to your capital and opens a few full-size positions, which a proportional mirror won't (it tracks the trader's proportions). Common answer.
    • "exactly proportional to the trader" → raw mirror (below), sized via the multiplier. If the trader's account dwarfs the budget, match a closer-sized trader or raise the multiplier so positions clear the $10 floor — a proportional mirror preserves their utilization %, it doesn't shrink yours.
  2. Hands-on or hands-off? Drive one trader yourself → raw mirror. Set-and-forget, auto-DSL every fill → a managed mirror (author).
  3. What shape of copy? → one specific trader (raw) · anything managed — a whale cohort, 2–3 named traders on fresh entries only, one elite's biggest conviction bet, traders hot right now, the consensus of the top copy strategies, a rule of their own — is a managed mirror they build (→ senpi-strategy-author).
  4. Budget — their call; don't advise how much to trade. Just state the trader's minimum to run it properly (senpi-trader-research min_mirror_budget.min_budget_usd). If their budget is below it, say plainly it won't open their full book (below opens_nothing_below_usd, nothing opens) and offer a closer-sized trader, a higher multiplier, or a budget-relative managed mirror. The pre-fund sim confirms it.
  5. Protection — default follow their exits; offer an added DSL safety-net, especially if the trader runs without stops.

Route the answer: managed → senpi-strategy-author (it forks the closest template when one fits) · raw mirror of one specific trader → continue below. Offer the managed option once, then respect a "no."

How a mirror actually works — explain it from the single source

When the user needs the mechanics — and many do ("why did it open at a 30% different entry?", "why so small?", "do I need my own stop?", "spot or perps?", "how much do I need?") — explain from references/mirror-trading-explained.md, the one source every skill quotes. Always hit: sizing reality (small budget vs big trader = dust; the multiplier is locked; concentrated-use → a managed mirror), slippage is the entry gate (too tight opens nothing), you mirror their exits (unrealised PnL doesn't transfer), protection is optional and stacks (default: follow their exits). Never paraphrase a different version of this anywhere.

Set it up (interview; pre-fill what's given)

Vetted trader → budget → mirrorMultiplier (the size knob; immutable after creation — set it deliberately) → slippage tolerance (explain it above; set it against where their current positions sit — not a silent 1% that opens nothing) → optional protection (none / static strategy-level SL/TP on total PnL / per-position DSL).

The hero check — simulate BEFORE funding (a one-shot sizing estimate, not paper trading)

Senpi has no paper-trading mode; the estimate below says what would open right now, and the only live test is running the mirror at the $10 floor. Never offer to watch a trader on a timer — a cron is a model call per firing. Run execution_estimate_position_opening at the user's budget × multiplier × slippage before creating anything. It returns, per position, open / skipped(slippage) / skipped(budget) + minimumBudgetRequired — i.e. exactly what would open for them and at what size. Show the real $ and %. If little would open, STOP and offer: (a) more budget, (b) a higher multiplier, (c) a trader closer to their size, or (d) a managed mirror that enters only on fresh opens (author). This one check prevents the core failure: funding capital that then barely trades.

Create + verify — don't fabricate

strategy_create with the agreed params — and always pass skillName + skillVersion (both are real params on strategy_create and strategy_create_custom_strategy). This skill creates the wallet directly, outside deploy.py, so without them every mirror it opens is orphaned (unattributed) per CLAUDE.md. Report the status the call returned; never say a position opened that no read showed. Poll strategy_list to ACTIVE and read strategy_get_clearinghouse_state only when a next step needs the opened positions: the ladder below, or the user asked to wait or to see what opened. Never poll just to confirm the create. If that read shows the wallet idle past a short window, tell the user and adjust target / budget / multiplier — do not close+recreate (see below).

DSL on the mirror

ratchet_stop_add per opened position adds the profit-lock ladder (no runtime) — but that's profit-lock only, and it takes over the position's stop order: a static SL (edit_position) is the other option, not a companion — adding the ratchet replaces it, so say which one the user keeps. The real two-phase DSL (a ratcheting max-loss floor + the locks, integrated) needs a runtime → a managed strategy (author) that auto-applies it on every fill. Don't hand-wrap 40 fills a day.

Closing — present next steps as a LIST, never a paragraph

Whenever you end a mirror or template flow with options ("set it up / simulate first / compare / build a managed mirror on a specific whale"), render them as a short numbered or bulleted list, one option per line — never a run-on sentence with 1. 2. buried inline. Bold the action verb; one clear next step per line.


The guardrails — every one earned from real mirror-trading churn

If you're about to… Don't — because Do instead
Fund a mirror without simulating it It can deploy a tiny fraction of the budget — the rest sits idle Run execution_estimate_position_opening first (Branch B)
Mirror a whale whose account dwarfs the budget A small budget on a whale-sized account = dust — positions round below the $10 floor Check trader-account ÷ budget up front; if ~100×+, raise the multiplier or pick a closer-sized trader
Call ratchet_stop_add on a raw position "DSL protection", or say it "can't be protected" It's profit-lock only (no downside floor — Phase-1 is dropped); integrated two-phase DSL is runtime-only Offer profit-lock + a static SL on a raw position; steer to a managed strategy for real two-sided DSL
Say funds are "stuck" / "lost" / "file a ticket" PENDING_FUNDING self-completes; FAILED auto-refunds to the embedded wallet Poll transient states with backoff; check the on-chain balance before any alarm
Report a trade as placed off an EMPTY tool result, or keep polling for it Trade tools run behind the agent's approval gate: a call the user does not approve in time is denied and comes back empty — nothing reached the venue, so there is nothing to poll for Say the approval timed out and nothing was placed; offer to re-run it for approval. An errored call is different — it carries its own message: surface the verbatim tool text. Read strategy_list / positions only to confirm what actually exists
Fire a fund-movement tool on partial args A bridge call with {amount:0.01} errored nan Build fund calls from a validated template; never proceed as if funds moved when it errored
Rank copy targets by raw ROI Surfaced 100%-win / −100%-drawdown / 99.6%-margin wallets as "best" Filter on drawdown + margin + closed-trade count + copyability first
Recommend a "top" trader without checking their book is mirrorable The best track record is often the worst mirror today — the winners already ran, so the mirror opens nothing Read current-position distance-from-entry first; if it's run, steer to a managed mirror that waits for fresh entries
Leave slippage at a silent / too-tight default 1% on a trader whose positions already moved opens nothing — the mirror sits flat and looks broken Set slippage against the trader's current distance-from-entry; warn before funding if nothing would open
Close + recreate a mirror to "fix" it not trading Each round-trip skims ~$1.50 in fees; funds fragment The fix is target / budget / multiplier, not re-create
Re-derive state fresh each session and misread it User had to repeat "you didn't do what I asked" 3× Persist intent + strategy IDs; reconcile intended-vs-actual before replying
Place or grow a hand position without the three numbers A wallet went almost entirely into one thin coin and a "keep it tight" stop was widened to over 40% of the account, one small request at a time — nothing ever said the total Share of account, dollars at the stop, applied leverage — before the replay; above 50% / 20%, a fresh yes to that sentence
Quote the leverage the user asked for after the venue clipped it 10× asked, 3× applied, the position still labelled "10x" Read leverage.value from the position; say the clip; label by what applies
Offer a cron as "watch it for me" on a raw position Every firing is a full agent turn, and it is not a stop ratchet_stop_add — the ladder watches for free (profit-lock only; say so)
Promise a ratchet_stop_add on a runtime-managed position covers future entries The add binds to the position open now. The runtime arms the next one from the strategy's own exit.dsl_preset — so "it never closes below +X again" is false, and the next entry closes the old way Say the ladder covers this position only, then route the file half to senpi-strategy-ops (a DSL change has two targets — the file for future positions, the ratchet for open ones; the user picks)
Say anything about a stop or ladder, or change one, outside the protection protocol Every rule in it was broken on a live short — the user caught each one The six rules above, in order

State machine is transient, not terminal — up to a point. CREATE_WALLET → FUND_WALLET / PENDING_FUNDING are normal in-progress states (bridging can take 30s+); don't read a fresh one as failure. SERR045 ("requires ACTIVE") on a pending strategy means wait, not broken. FAILED money is refunded automatically. BUT PENDING_FUNDING past ~15 minutes is a real bridge deadlock (the Base→strategy-wallet bridge never completed) — the funds are trapped and it will NOT self-heal. Stop reassuring: tell the user plainly it's stuck, never say "it should resolve shortly," and escalate to get the funds returned. (Agents have churned users by promising a stuck deposit would clear when it never did.)


Handoff & boundaries

  • A request to act on one of the user's SAVED wallets (close, open, set a stop, cancel — on a wallet in user_get_me's external_wallets, the ones they added in Your wallets) → answer by quoting its access line, and make no write-tool attempt: "Read-only. Senpi can analyze this wallet. It cannot place, change or cancel orders on it." Reading user_get_me to recognise the address is fine. A write tool that comes back NOT_A_STRATEGY_WALLET (match the error code) is the same answer — never retry it on another tool. "Your wallet" means one of their saved wallets or one the user said is theirs in this conversation; an address pasted in chat is never described as saved — to save it, the user can add it in Your wallets on senpi.ai (web).
  • Finding / vetting the trader → senpi-trader-research. It ranks records + reads current books and hands the action (set up the mirror) back to this skill; you own the mechanics — slippage, sizing, the pre-fund sim, execution.
  • Ongoing hands-off management / DSL-on-every-fill / fresh-entry / budget-relative sizing → senpi-strategy-author (their own managed mirror or strategy; it forks the closest template when one fits). This skill executes the direct trade and can add per-position protection.
  • Mirror with custom rules — a position-count cap ("max 5; if he opens more, don't mirror"), a per-position % cap ("each ≤ 5% of my capital"), "don't copy his shorts", "capture his adds", or a conditional exit → a custom mirror runtime via senpi-strategy-author. Note the mirrorMultiplier is immutable after creation — a user who wants to change size live must redeploy; there is no in-place edit.
  • "How's my mirror doing?" / compare my mirrors / is my trader still active / why didn't it fire → read references/mirror-monitoring.md — it composes your mirror's state (senpi-portfolio / strategy_get_clearinghouse_state) with the OG's current book (senpi-trader-research) and diffs them (are you still tracking, did the OG go idle, which positions drifted). After you create a mirror, tell the user they can ask any time.
  • Close / withdraw / rebalance a mirror → senpi-strategy-ops (close a mirror, reclaim funds, top-up, or shift budget between mirrors). A mirror is a strategy — lifecycle actions live in ops, not here.
  • A pasted address (I want to mirror trade 0x…) is the single most common entry — vet it through senpi-trader-research (mirrorability + drawdown) before mirroring, even when it's a popular wallet everyone is asking about. Don't rubber-stamp a hot address.
  • Never send USDC to an external address (no tool for it — direct the user to the app), and never present a strategy wallet as a deposit target.
  • Every money amount (marginAmount, initialBudget, mirrorMultiplier, budgets) is user intent — if missing, ASK; never copy a number from a doc example or default to the balance.

Red flags — STOP and re-check

  • You're about to strategy_create a mirror without having run the deployability sim.
  • You're about to call ratchet_stop_add on a raw position "DSL protection" — it's profit-lock only (no downside floor without a runtime); offer a static SL and/or a managed strategy for real two-sided DSL.
  • You're about to tell the user funds are "stuck", or to treat an EMPTY tool result as a placed trade — an unapproved (timed-out) call is denied and executes nothing; say so and offer the re-run.
  • You're about to open a manual position into a wallet a runtime is managing.
  • You're about to close+recreate a mirror that "isn't trading."
  • You're about to say anything about a stop or ladder — or change one — without the protection protocol's same-turn read and yes.
  • You're quoting a trader's ROI/win-rate with no drawdown beside it.
  • You're about to recommend mirroring a trader whose current positions have already run past their entry — the mirror would open nothing.
  • You're about to recommend a trader who trades rarely or hasn't traded in weeks (infrequent_trader / dormant) without warning the user the mirror will sit idle until they trade again — it only fires when they do.
  • You're about to promise a mirror "will replicate shortly" or a stuck strategy "should resolve" — verify on-chain first; never predict a sync that hasn't happened.

All of these mean: stop, run the check, correct the framing, or route to the managed path.

04 同仓库更多 Skills