- ago
Can you please help with converting following script from WL6 to WL7?

CODE:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; public class MyChart : WealthScript {    //===========================================================================================================    // RS Line    // indexUpFactor - typically 1.02 to 1.2    // rsDownFactor - typically 0.60 to 0.85    //-----------------------------------------------------------------------------------------------------------    protected void drawIndexAndRsLines(double indexUpFactor, double rsDownFactor)    {       // Index Line       //Bars SPX = GetExternalSymbol(".SPX", true);       Bars SPX = GetExternalSymbol("^GSPC", true);       double highRefPrice = Highest.Series(High, 200)[Bars.Count - 1];       DataSeries SPXNormalized = highRefPrice * indexUpFactor * SPX.Close / SPX.Close[Bars.Count - 1];       PlotSeries(PricePane, SPXNormalized, Color.Black, LineStyle.Solid, 1);       // RS Line       DataSeries RS = Bars.Close / SPX.Close;       DataSeries RS2 = Close[Bars.Count - 1] * rsDownFactor * RS / RS[Bars.Count - 1];       PlotSeries (CreatePane( 30, true, true ), RS, Color.Blue, LineStyle.Solid, 1 );       //PlotSeries(PricePane, RS2, Color.Blue, LineStyle.Solid, 1);    }    //===========================================================================================================    // 5 weeks of Quiet Accumulation    //-----------------------------------------------------------------------------------------------------------    protected void show5WeeksOfQuietAccumulation()    {       DataSeries pctChange = Close * 2;       for (int bar = 1; bar < Bars.Count; bar++)       {          pctChange[bar] = 100 * (Close[bar] - Close[bar - 1]) / Close[bar - 1];       }       for (int bar = 5; bar < Bars.Count; bar++)       {          if (pctChange[bar] > 0 && pctChange[bar] < 3             && pctChange[bar - 1] > 0 && pctChange[bar - 1] < 3             && pctChange[bar - 2] > 0 && pctChange[bar - 2] < 3             && pctChange[bar - 3] > 0 && pctChange[bar - 3] < 3             && pctChange[bar - 4] > 0 && pctChange[bar - 4] < 3)          {             AnnotateBar("|", bar, false, Color.Black);             AnnotateBar("|", bar, false, Color.Black);             AnnotateBar("|", bar, false, Color.Black);             AnnotateBar("5wQA", bar, false, Color.Black, Color.Yellow);          }       }    }    //===========================================================================================================    // Show 52 weeks high    //-----------------------------------------------------------------------------------------------------------    protected void show52WeeksHigh(int numBarsIn52Weeks)    {       // 52-week high       for (int bar = numBarsIn52Weeks; bar < Bars.Count; bar++)       {          if (High[bar] > Highest.Series(High, numBarsIn52Weeks)[bar - 1])          {             // New 52-week high detected. Paint the chart blue             SetBackgroundColor(bar, Color.FromArgb(15, Color.Blue));          }       }    }    //===========================================================================================================    // Daily Chart    //-----------------------------------------------------------------------------------------------------------    protected void dailyChart()    {       // Have some space in the right       PadBars(5);       // Simple Moving Averages       PlotSeries(PricePane, SMA.Series(Close, 10), Color.Green, LineStyle.Solid, 1);       PlotSeries(PricePane, SMA.Series(Close, 50), Color.Red, LineStyle.Solid, 1);       PlotSeries(PricePane, SMA.Series(Close, 200), Color.Black, LineStyle.Solid, 1);       PricePane.LogScale = false;       VolumePane.LogScale = true;       // S&P500 and RS Line       drawIndexAndRsLines(1.02, 0.85);       show52WeeksHigh(251);    }    //===========================================================================================================    // Weekly Chart    //-----------------------------------------------------------------------------------------------------------    protected void weeklyChart()    {       // Have some space in the right       PadBars(5);       // Simple Moving Averages       PlotSeries(PricePane, SMA.Series(Close, 10), Color.Red, LineStyle.Solid, 1);       PlotSeries(PricePane, SMA.Series(Close, 40), Color.Black, LineStyle.Solid, 1);       PricePane.LogScale = true;       VolumePane.LogScale = true;       drawIndexAndRsLines(1.02, 0.60);       show5WeeksOfQuietAccumulation();    }    //===========================================================================================================    // Monthly Chart    //-----------------------------------------------------------------------------------------------------------    protected void monthlyChart()    {       // Simple Moving Averages       PlotSeries(PricePane, SMA.Series(Close, 12), Color.Red, LineStyle.Solid, 1);       PlotSeries(PricePane, SMA.Series(Close, 60), Color.Black, LineStyle.Solid, 1);       PricePane.LogScale = true;       VolumePane.LogScale = true;    }    //===========================================================================================================    // Execute method.    // The control flow starts here.    //-----------------------------------------------------------------------------------------------------------    protected override void Execute()    {       if (Bars.Scale == BarScale.Daily)       {          dailyChart();       }       if (Bars.Scale == BarScale.Weekly)       {          weeklyChart();       }       if (Bars.Scale == BarScale.Monthly)       {          monthlyChart();       }    } }


0
763
Solved
6 Replies

Reply

Bookmark

Sort
- ago
#1
Hope this helps a bit:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript3 { public class MyStrategy : UserStrategyBase {       int extendedBars = 5;        //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) {          if (bars.Scale == HistoryScale.Daily)          {             dailyChart(bars);          }          if (bars.Scale == HistoryScale.Weekly)          {             weeklyChart(bars);          }          if (bars.Scale == HistoryScale.Monthly)          {             monthlyChart(bars);          } } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) { //code your buy conditions here } else { //code your sell conditions here } }       //===========================================================================================================       // RS Line       // indexUpFactor - typically 1.02 to 1.2       // rsDownFactor - typically 0.60 to 0.85       //-----------------------------------------------------------------------------------------------------------       protected void drawIndexAndRsLines(BarHistory bars, double indexUpFactor, double rsDownFactor)       {          StartIndex = 200;                    // Index Line          BarHistory SPX = GetHistory(bars, "^GSPC");          double highRefPrice = Highest.Value(bars.Count - 1 - extendedBars, bars.High, 200);          TimeSeries SPXNormalized = highRefPrice * indexUpFactor * SPX.Close / SPX.Close[bars.Count - 1];          PlotTimeSeries(SPXNormalized, "SPXNormalized", "Price", Color.Black);          // RS Line          TimeSeries RS = bars.Close / SPX.Close;          TimeSeries RS2 = bars.Close[bars.Count - 1] * rsDownFactor * RS / RS[bars.Count - 1];          PlotTimeSeries(RS, "RS", "RS", Color.Blue);          //PlotSeries(PricePane, RS2, Color.Blue, LineStyle.Solid, 1);       }       //===========================================================================================================       // 5 weeks of Quiet Accumulation       //-----------------------------------------------------------------------------------------------------------       protected void show5WeeksOfQuietAccumulation(BarHistory bars)       {          TimeSeries pctChange = ROC.Series(bars.Close, 1);                    for (int bar = 5; bar < bars.Count; bar++)          {             if (pctChange[bar] > 0 && pctChange[bar] < 3              && pctChange[bar - 1] > 0 && pctChange[bar - 1] < 3              && pctChange[bar - 2] > 0 && pctChange[bar - 2] < 3              && pctChange[bar - 3] > 0 && pctChange[bar - 3] < 3              && pctChange[bar - 4] > 0 && pctChange[bar - 4] < 3)             {                for (int i = 0; i <= 3; i++)                   DrawBarAnnotation("|", bar, false, Color.Black, 12);                DrawBarAnnotation("5wQA", bar, false, Color.Black, 12);             }          }       }       //===========================================================================================================       // Show 52 weeks high       //-----------------------------------------------------------------------------------------------------------       protected void show52WeeksHigh(BarHistory bars, int numBarsIn52Weeks)       {          // 52-week high          for (int bar = numBarsIn52Weeks; bar < bars.Count; bar++)          {             if (bars.High[bar] > Highest.Series(bars.High, numBarsIn52Weeks)[bar - 1])             {                // New 52-week high detected. Paint the chart blue                SetBackgroundColor(bars, bar, Color.FromArgb(15, Color.Blue));             }          }       }       //===========================================================================================================       // Daily Chart       //-----------------------------------------------------------------------------------------------------------       protected void dailyChart(BarHistory bars)       {          // Have some space in the right          bars.ExtendedBars = 5;          // Simple Moving Averages          PlotTimeSeries(SMA.Series(bars.Close, 10), "SMA10", "Price", Color.Green);          PlotTimeSeries(SMA.Series(bars.Close, 50), "SMA50", "Price", Color.Red);          PlotTimeSeries(SMA.Series(bars.Close, 200), "SMA200", "Price", Color.Black);          // S&P500 and RS Line          drawIndexAndRsLines(bars, 1.02, 0.85);          show52WeeksHigh(bars, 251);       }       //===========================================================================================================       // Weekly Chart       //-----------------------------------------------------------------------------------------------------------       protected void weeklyChart(BarHistory bars)       {          // Have some space in the right          bars.ExtendedBars = 5;          // Simple Moving Averages          PlotTimeSeries(SMA.Series(bars.Close, 10), "SMA10", "Price", Color.Red);          PlotTimeSeries(SMA.Series(bars.Close, 40), "SMA40", "Price", Color.Black);          // S&P500 and RS Line          drawIndexAndRsLines(bars, 1.02, 0.60);          show5WeeksOfQuietAccumulation(bars);       }       //===========================================================================================================       // Monthly Chart       //-----------------------------------------------------------------------------------------------------------       protected void monthlyChart(BarHistory bars)       {          // Simple Moving Averages          PlotTimeSeries(SMA.Series(bars.Close, 12), "SMA12", "Price", Color.Red);          PlotTimeSeries(SMA.Series(bars.Close, 60), "SMA60", "Price", Color.Black);       } } }
0
Best Answer
- ago
#2
@ Eugene, Thanks a lot for the above script!

Few questions:
1. I like different moving averages to be of different thickness to emphasize their importance and visual impact. How do I control thickness of different time series plots? I don't see any option in PlotTimeSeries().

2. What about configuring log scale for price and volume panes programmatically based on the timeframe?

3. DrawBarAnnotation is not stacking up like WL6. When you add annotation to the same bar, it is overwriting instead of stacking on the earlier one. So there is no way currently to add two or more annotations to the same bar. I use this feature a lot.

4. I saved it as "New Strategy - C# Coded". Then I click on "Compile" and "Run Backtest". Then it shows the "Chart". But in the timeframe selection is disabled and it is stuck at "Daily". It looks like I can't change timeframe from the Chart tab. It looks like I have to go to Strategy Settings to change the timeframe. Is there a way to change the timeframe from the Chart tab?



0
- ago
#3
1. PlotTimeSeries has parameter plotStyle which accepts PlotStyles.ThickLine. If you want finer control, PlotTimeSeriesLine accepts optional parameter lineWidth.

2. Dion will correct me if I'm wrong but this doesn't seem to be supported in strategy code.

3. You can concatenate the multiple strings (including line breaks) and add them once in a DrawBarAnnotation call.

4. Not sure if it's intentional behavior, will ask. As a workaround, you can change timeframe if you open a new chart and drop a saved strategy onto it.
0
- ago
#4
Thanks Eugene!

1. I assume you were referring to PlotTimeSeriesLine. PlotTimeSeriesLine solves the problem for me.

2. Can we add it to the feature request?

3. Using multiple strings with line break works fine. But the restriction is that all of them need to be of same color. Also, DrawBarAnnotation does not have option to set background color. Can we have both "stacking" and "background color" as WL6 feature parity request?
With the current restriction, you have to collect all the annotation strings for each bar and then play them at the end. I wrote a little handy code for that.
CODE:
      private Dictionary<int, string> _annotationsAboveMap = new Dictionary<int, string>();       private Dictionary<int, string> _annotationsBelowMap = new Dictionary<int, string>();       protected void DrawBarAnnotation2(string text, int idx, bool aboveBar)       {          if (aboveBar)          {             if (_annotationsAboveMap.ContainsKey(idx))                _annotationsAboveMap[idx] = _annotationsAboveMap[idx] + "\n" + text;             else                _annotationsAboveMap[idx] = text;          }          else          {             if (_annotationsBelowMap.ContainsKey(idx))                _annotationsBelowMap[idx] = _annotationsBelowMap[idx] + "\n" + text;             else                _annotationsBelowMap[idx] = text;          }       }       protected void DrawAllAnnotationsAtEnd(Color color, int fontSize)       {          foreach (KeyValuePair<int, string> entry in _annotationsAboveMap)          {             DrawBarAnnotation(entry.Value, entry.Key, true, Color.Black, fontSize);          }          foreach (KeyValuePair<int, string> entry in _annotationsBelowMap)          {             DrawBarAnnotation(entry.Value, entry.Key, false, Color.Black, fontSize);          }       }


4. Dropping a strategy on a chart is a very cool feature!

1
- ago
#5
It looks like I posted duplicate texts in the above reply. Could not find a way to edit the post after submit. It will be good to allow editing of the post for 15-30 min after the initial posting to fix these kind of errors.
0
- ago
#6
QUOTE:
It will be good to allow editing of the post for 15-30 min after the initial posting to fix these kind of errors.

Absolutely. I believe we should allow editing own posts for N hours after posting. Reported the issue.
0

Reply

Bookmark

Sort