Order Verbs
תוכן זה אינו זמין עדיין בשפה שלך.
Five verbs, each with exactly one meaning, in standard brokerage vocabulary.
| Verb | Meaning | Auto-sized? |
|---|---|---|
buy |
Enter long from flat. | Yes — from sizing model. |
sell_short |
Enter short from flat. | Yes — from sizing model. |
sell |
Exit or reduce an existing long. | No — explicit quantity required. |
buy_to_cover |
Exit or reduce an existing short. | No — explicit quantity required. |
order |
Raw order, no position semantics. | No — explicit qty + direction. |
Entry verbs: buy, sell_short
Auto-sized from the class-level sizing declaration. Take exactly one positional arg (the trade symbol). Additional positional args → RC2_ENTRY_EXTRA_ARG.
self.buy(self.trade, stop=price) # stop order, auto-sizedself.buy(self.trade, limit=price) # limit order, auto-sizedself.buy(self.trade, reason="Long signal") # market order with reasonself.buy(self.trade) # market order
self.sell_short(self.trade, stop=price) # short entry, auto-sizedself.sell_short(self.trade, limit=price) # short entry, restingself.sell_short(self.trade, reason="Short signal")Allowed kwargs
| Kwarg | Effect |
|---|---|
stop=price |
Make it a stop order instead of market. Fills at price. |
limit=price |
Make it a limit order instead of market. Fills at price or better. |
reason="..." |
Free-text annotation stored with the fill (separate from print(), which goes to the Console tab). |
qty=N |
Override sizing (only on FixedQuantity). |
percent=N |
Override sizing (only on FixedCapital / Compounding). |
stop= and limit= are the same slot on the wire and opposite geometries, so passing both is
RC2_ORDER_TYPE_CONFLICT. Quantity still comes from the sizing
model either way — a resting order resolves its size at fill time, from the price it actually filled
at, not from the price when you placed it.
Mismatching qty= or percent= to the sizing model raises RC2_OVERRIDE_INVALID:
sizing = FixedCapital()self.buy(self.trade, qty=10) # ❌ qty= not allowed on FixedCapitalself.buy(self.trade, percent=50) # ✅Exit verbs: sell, buy_to_cover
Explicit quantity is always required (positional arg). Sizing model isn’t involved. No qty= or percent= kwargs.
self.sell(self.trade, self.trade.position, stop=price) # full exit longself.sell(self.trade, self.trade.position, limit=price) # resting take-profitself.sell(self.trade, self.trade.position / 2) # partial exitself.sell(self.trade, 50) # fixed partial exit
self.buy_to_cover(self.trade, self.trade.position, stop=price) # full coverself.buy_to_cover(self.trade, self.trade.position, limit=price) # resting coverself.buy_to_cover(self.trade, self.trade.position / 2) # partial coverExits take stop= and limit= on the same terms as entries — one or the other, never both. A
limit= exit is the resting take-profit shape: it fills only if price comes to you, and expires
unfilled otherwise. If you want a level that is checked continuously and never expires, that is a
take_profit rule, not an order.
Forgetting the quantity → RC2_EXIT_NO_QTY:
self.sell(self.trade, stop=price) # ❌ — qty is required on sellPassing qty= or percent= to an exit verb → RC2_EXIT_NO_KWARGS.
Raw verb: order
The escape hatch for pyramiding, hedging, or manual sizing. Both qty and direction are required.
self.order(self.trade, qty=5, direction=Buy, stop=price)self.order(self.trade, qty=5, direction=Sell, stop=price)self.order(self.trade, qty=5, direction=Buy, limit=price)self.order(self.trade, qty=5, direction=Sell, limit=price)direction uses the action terms Buy / Sell — these are language constants, not strings. Missing qty or direction → RC2_ORDER_MISSING.
Fill timing
| Order type | Fires when | Fills at |
|---|---|---|
| Market | Always | The next bar’s open (T+1). |
| Buy stop | Price rises to the level | The stop price — or the bar’s open if it gapped above. |
| Sell stop | Price falls to the level | The stop price — or the bar’s open if it gapped below. |
| Buy limit | Price falls to the level | The limit price — or the bar’s open if it gapped below (price improvement). |
| Sell limit | Price rises to the level | The limit price — or the bar’s open if it gapped above (price improvement). |
You never fill on the same bar you signal — that prevents look-ahead bias and matches how real exchanges work.
A resting order gets one bar to fill. If the next bar’s range never reaches the level, the order expires; it is not carried forward. Re-issue it each bar if you want it to keep resting:
class RestingEntry(Strategy): trade = Symbol() sizing = FixedCapital()
def execute(self): if self.trade.is_flat: self.buy(self.trade, limit=self.trade.close * 0.99, reason="Rest 1% below")Because the order fills at its level (or better), sizing follows: a FixedCapital entry that fills
1% cheaper buys correspondingly more. Quantity is resolved from the fill price, never from the
price at the moment you placed the order.
Hard rules
- The first positional argument is always the symbol slot (
self.trade).self.buy(stop=price)without it isRC2_SIG_SYMBOL. - Orders can only target the trading symbol.
self.buy(self.spy, ...)against a data feed isRC2_SIG_DATAFEED. - At most one signal per execution path per bar. Two consecutive
self.buy()calls in the same branch are silently merged into the first. - An entry verb when already in the same direction is silently skipped.
self.buy()while long is a no-op. - An exit verb when flat fills 0 shares — also a no-op.
Common diagnostics
| Code | What it means |
|---|---|
RC2_ENTRY_EXTRA_ARG |
Entry verb got more than one positional arg. |
RC2_EXIT_NO_QTY |
Exit verb missing the quantity positional. |
RC2_EXIT_NO_KWARGS |
Exit verb received qty= or percent=. |
RC2_OVERRIDE_INVALID |
Override kwarg doesn’t match the sizing model. |
RC2_SIG_SYMBOL |
First arg isn’t a symbol slot. |
RC2_SIG_DATAFEED |
Order targets a data feed. |
RC2_SIG_UNKNOWN |
Verb name isn’t a recognized order verb. |
RC2_ORDER_MISSING |
order() missing qty= or direction=. |
RC2_ORDER_TYPE_CONFLICT |
One verb carried both stop= and limit=. |