I have a strategy that signaled a Buy@Market order for symbol 'CLSK' for Friday, 11/8/24. The security was halted all day Friday which the company now says was due to a "clerical error", it had a delayed open today (11/11/24). However, the strategy took a position in it on 11/8/24.
Using a volume filter (such as bars.Volume[idx] > 0) obviously doesn't work b/c the signal bar ('idx') had volume, just not the position entry bar. I even played with different values for Volume % Limit in Preferences > Backtest > Other Settings but that doesn't work either, the order still gets executed.
Q: Is there a simple & reliable way to avoid order execution on a zero-volume day?
Using a volume filter (such as bars.Volume[idx] > 0) obviously doesn't work b/c the signal bar ('idx') had volume, just not the position entry bar. I even played with different values for Volume % Limit in Preferences > Backtest > Other Settings but that doesn't work either, the order still gets executed.
Q: Is there a simple & reliable way to avoid order execution on a zero-volume day?
Rename
What historical provider are you using? I'm looking at the chart for CLSK on QData and there is no bar for 11/8.
Provider: Norgate.
Padding: All market days. If I change it to No padding I get an Execute Exception: Object reference not set to an instance of an object.
Padding: All market days. If I change it to No padding I get an Execute Exception: Object reference not set to an instance of an object.
@Glitch
You may wish to look into why the 'Volume % Limit' setting (in Preferences) didn't work. One would think that any value other than zero in that box would've automatically excluded the trade in this situation but it didn't.
You may wish to look into why the 'Volume % Limit' setting (in Preferences) didn't work. One would think that any value other than zero in that box would've automatically excluded the trade in this situation but it didn't.
It doesn't work for 0 Volume (only), but I don't see a reason for that constraint... whoops, actually I do. It's so that you can trade Forex, for example, without volume and without making a change to that preference.
I'm not seeing any problem with Norgate "No padding". It's the default selection that everyone uses.
When does your Object Ref error occur exactly? Post the stack trace.
I'm not seeing any problem with Norgate "No padding". It's the default selection that everyone uses.
When does your Object Ref error occur exactly? Post the stack trace.
That error no longer appears since I have a new bar of data (11/11/24). Anyway, I don't intend to change the setting for Padding.
------------------
A simple mod to the 0 Volume situation - such that it's ignored for security type Forex but works for all other types (stocks, ETFs, futures, options, etc.) - would make it work across all security types.
------------------
A simple mod to the 0 Volume situation - such that it's ignored for security type Forex but works for all other types (stocks, ETFs, futures, options, etc.) - would make it work across all security types.
It's up to Glitch if he intends to change the design. There may be more fallout than the one I just thought of in passing.
@Glitch
The simple solution I suggested above will make backtesting more robust.
The simple solution I suggested above will make backtesting more robust.
I tried the following code as a way to set position size to zero:
While the Posn Qty does get set to 0 in Backtest Results > Positions...
- Trade Signals still get generated and they display the full position size
- There's no change in the results - it's as if the full position was taken.
How do I fix this code? I want to get rid of the bogus position entirely so the strategy's signal is available for the next bar & backtest results are not falsified?
CODE:
//Set Trade Qty to zero on zero-volume bars public override void BacktestComplete() { foreach (Position p in Backtester.Positions) { DateTime dt = p.EntryDate; int idxx = CurrentBars.IndexOf(dt); if (CurrentBars.Volume[idxx] == 0) p.Quantity = 0; } }
While the Posn Qty does get set to 0 in Backtest Results > Positions...
- Trade Signals still get generated and they display the full position size
- There's no change in the results - it's as if the full position was taken.
How do I fix this code? I want to get rid of the bogus position entirely so the strategy's signal is available for the next bar & backtest results are not falsified?
You could look ahead one bar before issuing PlaceTrade, and if Volume is zero on that bar, avoid the PlaceTrade call.
Avoid the look ahead on the last bar of data since there is no idx +1 at that point.
Avoid the look ahead on the last bar of data since there is no idx +1 at that point.
I'd considered, and dropped, that idea as its really the last bar that matters as one acts on signals generated in the Strategy Monitor (on the last bar).
-------------------------
Taking a very broad perspective... Apart from the occasional stock halt, a far more common cause of zero-volume bars is inactivity... some stocks and ETFs are just not that active and even if they're open for trading there may be none. And of course the great majority of Options don't have any volume.
With that in mind the backtester really shouldn't be executing a trade on a zero-volume bar for most security types (Forex excepted) as its purpose is to mimic real life (as much as possible).
A better solution would be for the Volume % Limit box to have a sub-box such as "Disallow trades on zero-volume bars" (or its opposite "Ignore zero-volume bars") which are self-explanatory. IF this is implemented one should simultaneously be allowed to override the chosen setting via code inside a strategy; this way one can have a default setting yet be able to override it as needed - just as one can do currently for many settings in Preferences.
Problem solved, everyone happy.
-------------------------
Taking a very broad perspective... Apart from the occasional stock halt, a far more common cause of zero-volume bars is inactivity... some stocks and ETFs are just not that active and even if they're open for trading there may be none. And of course the great majority of Options don't have any volume.
With that in mind the backtester really shouldn't be executing a trade on a zero-volume bar for most security types (Forex excepted) as its purpose is to mimic real life (as much as possible).
A better solution would be for the Volume % Limit box to have a sub-box such as "Disallow trades on zero-volume bars" (or its opposite "Ignore zero-volume bars") which are self-explanatory. IF this is implemented one should simultaneously be allowed to override the chosen setting via code inside a strategy; this way one can have a default setting yet be able to override it as needed - just as one can do currently for many settings in Preferences.
Problem solved, everyone happy.
I'm not sure why you discarded the idea.
On the last bar of data we don't know what the volume of the following bar will be, because it will happen in the future.
So the Strategy Monitor will issue a signal regardless.
On the last bar of data we don't know what the volume of the following bar will be, because it will happen in the future.
So the Strategy Monitor will issue a signal regardless.
You're right, my bad (I was distracted by something at the time).
It's still a lot of effort to put it in each strategy - current and future.
A simpler & effortless implementation may be done via the suggestion above. Everyone will be able to use it w/o ever having read this thread.
It's still a lot of effort to put it in each strategy - current and future.
A simpler & effortless implementation may be done via the suggestion above. Everyone will be able to use it w/o ever having read this thread.
QUOTE:
backtester really shouldn't be executing a trade on a zero-volume bar for most security types
I agree because one doesn't know the actual price of a stock not being traded. There are indicators one can use that are weighted by volume. And doing so is a good idea.
I trade WL signals from the Quotes window. I suppose you could add a Volume column to the Quotes window. I'm just wondering if I would consult such a column if it had one?
Perhaps it would be better to add a user-defined column to the Quotes window, then I would select some kind of volume dependent indicator (e.g. Money Flow) to fill it with.
It seems like an awful lot of effort to cover something that rarely if ever comes up. Didn't Norgate already correct that bar anyway?
It was halted the entire day. It happens to dozens of companies every day.
https://www.nasdaqtrader.com/trader.aspx?id=tradehalts#
https://www.nasdaqtrader.com/trader.aspx?id=tradehalts#
But the issue is data providers leaving zero volume bars for those days.
I don't see a zero-volume bar for CLSK on Q-Data. Apparently Norgate also corrected it.
So, it seems like an awful lot of effort to handle cases that the data provider will ultimately correct.
I don't see a zero-volume bar for CLSK on Q-Data. Apparently Norgate also corrected it.
So, it seems like an awful lot of effort to handle cases that the data provider will ultimately correct.
If you leave the Norgate option for "Padding: All market days" selected, then it will be there. (Yes, this is the "issue".)
OK, the simplest solution is to turn off that option for Norgate. Problem solved.
It looks like "No Padding" is also the default.
It looks like "No Padding" is also the default.
"No Padding" is *not* the best option as it can throw indicators (esp. custom ones) out of sync causing "Object reference..." error, see Post #2. Also, plots of external symbols will not plot for the duration of the base symbol's halted days and indicators calculated on those external symbol's bar plot (e.g. a moving average) may get out of whack with their true value, esp if the halt is of a long duration.
------------------------
I believe the best solution is to insert your look-ahead-one-bar into the Volume % Limit logic and fix the deficiency. It's only a few lines of code and a one-time small effort for you - but it'll save everyone a ton of time having to fix each strategy individually.
------------------------
I believe the best solution is to insert your look-ahead-one-bar into the Volume % Limit logic and fix the deficiency. It's only a few lines of code and a one-time small effort for you - but it'll save everyone a ton of time having to fix each strategy individually.
I ran a simple test on a Q-Data dataset containing non-leveraged ETF symbols.
Test code:
Results:
Found a large number of symbols with zero-volume bars over the 10-year lookback period (even though many symbols had a shorter history). Here's a screenshot near the bottom of the debug window:
Anyone can confirm this on their own PC.
Opened a position on a zero-volume bar on an affected symbol (HEAT), the Backtester readily obliged (even though its an impossibility in real life):
------------------------------
Points:
1. Zero-volume bars are more common than people realize.
2. They appear to be most often due to inactivity rather than a trading halt (I did this test on ETFs which are rarely, if ever, halted while the market is open).
3. No data provider is immune from the issue as they're obligated to report the date and volume even if there was no activity.
4. The Backtester should NOT be trading on a bar with zero volume. A *simple* adjustment to the 'Volume % Limit' in Preferences can fix this.
Hope the developers will address this. Asking users to create a workaround in every coded strategy is impractical + it doesn't fix Building Block strategies.
Test code:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript2 { public class MyStrategy : UserStrategyBase { public override void Initialize(BarHistory bars) { for (int bar = 0; bar < bars.Count; bar++) { if (bars.Volume[bar] == 0) { //WriteToDebugLog(bars.Symbol + "\t" + bars.DateTimes[bar].ToShortDateString() + "\t" + bars.Volume[bar]);//uncomment to see affected bars counter += 1; } } if (counter > 0) //comment out to see the list of all symbols (including those w/o any zero vol bars) { WriteToDebugLog("Number of zero volume bars:" + "\t" + counter); WriteToDebugLog(""); } } public override void Execute(BarHistory bars, int idx) {} private int counter; } }
Results:
Found a large number of symbols with zero-volume bars over the 10-year lookback period (even though many symbols had a shorter history). Here's a screenshot near the bottom of the debug window:
Anyone can confirm this on their own PC.
Opened a position on a zero-volume bar on an affected symbol (HEAT), the Backtester readily obliged (even though its an impossibility in real life):
------------------------------
Points:
1. Zero-volume bars are more common than people realize.
2. They appear to be most often due to inactivity rather than a trading halt (I did this test on ETFs which are rarely, if ever, halted while the market is open).
3. No data provider is immune from the issue as they're obligated to report the date and volume even if there was no activity.
4. The Backtester should NOT be trading on a bar with zero volume. A *simple* adjustment to the 'Volume % Limit' in Preferences can fix this.
Hope the developers will address this. Asking users to create a workaround in every coded strategy is impractical + it doesn't fix Building Block strategies.
Interesting, yes I think this is something we'll want to address!
Thank you.
I offered a way to fix this in Post #10, it covers every possible scenario - including keeping the current behavior (should someone want to do that). If you want me to rewrite it for better clarity let me know, I'll be happy to oblige.
I offered a way to fix this in Post #10, it covers every possible scenario - including keeping the current behavior (should someone want to do that). If you want me to rewrite it for better clarity let me know, I'll be happy to oblige.
Using B105 in which the zero-volume bars has apparently been fixed.
A few Qs:
1. Seems like it has been hard-coded so there's no possibility of overriding it via code, right?
2. How did you address Closing a position on a zero-volume bar? While dealing with an Opening trade is easy - you just don't take it on a zero-volume bar - Closing a position can be challenging... is it being carried forward to the next bar until it fills, or is it just forgotten so all such unfilled positions will just pile up? Also, they'll block a new position from being opened in single-position strategies.
3. Trades on zero-volume bars are still happening if the Volume % Limit is set at 0.
A few Qs:
1. Seems like it has been hard-coded so there's no possibility of overriding it via code, right?
2. How did you address Closing a position on a zero-volume bar? While dealing with an Opening trade is easy - you just don't take it on a zero-volume bar - Closing a position can be challenging... is it being carried forward to the next bar until it fills, or is it just forgotten so all such unfilled positions will just pile up? Also, they'll block a new position from being opened in single-position strategies.
3. Trades on zero-volume bars are still happening if the Volume % Limit is set at 0.
1a. Disable the volume limit preference.
1b. Stop using zero volume bars.
2. We'll need a feature request for that edge case. For now you can just peek ahead to avoid a trade on a zero volume bar.
3. 0 disables the Volume % preference by design.
1b. Stop using zero volume bars.
2. We'll need a feature request for that edge case. For now you can just peek ahead to avoid a trade on a zero volume bar.
3. 0 disables the Volume % preference by design.
The whole purpose of fixing the Volume % Limit's behavior wrt zero-volume bars was to avoid every user having to write lines of code in every strategy to peek ahead for 0-vol bars (and it still wouldn't fix the building-block strategies).
-----------------------------
How about offering a way to override Volume % Limit setting via code? That way one can have a default setting yet override it, as and when needed.
-----------------------------
How about offering a way to override Volume % Limit setting via code? That way one can have a default setting yet override it, as and when needed.
@Glitch:
Hopefully you'll create a code-based override of Volume % Limit setting. It's a trivial task.
*Signing off*
Hopefully you'll create a code-based override of Volume % Limit setting. It's a trivial task.
*Signing off*
Your Response
Post
Edit Post
Login is required