How to pass a flag to Custom Backtest Procedure at each bar (like signals)?

Say I have the following trading strategy:

Buy = Cross(_rsi_14, 30);
Sell = Cross (70, _rsi_14);

During a multi-symbol backtest, the number of signals greatly varies from bar to bar. For example, the bar #1 might produce 3 Buy signals, the bar #2 8 Buy signals and the bar #3 11 Buy signals. This makes position sizing difficult.

For instance, if I set the maximum position size to -10 and use even position sizes for all signals at the same bar, I will get the following position sizes:
Bar 1 : -10 (3 positions)
Bar 2: -7/8 (8 positions)
Bar 3: all cash used, no new positions opened.
The exposure is high but 11 signals are wasted and the first 3 positions are unproportionally large.

Maximum signal size -2 would make use of all the signals and make the positions equal but the exposure would be lower.

Rebalancing at each bar would be possible but it would involve partial selling before the Sell condition is met, probably inflicting unnecessary losses.

Now the question - is there a way to let the Custom Backtest Procedure know how much Buy signals might be coming in advance? For instance, is it possible to create an array like

X = _rsi_14 < 30;

during the first phase and somehow pass it to the CBT to be looked up without prior knowledge about the list of tickers from the CBT part?

It would be easy with static variables but the CBT would need to know the ticker names to check the static variables. Is it possible to loop through the tickers in a Watchlist in the CBT? There are the InWatchlist() and InWatchlistName() functions but what about the other way round?

Any thoughts?

First, your math is hard to follow at best, or perhaps just incorrect.

Second, what you're proposing is called future peeking, and it's one way to make sure that you get totally unrealistic backtest results. Forget about AmiBroker for a moment; how many entry signals is your favorite trading strategy going to produce next Tuesday? Obviously you can't know the answer to that question, and therefore your backtest shouldn't either.

Third, you can use static variables that are not symbol-specific to pass data from Phase 1 to Phase 2 (CBT). In your example, however, this would seem to be a very poor idea.

Finally, if you just want to know how many signals (entry, exit, or both) have been generated for a particular bar in the CBT, you can use the function bo.GetSignalQty(). I have never had reason to call this for anything but the current bar though.

1 Like

I am not proposing future peeking.

How do you know that a certain asset would gain in price by the next Tuesday? Obviously you cannot and a backtest cannot and must not know it as well to generate meaningful results. However, the whole business of trading is about statistical probability that it could happen.

In my example, there obviously cannot be more assets crossing the rsi=30 line than there are assets below the 30 line at the previous bar. One can build a statistic model predicting that, say, 30% of assets with rsi between 25 and 30 cross 30 during the next 5 bars under certain conditions. I was asking about letting the CBT know how many assets have their RSIs below 30 at any given bar or anything similar.

I was not asking about counting the signals either - I was asking if it was possible to count assets having certain conditions fullfilled analogically to counting signals.

You can just use StaticVarAdd() to determine the number of symbols that meet some condition on each bar, and then you can apply your statistical analysis within the CBT. For example:

// Phase 1
pctHitRate = 30;
StaticVarAdd("countLowRSI", _rsi_14 < 30);

// CBT
countLowRSI = StaticVarGet("countLowRSI");
estimatedFutureSignals = countLowRSI * pctHitRate / 100;

Thank you, works well!

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.