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 = 0.00001, tmult = FALSE, replace = TRUE, return = FALSE, ..., TxnFees = 0, label = "", time.in.force = "")
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.ruleSignal
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:
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
.
updateOrders