partial profits added to slider

Let traders pre-arm tiered partial exits (e.g., 25% @ TP1, 50% @ TP2, trail remainder) via a slider UI. Orders are server-side (not client-dependent), OCO-linked, tick-rounded, and risk-checked.


User Experience (UX)

  • Slider with up to 3 targets (configurable):

    • Knobs = TP1/TP2/TP3 price levels (drag to price or type exact level).

    • Fill bars / handles show % to close at each target (e.g., 25%, 50%, 25%).

    • Toggle “Trail remainder” with offset (ticks or ATR multiple).

    • Quick-set buttons: 1R / 2R / 3R, Last swing high/low, +X ticks.

  • Per-account or grouped: if copy-trading, apply same risk % per account or map using copy-ratio.

  • “Arm” vs “Live”:

    • Armed: preview shows working child orders that will post on entry.

    • Live: after entry, child orders are placed and server-managed.


Data Model

// shared types type AccountId = string; type Symbol = "ES" | "NQ" | string; interface TpTier { price: number; // exchange price, rounded to tick size pct: number; // 0..100, sum across tiers <= 100 } interface TpPlan { tiers: TpTier[]; // e.g., [{price: 5400.00, pct: 25}, ...] trailRemainder?: { // optional trailing for leftover qty mode: "ticks" | "atr"; value: number; // ticks or ATR multiple activationPrice?: number; // optional }; reduceOnly: boolean; // enforce exits only goodTil: "DAY" | "GTD" | "GTC"; } interface ArmedPlan { symbol: Symbol; side: "LONG" | "SHORT"; // determines TP direction qtyPlan: { // how quantity is computed mode: "fixed" | "percent"; value: number; // fixed contracts OR % of open qty }; tp: TpPlan; riskEnvelopeId?: string; // link to risk ruleset copyMap?: CopyRatio[]; // optional for multi-account } interface CopyRatio { accountId: AccountId; qtyRatio: number; // e.g., 0.5 → half the base qty; supports floor>=1 tick-size rules dollarCap?: number; // max notional per account } 

Client (React/TypeScript) – Slider Component (core idea)

