- ago
We're building a multi-timeframe strategy in C#. The primary chart is intraday (5-min), and we want a secondary pane showing a higher-timeframe view of the same symbol (15-min, 60-min, daily, etc.). The HTF pane is purely visual - the strategy logic used the compressed HTF series internally for a directional filter.

We compressed the primary via BarHistoryCompressor and plotted the result with PlotBarHistory on a named secondary pane. The data itself checked out: the compressed BarHistory had the correct start date, end date, and bar count, with evenly spaced DateTimes spanning the full primary range.

The issue was that the HTF pane visually truncated at a fixed calendar date well before the primary’s end, even though the underlying BarHistory still contained bars through the full range. Older dates rendered correctly, but everything after a certain date was blank. Coarser HTF compressions cut off sooner than finer ones. The HTF pane’s price scale also differed from the primary’s at the same dates (same symbol, but different visible price ranges) which suggested the plotted HTF candles were not aligned to the primary chart’s timeline.

PlotBarHistoryStyle, GetHistoryUnsynched, and WLHost.Instance.GetHistory all exhibited the same or worse behavior.

What's the right way to plot an HTF candle pane (of the same primary symbol) that spans the full primary date range and aligns with the primary's timeline? Is there an idiom I'm missing, or a known limitation?

Thank you for your help.
0
545
2 Replies

Reply

Bookmark

Sort
Cone8
- ago
#1
Plot Series type methods expect the target to be synchronized with the primary chart. After compressing, you should use BarHistorySynchronizer to synchronize it for plotting. In that case, however, you'll get a bunch of duplicate bars, which isn't too pleasing.

There are a lot of ways to do this - including drawing your bars with vertical and horzontal lines, but here's one I had saved from some time ago. It could be what you're looking for.

CODE:
using WealthLab.Backtest; using WealthLab.Core; using System.Drawing; namespace WealthScript3 {    public class MyStrategy123 : UserStrategyBase    {       public override void Initialize(BarHistory bars)       {          BarHistory hourly = BarHistoryCompressor.ToMinute(bars, 60);                   PlotScaledBars(hourly, bars);                    // use the sync'd reference in the script          _hourlySync = BarHistorySynchronizer.Synchronize(hourly, bars);                   }       public override void Execute(BarHistory bars, int idx)       {          double lasthourHigh = _hourlySync.High[idx];       }              // synchronizes the scaled bars for plotting       public void PlotScaledBars(BarHistory scaledBH, BarHistory master)       {          //make a new Bar History just for plotting          BarHistory plotter = new BarHistory(scaledBH);          int n = 0;          for (int k = 0; k < scaledBH.Count; k++)          {                         int syncbar = master.IndexOf(scaledBH.DateTimes[k]);             //WriteToDebugLog(n + ", " + syncbar);                          while (n < syncbar)             {                plotter.Add(master.DateTimes[n], double.NaN, double.NaN, double.NaN, double.NaN, double.NaN);                n++;             }                          plotter.Add(scaledBH.DateTimes[k], scaledBH.Open[k], scaledBH.High[k], scaledBH.Low[k], scaledBH.Close[k], scaledBH.Volume[k]);             n++;             }                    PlotBarHistory(plotter, "Comp");          DrawHeaderText($"{scaledBH.Scale} bars", WLColor.Fuchsia, 14, "Comp");       }              BarHistory _hourlySync;    } }
2
- ago
#2
Thank you - we'll give it a try. Thanks again, Cone!
0

Reply

Bookmark

Sort