applyStrategy
. In this mode, this function
will be called twice, once with path.dep=FALSE
and
then again in stepping over the time indexes of the mktdata
object.
applyRules(portfolio, symbol, strategy, mktdata, Dates = NULL, indicators = NULL, signals = NULL, parameters = NULL, ..., path.dep = TRUE, rule.order = NULL, debug = FALSE)
path.dep=FALSE
add.rule
, the first step in
this dimension reduction is to look for places in the
time series where signals may cause the strategy to enter
or change orders. This creates an index of timestamps
that must be evaluated. This index should be
significantly shorter than the full number of
observations. quantstrat
will always run
applyRules
on each of these indices where we've
previously figured out that the strategy might want to do
something. The next step in dimension reduction works on the order
book. If there are open orders, we need to figure out
when they might get filled. For market orders, this is
the next observation. For limit orders, we can locate
the index timestamps after the order is placed to see
when the order might cross. We will add this index to
the list of indices to be evaluated. There is of course
no guarantee that the order will still be open at that
time, that trading will not be on hold
because of
a risk rule, or that something else hasn't interfered.
Adding the index to the list only tells the loop inside
applyRules
that rules (including order processing
rules) need to be checked at that index, to see if
anything needs to happen. For trailing orders, the picture is somewhat more
complicated. Trailing orders may move on each new
observation, per the method described in
addOrder
. To speed up evaluation of when
such an order may cross, we need to combine the possible
crossing logic for the limit orders, above, with some
additional logic to handle the trailing orders. We begin
by evaluating when the order price might be moved. We
then examine the market data between the current index
and the point at which the order may move. if there is a
(possible) cross, we insert that index into the indices
for examination. If not, we insert the index of the next
probable move. It should be noted that this dimension reduction
methodology does 'look ahead' in the data. This 'look
ahead' is only done after the order has been
entered in the normal path-dependent process, and only to
insert new indices for evaluation, and so should not
introduce biases.add.rule
, will likely take up most of the
execution time of a strategy backtest.Individual rule functions may need to use <<- to="" place="" hold and
holdtill
variables into play. These
would be most likely implemented by risk rules. When
hold==TRUE
, any open oders will still be processed
(orders are NOT canceled automatically, but no new
orders may be entered. type='risk'
rules will still
function during a hold. Note that hold must be set via a
custom rule. We tend to set hold in an order or risk rule.<->
quantstrat
has a significant amount of logic devoted
to handling path-dependent rule execution. Most of that
code/logic resides in this function.
This function, along with ruleOrderProc
,
addOrder
, and applyStrategy
will likely need to be replaced to connect to a live market
infrastructure.
add.rule
applyStrategy