Is it possible in WL to write a strategy that includes, for example, a calculation that checks whether the SPY is above its 50 day MA? The data set has about 20 symbols, but I don't want to trade any of them if the SPY price is below its 50 day SMA.
Rename
We can do that without breaking a sweat.
See the QuickRef example for GetHistory.
Actually, that example won't quite get you there.. let me expand on it here:
You can also do this in the Building Blocks by dragging the "Indicator Symbol" Qualifier on an "Indicator Compare to Indicator" Condition.
See the QuickRef example for GetHistory.
Actually, that example won't quite get you there.. let me expand on it here:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.ChartWPF; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //plot some market benchmarks along with the symbol being charted public override void Initialize(BarHistory bars) { _spy = GetHistory(bars, "SPY"); PlotBarHistory(_spy, "SPYPane", Color.Silver); _smaSpy = SMA.Series(_spy.Close, 50); PlotIndicator(_smaSpy, default, default, default, "SPYPane"); } public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) { if (_spy.Close[idx] > _smaSpy[idx]) { //code your buy conditions here } } else { //code your sell conditions here } } BarHistory _spy; SMA _smaSpy; } }
You can also do this in the Building Blocks by dragging the "Indicator Symbol" Qualifier on an "Indicator Compare to Indicator" Condition.
it’s also possible in Building Blocks via the External Symbol Qualifier.
That's amazing. Thanks very much.
I am not sure if the code is correct. When I add some simple buy and sell conditions, I get "Object reference not set to an instance of an object" at the code line:
if (_spy.Close[idx] > _smaSpy[idx])
if (_spy.Close[idx] > _smaSpy[idx])
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.ChartWPF; using System.Drawing; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategya : UserStrategyBase { //plot some market benchmarks along with the symbol being charted public override void Initialize(BarHistory bars) { BarHistory _spy = GetHistory(bars, "SPY"); PlotBarHistory(_spy, "SPYPane", Color.Silver); _smaSpy = SMA.Series(_spy.Close, 50); PlotIndicator(_smaSpy, default, default, default, "SPYPane"); //new indicator1 = new EMA(bars.Close, 2); PlotIndicator(indicator1, Color.FromArgb(255, 0, 0, 0)); indicator2 = new EMA(bars.Close, 5); PlotIndicator(indicator2, Color.FromArgb(255, 0, 0, 255)); StartIndex = 5; } public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) { if (_spy.Close[idx] > _smaSpy[idx]) { //code your buy conditions here int index = idx; Position foundPosition0 = FindOpenPosition(0); bool condition0; if (foundPosition0 == null) { condition0 = false; { if (indicator1.CrossesOver(indicator2, index)) { condition0 = true; } } if (condition0) { _transaction = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, 0, "Buy At Market (1)"); } } } } else { //code your sell conditions here _transaction = PlaceTrade(bars, TransactionType.Sell, OrderType.Market, 0, 0, "Sell At Market (1)"); // condition0 = false; // { // if (indicator12.CrossesUnder(indicator22, index)) // { // condition0 = true; // } // } // if (condition0) // { // ClosePosition(foundPosition0, OrderType.Market, 0, "Sell At Market (1)"); // } } } BarHistory _spy; SMA _smaSpy; private IndicatorBase indicator1; private IndicatorBase indicator2; private IndicatorBase indicator12; private IndicatorBase indicator22; private Transaction _transaction; } }
You declare a variable _spy in the private variables section at the bottom, good. But then you declare the same variable again in Initialize. So, by the time Execute comes around, the original _spy is still unassigned and thus null.
You need to change
BarHistory _spy =
in Initialize to simply
_spy =
to use the same variable you declare in the private variables area.
You need to change
BarHistory _spy =
in Initialize to simply
_spy =
to use the same variable you declare in the private variables area.
Sorry, that was my mistake for not running the code after creating it! (Corrected my example above.)
QUOTE:In other words, you declared two independent _spy variables, which is not what you want. You want one declaration that shares this variable between methods (Initialize and Execute).
You declare a variable _spy in the private variables section at the bottom, good. But then you declare the same variable again in Initialize.
Check your C# textbook for scoping rules with declarations for details so you get the big picture. But declare _spy once as a private variable outside the MyStrategy method blocks (such as Initialize), then just use that variable without including a BarHistory datatype declaration in the assignment within Initialize.
This is easy to understand, but only if you study the scoping rules in your C# textbook. The bits and pieces discussed in the forum won't explain why C# is designed this way, but the textbook will.
I just tried your corrected code, but still get the error at line 35:
if (_spy.Close[idx] > _smaSpy[idx]) Object reference not set to an instance of an object.
if (_spy.Close[idx] > _smaSpy[idx]) Object reference not set to an instance of an object.
At least one error in your code is setting StartIndex = 5 when the SMA period is 50.
You problem is line 16. You are declaring a new copy of the _spy variable instead of using the one you declared at the bottom of the strategy.
Change
BarHistory _spy = GetHistory(bars, "SPY");
to
_spy = GetHistory(bars, "SPY");
Change
BarHistory _spy = GetHistory(bars, "SPY");
to
_spy = GetHistory(bars, "SPY");
Thanks Glitch. Works fine now.
Your Response
Post
Edit Post
Login is required