Skip to content
jeff.finance.trading-deskv1.4.0

Trading desk decisions

Applies a trading desk's written rules to the current order book. Selects buy, sell or hold, trade size, venue, actions for open orders and whether to reduce risk.

Open in playground

Example

Context

desk
Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
market_context
Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.

Input

Time 13:12:05. Mid 40.31, 20-minute average 40.88. Spread 5 bp. Order-flow imbalance -0.42. Realised volatility (5 min) 38% annualised. Position: long 2,500 shares, average price 41.35. Day P&L on this stock: -26,400. Open orders: none. News: none flagged.

Answer (JSON)
value yes, confidence 1
Top options
  1. yes 1
  2. no 0

The day's loss on the stock is beyond the limit the desk's rules set, so the answer to going risk-off is yes.

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.risk_off", context={        "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).",        "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.",    })     decision = decide("Time 13:12:05. Mid 40.31, 20-minute average 40.88. Spread 5 bp.\nOrder-flow imbalance -0.42. Realised volatility (5 min) 38% annualised.\nPosition: long 2,500 shares, average price 41.35. Day P&L on this stock: -26,400.\nOpen orders: none. News: none flagged.")     print(decision.value, decision.confidence)

More examples

  • Calm afternoon inside every limitanswer no · confidence 1

    Context

    desk
    Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Routing: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
    market_context
    Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.

    Input

    Time 14:05:10. Mid 41.18, 20-minute average 41.22. Spread 4 bp. Order-flow imbalance +0.05. Realised volatility (5 min) 22% annualised. Position: long 500 shares, average price 41.05. Day P&L on this stock: +1,850. Open orders: none. News: none flagged.

    Answer (JSON)
    value no, confidence 1
    Top options
    1. no 1
    2. yes 0

    The desk is in profit, volatility is low and there is no news, so no trigger is met and the answer is no.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.risk_off", context={        "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRouting: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).",        "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.",    })     decision = decide("Time 14:05:10. Mid 41.18, 20-minute average 41.22. Spread 4 bp.\nOrder-flow imbalance +0.05. Realised volatility (5 min) 22% annualised.\nPosition: long 500 shares, average price 41.05. Day P&L on this stock: +1,850.\nOpen orders: none. News: none flagged.")     print(decision.value, decision.confidence)
  • Mid well below its averageanswer buy · confidence 0.956

    Context

    desk
    Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Routing: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
    market_context
    Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.

    Input

    Time 11:20:30. Mid 40.80, 20-minute average 41.25 (mid 1.1% below). Spread 4 bp. Order-flow imbalance -0.10. Realised volatility (5 min) 25% annualised. Position: flat. Day P&L on this stock: +300. Open orders: none. News: none flagged.

    Answer (JSON)
    value buy, confidence 0.956
    Top options
    1. buy 0.956
    2. hold 0.03
    3. sell 0.014

    The mid is 1.1% below its 20-minute average and no filter blocks a trade, so the next action is buy.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.direction", context={        "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRouting: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).",        "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.",    })     decision = decide("Time 11:20:30. Mid 40.80, 20-minute average 41.25 (mid 1.1% below). Spread 4 bp.\nOrder-flow imbalance -0.10. Realised volatility (5 min) 25% annualised.\nPosition: flat. Day P&L on this stock: +300.\nOpen orders: none. News: none flagged.")     print(decision.value, decision.confidence)
  • Buy signal blocked by a wide spreadanswer hold · confidence 1

    Context

    desk
    Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Routing: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
    market_context
    Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.

    Input

    Time 11:24:02. Mid 40.78, 20-minute average 41.25 (mid 1.1% below). Spread 12 bp. Order-flow imbalance -0.30. Realised volatility (5 min) 31% annualised. Position: flat. Day P&L on this stock: +300. Open orders: none. News: none flagged.

    Answer (JSON)
    value hold, confidence 1
    Top options
    1. hold 1
    2. sell 0
    3. buy 0

    The buy rule is met but the spread is wider than the desk's 8 basis points, so the action is hold.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.direction", context={        "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRouting: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).",        "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.",    })     decision = decide("Time 11:24:02. Mid 40.78, 20-minute average 41.25 (mid 1.1% below). Spread 12 bp.\nOrder-flow imbalance -0.30. Realised volatility (5 min) 31% annualised.\nPosition: flat. Day P&L on this stock: +300.\nOpen orders: none. News: none flagged.")     print(decision.value, decision.confidence)
  • Only one lit venue shows enough sizeanswer venue_a · confidence 0.759

    Context

    desk
    Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above. Clip size: 500 shares. Position limit: 3,000 shares either way. Filters: no new trades when the spread is wider than 8 basis points, or after 15:45. Routing: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order. Risk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged "material" on this stock. Venues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).
    market_context
    Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.

    Input

    Time 11:20:31. Request: route a new buy order for 500 shares at the ask. Displayed size on the ask: venue_a 900 shares at 40.82; venue_b 200 shares at 40.82; venue_c 100 shares at 40.82. Spread 4 bp.

    Labels (the options)

    venue_a
    Lit exchange, fee 0.3 bp, 0.4 ms
    venue_b
    Lit exchange, rebate 0.1 bp, 1.1 ms
    venue_c
    Dark pool, fee 0.1 bp, 2.0 ms
    Answer (JSON)
    value venue_a, confidence 0.759
    Top options
    1. venue_a 0.759
    2. venue_b 0.171
    3. venue_c 0.071

    Only the first lit exchange shows enough size on the ask for the whole order, so the order goes to venue_a.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.route", context={        "desk": "Strategy: mean reversion on one stock. Buy when the mid is more than 0.6% below its 20-minute average, sell when more than 0.6% above.\nClip size: 500 shares. Position limit: 3,000 shares either way.\nFilters: no new trades when the spread is wider than 8 basis points, or after 15:45.\nRouting: send each order to the venue with the lowest fee whose displayed size on the order's side covers the whole order.\nRisk-off triggers: (1) the day's loss on this stock exceeds 25,000; (2) realised volatility over 5 minutes is above 60% annualised; (3) a trading halt or a news alert flagged \"material\" on this stock.\nVenues: venue_a (lit exchange, fee 0.3 bp, 0.4 ms), venue_b (lit exchange, rebate 0.1 bp, 1.1 ms), venue_c (dark pool, fee 0.1 bp, 2.0 ms).",        "market_context": "Stock: a mid-cap European industrial. Date: 2 November 2026. Opening mid 41.20; morning range 40.95 to 41.60; typical spread 4 bp; trading normal.",    }, labels={        "venue_a": "Lit exchange, fee 0.3 bp, 0.4 ms",        "venue_b": "Lit exchange, rebate 0.1 bp, 1.1 ms",        "venue_c": "Dark pool, fee 0.1 bp, 2.0 ms",    })     decision = decide("Time 11:20:31. Request: route a new buy order for 500 shares at the ask.\nDisplayed size on the ask: venue_a 900 shares at 40.82; venue_b 200 shares at 40.82; venue_c 100 shares at 40.82.\nSpread 4 bp.")     print(decision.value, decision.confidence)

