Cases:


flat.to.flat && replace=FALSE

This is the simplest case, as with equity curve resampling, we're just rearranging the vector of durations and quanitities.

To create each replicate vector:

It will probably make sense for all these methods to create a little internal function to do the sampling, and then call replicate() with simplify=FALSE which should return a listof the replicates which we'll then be able to iterate over using foreach().


flat.to.flat and replace=TRUE

This is the next simplest case, the risk is that the cumulative duration of our samples with replacement is longer or shorter than the total duration.

To address this, we'll try to take too many samples and then shorten it to the correct duration.

To create each replicate vector:

we could choose an arbitrarily large fudge factor, e.g. 50% of nrows, or we could do something a little more complicated, taking a saple of nrow(txnsimdf), testing the duration, and taking an additional smaple if needed until the sum(duration) is longer than the duration of

The index for the replicates, in both replace=TRUE, and replace=FALSE, should be the start date plus the cumsum of the duration at each row. This should create a monotonically increasing index of the beginning of each trade or flat period.


round turn trade methods which are not flat.to.flat

For any round turn trade methodology which is not measuring round turns as flat.to.flat, things get more complicated. Fortunately, the complication is the same for txnsim regardless of the methodology used to pair entry and exit trades.

The first major complication with any trade that levels into a position is that sum(txnsimdf$duration) will be longer than the market data. The general pattern of the solution to this complication is that we sample as usual, to the a duration equal to the original sum(txnsimdf$duration), and then overlap any overage onto the first set of samples to get leveled trades.

The next major complication would be on max position. For this first rendition, I think we should focus on the quantstrat-compatible Poslimit slot in the blotter portfolio object. It can be found here:

portf$symbols[[symbol]]$PosLimit

and has columns:

"MaxPos", "LongLevels", "MinPos", "ShortLevels"

The general pattern of the solution to the maxpos problem is that we should check the cumsum of the position implied by the replicate transactions, and reduce or eliminate trades that would violate the max position limits.

if replace=FALSE

If replace=FALSE, we start the same way as for flat.to.flat:

Note that the duration/quantity tuples will have total duration longer than mktdata, as described above. We'll deal with this when generating transactions.

if replace=TRUE

If replace=TRUE, we again start the same way as for flat.to.flat:

In all four scenarios described here, it seems as though we can have the same return from the function that generates replicates. We should return a list of n replicates which contains the duration/quantity tuples


Generating transactions


round turn trade method is flat.to.flat

At this point, replace=TRUE and replace=FALSE are immaterial. The object has a total duration equal to the market data, and all we need to do is create the addTxns object and apply it.


round turn trade methods which are not flat.to.flat


addTxns object:

At this point, we should have an object containing a single index that fits within the mktdata, of the same [start, duration, qty] form as the txnsimdf object.

Generating data for addTxns will proceed in the same manner for all input data at this point.

It is important that this step be done as an xts object, because xts will keep everything ordered correctly.


Applying Transactions:



braverock/blotter documentation built on Sept. 15, 2024, 8:45 p.m.