It is important to understand that all the order functionality included in quantstrat
exists to more closely model a real trading environment both in backtesting and in production.
Many backtesting systems make a set of assumptions about instant execution,
and we have chosen not to do this in quantstrat, because real quantitative
trading systems do not have instant execution. They make decisions
(the Rules) and then enter orders (the province of this function in backtesting),
during which there is some delay
between receiving the data that fires the
Signal and Rule, and the time the order reaches the market, and then those orders
MAY become transactions if market prices and liquidity cooperate.
addOrder(portfolio, symbol, timestamp, qty, price, ordertype, side,
threshold = NULL, orderset = "", status = "open",
statustimestamp = "", prefer = NULL, delay = 1e-05,
tmult = FALSE, replace = TRUE, return = FALSE, ..., TxnFees = 0,
label = "", time.in.force = "")
text name of the portfolio to associate the order book with
identfier of the instrument to find orders for. The name of any associated price objects (xts prices, usually OHLC) should match these
timestamp coercible to POSIXct that will be the time to search for orders before this time
numeric quantity of the order, or "all" or "trigger"
numeric price at which the order is to be inserted
one of "market","limit","stoplimit", "stoptrailing" or "iceberg"
one of either "long" or "short"
numeric threshold to apply to limit, stoplimit, stoptrailing and iceberg orders, default NULL
set a tag identifying the orderset
one of "open", "closed", "canceled", "revoked", or "replaced", default "open"
timestamp of a status update, will be blank when order is initiated
the prefered order price (eg. 'Close')
what delay to add to timestamp when inserting the order into the order book, in seconds
if TRUE, threshold is a percent multiplier for price
, not a scalar. Threshold is converted to a scalar by multiplying it with the price at the time of order entry (i.e. the scalar will not change if the order is updated, as in the case of a trailing stop), then it is added to the price just like a scalar threshold.
TRUE/FALSE, whether to replace any other open order(s) on this symbol with the same properties as this order, default TRUE, see Details
if TRUE, return the row that makes up the order, default FALSE (will assign into the environment)
any other passthru parameters
numeric fees (usually negative) or function name for calculating TxnFees (processing happens later, not in this function)
text label, default to '', set to rule label by ruleSignal
timestamp time-in-force; either a time stamp, or a number of seconds, or 'GTC' / '', 'GTC' and '' both meaning 'Good Till Canceled'; order expires if still 'open' at this timestamp, default is ''
By default, this function will locate and replace any 'open' order(s)
on the requested portfolio/symbol that have the same order
type and side. If an orderset is also specified and replace=TRUE,
all open orders for the orderset will be replaced.
If you do not want open orders to be canceled and replaced with the new order,
set replace=FALSE
.
We have modeled a 'limit' order, used to enter or exit a position at a specific price, determined by the
prefered price (see prefer
) plus threshold
(see below).
We have modeled two types of stop orders, which should be sufficient to model most types of stops.
We have modeled the simplest type, a 'stoplimit' order, which is just a limit order used to enter
or exit a position at a specific price, determined by the prefered price (see prefer
) plus threshold
(see below). The stoplimit order type can be used to implement both stop-enter (long/buy or short/sell)
and stop-loss (long/sell or short/buy) style limit orders. There is no functional difference between a
regular 'limit' order and a 'stoplimit' order once entered into the order book, but the distinction will
likely be useful for reporting on when stops have been triggered.
We have also modeled a 'stoptrailing' order, which may be used to model dynamic limit-based exit. The
threshold
will be calculated only once upon order entry (see below) and remain fixed for the life span
of the order. In this way, a 10 pct trailing exit will not change in size from the current price as the
price changes. Be aware that a stoptrailing order may be moved ("replaced") frequently.
Some markets and brokers recognize a stop that triggers a market order, when the stop is triggered, a market order will be executed at the then-prevailing price. We have not modeled this type of order.
We have also added the 'iceberg' order type. This order type should
most often be paired with delay
and osMaxPos
. The
iceberg order when initially entered is treated like a limit
order, with an optional threshold
(which is applied at initial order
entry, so be careful). Right now, they will enter a new order at price+threshold
upon any execution of the prior iceberg order. This process could
be infinite if osMaxPos
or an equivalent order sizing
function is not used to limit total position size. An order delay
is also advisable to model the delay that occurs between getting the trade
confirmation of the previous trade and entering the new order into the order book.
The 'limit', 'stoplimit', 'stoptrailing' and 'iceberg' order types are the only order types that make
use of the order threshold
. Thresholds may be specified in one of 2 ways: as a scalar (tmult=FALSE
)
or as a multiplier for the current price (tmult=TRUE
). If tmult=TRUE
, threshold
is converted to a
scalar by multiplying it with the price at the time of order entry, and the scalar will not change if the order is updated.
The threshold is then added to the prefered order price upon order entry. The correct sign for the threshold (pos or neg, ie. add or subtract) is automagically figured out from the order side and the order quantity (buy or sell); if the user provides the wrong sign for the threshold, then it will be reversed. In other words, the user may provide all thresholds as a positive number, and the software will automagically figure out whether to add or subtract the threshold amount from the price.
If you ever wanted to move from a backtesting mode to a production mode,
this function (and the linked funtion ruleOrderProc
) would
need to be replaced by functions that worked against your execution environment.
Basically, the execution environment must provide three interfaces in a live
trading environment:
a market data interface to provide updated market data, usually accessed in an event loop
an order interface for sending orders (and canceling or updating them) to the market
a fill interface that reports the transaction details when an order has been filled
Conversion to a live trading environment will also likely require a new version of
applyStrategy
to provide the event loop interface and interact with mktdata
.
getOrderBook
updateOrders