Use when

  • Your desk has written rules for entry levels, sizing, position limits, venues, order handling and risk-reduction triggers.
  • Uncertain decisions should be referred to a person or a further check based on their probabilities.

Avoid when

  • You need price forecasts or a trading strategy; this adapter applies the rules provided.
  • The rules are simple enough to implement directly in code.

Context and input

FieldKindDescription
market_state
inputThe live state: time, order book, spread, mid and its average, order-flow imbalance, realised volatility, recent trades, displayed size per venue, position and P&L, open orders, parent order, news, and the request.
desk
contextThe desk definition: strategy and entry rule, clip size, position limit, spread and cut-off filters, order handling, risk-off triggers, the instrument, the venues with fees and latencies, and the routing rule.
market_context
contextThe stock and the day: date, opening mid price, the morning's range and spread, and whether trading is calm, normal or active.

Functions

KeyInterfaceInstructionsLabels
routeclassifyYou are the order router of an automated trading desk. Send the new order described in the request line of the live market state to one of the desk's three venues, using the routing rule in the desk definition. A buy order takes the ask side and a sell order takes the bid side, so compare the order size with each venue's displayed size on that side.venue_a, venue_b, venue_c
risk_offclassifyYou are the risk check of an automated trading desk. Decide whether the desk must go risk-off now under the risk-off triggers in its desk definition. Going risk-off means the desk stops opening trades in this stock, cancels its orders and reduces its position. Answer yes if any one trigger is met by the live market state, otherwise no.yes, no
directionclassifyYou are the decision step of an automated trading desk. The desk definition states the strategy's entry rule, the clip size (the standard order size), the position limit, a maximum spread and a cut-off time for new trades. Apply them to the live market state and choose the next action. Use only these entry rules: risk-off triggers, open orders and order routing are decided separately.buy, sell, hold
sizeclassifyYou are the decision step of an automated trading desk. A volatility-target desk sizes its position from realised volatility and the unrealised loss on its position; an execution desk paces a client parent order against its schedule and its limit price. Apply the sizing or pacing rule in the desk definition to the live market state.increase, decrease, keep
orderclassifyYou manage the open orders of an automated trading desk. Decide what to do with the open order named in the request line of the live market state, using the order rules in the desk definition. 'Ticks behind' is the distance from the best price on the order's own side (the best bid for a buy order, the best ask for a sell order).cancel, amend, leave

How it was measured

Test accuracy: the share of test rows whose top answer was right.

  • 97.7% on the in-house test of simulated order books (5,000 rows). in-house: same generator as the training data

When confident

From the calibration set: at or above the threshold confidence, how often the answer is right, and how often the adapter is that confident. Below it, escalate.

FunctionRight when confidentConfident onThresholdCalibration rows
route99.4%90.5%0.81200
risk_off100.0%100.0%0.9996200
direction100.0%100.0%0.98200
size99.2%63.0%0.97200
order100.0%100.0%0.999200

Base: Jeff v1.4. Adapter trained: 25 October 2026.

Base

jeff-base v1.4

Call it

jeff.finance.trading-desk.route, with placeholders for its input and context.

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.finance.trading-desk.route", context={        "desk": "<desk>",        "market_context": "<market_context>",    })     decision = decide("<market_state>")     print(decision.value, decision.confidence)

Download

Weights: mstrasser/jeff-adapter-trading-desk (v1.4)

Licence: Apache-2.0