function TpSlider({ price, tickSize, initialPlan, onChange }: { price: number; tickSize: number; initialPlan: TpPlan; onChange: (tp: TpPlan) => void }) { // internal state manages tier prices & percents // Ensure tick rounding on drag const round = (p:number)=> Math.round(p / tickSize) * tickSize; // Emit onChange with validated tiers (sum<=100, each pct>=0) // Visual handles = prices; separate mini-sliders = % allocations // Not full code—shows architecture & validation hooks return ( <div className="tp-slider"> {/* price handles, percent sliders, quick presets, trail toggle */} </div> ); } 

Key client behaviors:

  • Tick rounding on drag/end.

  • Validation: sum of pct ≤ 100; show remaining remainder.

  • Latency-safe: arming only configures; no orders until server confirms “live.”

  • WebSocket stream shows working child orders / fills in real time.


Backend API (REST + WS)

POST /api/tp/arm Body: ArmedPlan + { accounts: AccountId[] } Resp: { armedPlanId, preview: ChildOrderPreview[] } POST /api/tp/activate Body: { armedPlanId, parentOrderId } // called after entry placed/filled Resp: { childOrderGroupId } POST /api/tp/cancel Body: { childOrderGroupId } WS feed: /stream/orders // publishes child order lifecycle & fills 

Preview endpoint simulates tier splits, tick rounding, and risk caps before anything hits the exchange.


Order-Engine Logic (server-side)

  1. On entry filled (or partially filled), compute activeQty per account.

  2. For each account:

    • Apply copyMap.qtyRatio (if present) OR base qty.

    • Compute tierQty = floor(activeQty * tier.pct/100) with minQty=1 where allowed; fix rounding by adding remainder to the last tier.

    • Direction:

      • Long → TPs above entry; Short → below.

      • Validate distance≥1 tick and within exchange price bands.

  3. Place child orders as Reduce-Only Limit at each tier price, OCO-grouped with stop(s) if you support brackets.

  4. If trailRemainder:

    • After last fixed tier is filled (or from activationPrice), register a server-side trailing stop (ticks/ATR).

    • Chase logic runs on server, not client (protects against app disconnects).

  5. OCO & State Machine

    • Each tier limit is OCO with a group cancel on Flatten or Stop hit.

    • If a tier partially fills, update remaining tier qty or collapse to next tier per policy.

  6. Risk checks (pre-trade + post-trade):

    • Verify Topstep rules (max daily loss, trailing drawdown, product limits).

    • Block orders that would breach limits; return reason codes to client.


Exchange/FIX Details (CME futures aware)

  • Use Reduce-Only (or synthetic) + TimeInForce (DAY, GTD, or synthetic GTC if the venue requires).

  • Tick rounding with instrument metadata (min price increment varies by symbol).

  • Respect price bands / velocity logic—reject if price outside.

  • Support partial fills: maintain remainingQty and cascade adjustments.

  • Idempotency keys per child to avoid dupes on retries.


Pseudocode (core engine)

def activate_tp_plan(armed_plan, parent_fill): entry_price = parent_fill.avg_price active_qty = parent_fill.filled_qty for acct in accounts(armed_plan): base = apply_copy_ratio(active_qty, acct, armed_plan.copyMap) tiers = [] running = 0 for i, t in enumerate(armed_plan.tp.tiers): q = int(floor(base * t.pct / 100)) if i == len(armed_plan.tp.tiers) - 1: q = max(base - running, 0) # allocate remainder running += q if q <= 0: continue price = round_to_tick(t.price, instrument.tick) side = "SELL" if armed_plan.side=="LONG" else "BUY" tiers.append(place_limit_reduce_only( account=acct, symbol=armed_plan.symbol, side=side, qty=q, price=price, oco_group=f"TP-{parent_fill.order_id}" )) if armed_plan.tp.trailRemainder and running < base: qty_left = base - running place_trailing_stop( account=acct, symbol=armed_plan.symbol, side=("SELL" if armed_plan.side=="LONG" else "BUY"), qty=qty_left, mode=armed_plan.tp.trailRemainder.mode, value=armed_plan.tp.trailRemainder.value, activation=armed_plan.tp.trailRemainder.activationPrice, oco_group=f"TP-{parent_fill.order_id}" ) return {"status":"live", "group": f"TP-{parent_fill.order_id}"} 

Risk & Compliance Guardrails

  • Reduce-Only enforced; never increases exposure.

  • Per-tier dollar caps and per-account notional caps.

  • Auto-flatten on: daily loss breach, trailing drawdown breach, or end-of-session policy.

  • Audit log: every config, calculation, and exchange ACK with timestamps.


Copy-Trading Compatibility

  • On activation, apply account-specific ratios: e.g., base qty from the “lead” account, map 150K:50K = 3:1.

  • All child orders inherit the per-account qty after ratioing; TP percentages remain consistent across accounts.


Edge Cases to Handle

  • Partial parent fills: arm TPs only for filled qty; on additional fills, append or rebalance per policy.

  • Price knob overlap: if TP2 dragged below TP1, auto-swap or block until valid.

  • Zero/low qty after rounding: borrow one contract from the next tier to keep at least 1 where allowed.

  • Connection loss: orders live on server; client just reflects state via WS.

  • Market gaps: if TP price crosses gap and is invalid, convert to market-to-limit with band checks.


Testing Plan (high level)

  • Unit: tick rounding, qty split, copy ratios, ATR trailing math.

  • Sim: partial fills, rapid fills, rejects, cancels, OCO behavior.

  • UAT: latency, WS updates, cross-account consistency, rule-breach auto-flatten.


Why this is minimal-risk to ship

  • Uses primitives most venues/brokers already support: reduce-only limit, trailing stop, OCO.

  • Server-side orchestration means no UX dependency for execution safety.

  • Backward-compatible: if slider is off, nothing changes.


If you want, I can also provide:

  • A drop-in React component with tick-aware handles and percent mini-sliders.

  • A Node/Python reference microservice that converts a TP plan → exchange orders (with mock FIX/REST adapters).

  • A QA checklist specific to ES/NQ (CME) session boundaries and price bands.

Want me to package this into a one-page PDF spec you can forward to their product/engineering lead?

Please authenticate to join the conversation.

Upvoters
Status

In Review

Board

💡 Feature Request

Tags

Risk Tools

Date

6 months ago

Author

Joseph Smith

Subscribe to post

Get notified by email when there are changes.