CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using System.IO; using System.Collections.Generic; namespace WealthScript4 { public class MyStrategy : UserStrategyBase { public MyStrategy() : base() { StartIndex = 0; } public override void Initialize(BarHistory bars) { } public override void Execute(BarHistory bars, int idx) { if (idx == bars.Count - 1) WriteToDebugLog ($" {logList.Count}"); } public override void PreExecute(DateTime dt, List<BarHistory> participants) { var logFile = File.ReadAllLines(@"C:\Users\ww5\Desktop\Test.txt"); logList = new List<string>(logFile); } private List<string> logList = new List<string>{ }; } }
QUOTE:And the rest is also 0. How is it possible if PreExecute is executed once before each loop and all the symbols should receive the same value of Loglist.Count?
---Symbol by Symbol Debug Logs---
---DLTR---
1249
---GFS---
1249
---ADP---
0
---HON---
0
---VRTX---
0
---MU---
0
Rename
PreExecute will execute within the context of one of the symbols in the participants list. For all of the other symbols your list will not get loaded from the file and so will have zero items. This isn’t a bug, just a misunderstanding so allow me to rename the topic.
Anyway, the file isn't changed throughout the whole execution loop. So the only guess is that PreExecute is not triggered on the first symbol. Then what is the correct function to run my code before the Execute loop?
PreExecute is called on each unique DateTime of processing.
Each time it is called, it is called within the context of ONE of the participants.
Each time is called, that one participant might be different than the previous one depending on which symbols happen to be in the participants list for that DateTime.
I'm not sure what you're trying to accomplish exactly, but if can describe it I can help.
Each time it is called, it is called within the context of ONE of the participants.
Each time is called, that one participant might be different than the previous one depending on which symbols happen to be in the participants list for that DateTime.
I'm not sure what you're trying to accomplish exactly, but if can describe it I can help.
QUOTE:
PreExecute is called on each unique DateTime of processing.
I need exactly this, execute a certain code before each iteration. Simply said, in this file I specify which symbols can be traded at the moment.
If I'm reading the original example code correctly, Test.txt is moving target that's constantly changing with each new bar. I would instead lock Test.txt down so it doesn't change during the entire backtest. In that case, you can implement it like this so the file is only read once:
NOTE: I would leave logList as a string[] rather than changing it to a List<string>. The only advantage of using a List collection is because you don't know the length, but a string[] would be faster and contiguous in heap memory.
I'm assuming PreExecute is called to compile a temporary List of symbols for trading on that specific bar. And that's a reasonable use case.
CODE:If there are some kind of symbol dependencies within Test.txt, I would keep those dependencies constant throughout the entire backtest, although one symbol might have different dependencies than the next in the Test.txt file.
public class MyStrategy : UserStrategyBase { static readonly List<string> logList; public MyStrategy() { if (logList.IsNull()) { string[] logFile = File.ReadAllLines(@"C:\Users\ww5\Desktop\Test.txt"); logList = new List<string>(logFile); } } }
NOTE: I would leave logList as a string[] rather than changing it to a List<string>. The only advantage of using a List collection is because you don't know the length, but a string[] would be faster and contiguous in heap memory.
I'm assuming PreExecute is called to compile a temporary List of symbols for trading on that specific bar. And that's a reasonable use case.
You probably want to make the list static, that way it can be shared amongst all the instances of your Strategy class.
Thank you for answers. This solves the problem.
There is still one last question, static divides the variable between all symbols, but how to make that the variable would be stored but only within one symbol?
There is still one last question, static divides the variable between all symbols, but how to make that the variable would be stored but only within one symbol?
A static is stored at the class level, not at any particular instance level.
QUOTE:Yes it does, but it shares among all symbols in strategy monitor. What if I want to store in each symbol separately?
A static is stored at the class level, not at any particular instance level.
QUOTE:
What if I want to store in each symbol separately?
Now we are back to the PreExecute example https://www.wealth-lab.com/Support/ApiReference/UserStrategyBase#PreExecute Below is a part of that PreExecute example.
CODE:So you are storing whatever in the bars.Cache["Log"] for each individual BarHistory case. Where are we going with all this complexity? Is it necessary to have separate copies?
public override void Initialize(BarHistory bars) { rsi = new RSI(bars.Close, 14); bars.Cache["RSI"] = rsi; }
QUOTE:
Below is a part of that PreExecute example.
That's first I've tried
CODE:But this variable is also not saved between Strategy Monitor runs
public override void Initialize(BarHistory bars) { bars.Cache["test"] = 1; } public override void Execute(BarHistory bars, int idx) { bars.Cache["test"] = Convert.ToInt32(bars.Cache["test"]) + 1; }
QUOTE:
Where are we going with all this complexity?
I totally agree. The markets are already too complicated to make it even more complicated. But, for example, I need to store the stop loss level in the strategy, how do you think it should be done? Yes, for the initial question with storing tradeable symbols static variable works, but if I need to store stop loss on each character separately? The only thing I can think of is static dictionary.
Even static objects/variables won't work. For persistent storage between different backtest runs, you'll need to resort to using Global variables or a file store. File.IO is a good way to go because you'll have a record to look back on.
I don't like the boxing and unboxing code in Post #11. Let's do it in a straightforward fashion.
Agreed. I suppose you could declare a Dictionary<BarHistory,double> in Global storage to store your stop loss values for each symbol there. But this solution is overdone.
How are you "computing" the stop loss values in the first place? Rather than storing these values, I would re-compute them from the original time series you computed them from in the first place.
CODE:
public override void Initialize(BarHistory bars) { bars.Cache["test"] = 1.0D; //force it to double (or something you know), then box it } public override void Execute(BarHistory bars, int idx) { double x = (double)bars.Cache["test"]; //unbox it back to double }
QUOTE:
For persistent storage between different backtest runs, you'll need to resort to using Global variables or a file store.
Agreed. I suppose you could declare a Dictionary<BarHistory,double> in Global storage to store your stop loss values for each symbol there. But this solution is overdone.
How are you "computing" the stop loss values in the first place? Rather than storing these values, I would re-compute them from the original time series you computed them from in the first place.
CODE:Also, the ideal stop loss value will vary from one day to the next as a function of whether the market is bullish or bearish for that particular day (which makes storing such "dated" stop values pointless).
public override void Initialize(BarHistory bars) { Median stopPrice = Median.Series(bars.Low, 3); PlotIndicator(stopPrice); }
QUOTE:
Let's do it in a straightforward fashion
Anyway it is not saved between restarts, so I use a static Dictionary, which is saved.
QUOTE:
How are you "computing" the stop loss values in the first place? Rather than storing these values, I would re-compute them from the original time series you computed them from in the first place.
I use automatically calculated values in most strategies, so I have not encountered such problems before. And this is the only way to be sure that the stop will be correctly calculated and executed. But now I tried to combine manual and automated trading, i.e. I give a list of tickers and their stop losses and then the strategy itself buys and executes the trade. That's why there is a problem of how to store stop loss. So I will store it in a file.
QUOTE:
I use automatically calculated values in most strategies,... And this is the only way to be sure that the stop will be correctly calculated and executed.
But certainly you must calculate the stop loss prices from the historical candle bar data. And that data is available to you, so you can recalculate them as needed. There's no need to store stop loss prices, which would get stale.
Most traders use the most recent Close and the ATR to compute the best stop loss price. And WL does support a chandelier stop loss exit that's based on that very effective approach. Check it out.
CODE:https://corporatefinanceinstitute.com/resources/equities/chandelier-exit/
CloseAtTrailingStop(LastPosition, TrailingStopType.ATR, 2.5);
You can add the following code so Stop and Limit levels are plotted on the Price pane.
CODE:We need to move this discussion to a new topic to go further since we are no longer discussing PreExecute.
public MyStrategy() { PlotStopsAndLimits(); }
Your Response
Post
Edit Post
Login is required