דלגו לתוכן
פתיחת RaamTrade

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-sized
self.buy(self.trade, limit=price) # limit order, auto-sized
self.buy(self.trade, reason="Long signal") # market order with reason
self.buy(self.trade) # market order
self.sell_short(self.trade, stop=price) # short entry, auto-sized
self.sell_short(self.trade, limit=price) # short entry, resting
self.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 FixedCapital
self.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 long
self.sell(self.trade, self.trade.position, limit=price) # resting take-profit
self.sell(self.trade, self.trade.position / 2) # partial exit
self.sell(self.trade, 50) # fixed partial exit
self.buy_to_cover(self.trade, self.trade.position, stop=price) # full cover
self.buy_to_cover(self.trade, self.trade.position, limit=price) # resting cover
self.buy_to_cover(self.trade, self.trade.position / 2) # partial cover

Exits 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 sell

Passing 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 is RC2_SIG_SYMBOL.
  • Orders can only target the trading symbol. self.buy(self.spy, ...) against a data feed is RC2_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=.