ww58
- ago
I am using the following code
CODE:
DataSet sharesDataset = DataSetFactory.Instance.Find("Dataset Today"); sharesDataset.Symbols = tickers;

The symbols are successfully updated in the program, but they are not saved in the xml file, so after a restart the previous ones are loaded again. How to save them?
0
401
Solved
20 Replies

Reply

Bookmark

Sort
- ago
#1
No, serializing DataSet composition to XML is not supported.
0
ww58
- ago
#2
So the only way is to manually update the file?

And if we go the other way around, can I somehow before the session starts each day, using the code above, choose which instruments will be traded on?
0
- ago
#3
You can "choose instruments to trade" without modifying the XML file. What's the purpose of updating the file?

EDIT: I couldn't have expressed my confusion any better than @Cone's reply below:
0
Cone8
 ( 24.61% )
- ago
#4
I must be missing something because I really don't understand the need to changes a DataSet for this purpose. Presumably, you're filtering a larger set of symbols for the candidates to trade "today".

Why don't you create your filter, saved those symbols to a List, and just ignore any symbol that isn't in the list "today"?
0
ww58
- ago
#5
>What's the purpose of updating the file?
Updating the file to make sure that after restarting the program the data will be saved.

>Presumably, you're filtering a larger set of symbols for the candidates to trade "today".
That's the exact reason. I do daily analysis on the whole market on the one strategy, and trading intraday on another. It is unnecessary and redundantly for me to get intraday quotes for the whole market when only 40 instruments are selected.

>Why don't you create your filter, saved those symbols to a List, and just ignore any symbol that isn't in the list "today"?
The quotes will still be downloaded, right?
1
- ago
#6
Understood, it's a reasonable concern. The correct and supported way to get there may be to build a DataSetProvider: https://www.wealth-lab.com/Support/ExtensionApi/DataSetProvider

These DataSets can be loaded and refreshed on the fly while WL is running. And the logic to select your 40 instruments could perhaps be transfered to the DataSetProvider's code so it frees you up from running the strategy?
1
Cone8
 ( 24.61% )
- ago
#7
For Daily analysis, use WealthLab's Screener.
Scan the enter market in seconds and then create your DataSet.

Note! The Screener only uses the most recent 250 bars of data, so these are 52-week highs, not all-time highs in many cases.

0
ww58
- ago
#8
>These DataSets can be loaded and refreshed on the fly while WL is running
Finally reached the realization of this functionality. I have the following code:

CODE:
using System; using System.IO; using WealthLab.Core; using WealthLab.Data; namespace DynamicDatasets { public class DynamicDatasets : DataSetProviderBase {        List<DataSet> dataSets = new List<DataSet>(); public override List<DataSet> DataSets { get { DataSet dataSet = new DataSet(); dataSet.Name = "Test"; dataSet.PreferredDataProviderName = Name; dataSet.ReadOnlySymbols = false; dataSet.IsUserCreated = false; dataSet.Symbols = File.ReadAllLines(WLHost.Instance.DataFolder +"/test.txt").ToList(); dataSets.Add(dataSet); return dataSets; } }        public override void SymbolsModified(DataSet ds, List<string> symbols){ DataSet existingDataSet = dataSets.FirstOrDefault(d => d.Name == ds.Name)!; if (existingDataSet != null) { existingDataSet.Symbols = symbols; File.WriteAllLines(WLHost.Instance.DataFolder +"/test.txt", symbols); } } } }
I am accessing this dataset from a strategy
CODE:
         DataSet sharesDataset = DataSetFactory.Instance.Find("Test");          sharesDataset.Symbols = new List<string>() { "ABNB", "TSLA" };
and it seems to be working. It modifies the symbols of this dataset, but doesn't call SymbolsModified, so file remains unchanged. What am I doing wrong?
0
Glitch8
 ( 10.13% )
- ago
#9
Any Strategy that you run on the remote Screener is running on the Screener SERVICE computer, not your local computer. So that Strategy has no way to access your local files or do anything with your local DataSets.
0
ww58
- ago
#10
>So that Strategy has no way to access your local files or do anything with your local DataSets.
I am not using a screener, I am using a regular strategy in monitor on daily bars. The goal is simply to change the dataset from it
0
Glitch8
 ( 10.13% )
- ago
#11
I see, you’re creating a DataSet Provider. SymbolsModified is only called when the symbols are changed by the user in the WL7 UI.

You can add a new method to your DataSet class, something like SaveFile, and then call that method from your Strategy?

You’d need to create your own DataSet derived class, add the method, be sure to use your class when creating the DataSet in the DSP, and then cast the returned DataSet to your custom class type in the Strategy code Find call.
1
ww58
- ago
#12
>SymbolsModified is only called when the symbols are changed by the user in the WL7 UI.
if I understand correctly method isn't called in WL8.

Anyway, I don't see how the task can be resolved using DataSet Provider API at all. Maybe I messed something up, but in the end I can change the dataset file from the strategy call to my class, but in the program itself, in the interface, the old one remains. The one that was loaded when the program was started.

Even if I try to use usual datasets and such code and suppress Exception by using "try catch"
CODE:
DataSetFactory.Instance.UpdateSymbols(DataSetFactory.Instance.Find("Test"), new List<string>() { "TSLA", "AAPL" });
it modifies the xml dataset file but strategy backtester uses the old dataset untill I click on it.

Any chance for full-fledged dataset editing feature?
0
Glitch8
 ( 10.13% )
- ago
#13
To be honest I don't understand the requirement. Can you spell it out in simple plain English what you're trying to accomplish?
0
ww58
- ago
#14
I wrote about it in Post #5.

I have a two-part strategy. The first one using daily bars selects stocks, which will be traded the next day on an intraday basis. So that the second strategy would not receive 5min quotes for the whole market the first strategy should change the dataset and leave only the selected ones for this day.
0
Glitch8
 ( 10.13% )
- ago
#15
The first (daily) Strategy could just save a file with the symbols.

The next day, after a WL8 restart, your DataSet Provider would just read the symbols from the file to determine what symbols to use to populate the DataSet.

Am I missing something?
0
ww58
- ago
#16
That's exactly how it works right now. Even without DataSetProvider, just editing xml file works. Now this is the only feature that requires restarting the program, since for some time wl handles IB connection restore flawlessly. So I'll probably keep it that way. I just wanted to realize it more gracefully without restart if possible.
0
Glitch8
 ( 10.13% )
- ago
#17
Technically it could be possible but it would probably involve some event handling and custom methods. We could take it on as a Concierge project if it's something you'd really like to see realized.
0
- ago
#18
@ww5 - you mentioned you were suppressing an exception when you used UpdateSymbols. Assuming I'm understanding what you did, don't suppress the exception. Instead, you need to wrap the UpdateSymbols call in a Invoke call that uses the main thread (see code below).

Using the sample code below, I could update the data set, and it was immediately reflected in any strategies that I had open that were referencing the dataset. For instance, if a strategy had run with the dataset, with 2 symbols, then of course in the lower left corner of the strategy it would show 2 symbols loaded. If I ran my test code to modify the dataset (via DataSetFactory.Instance.UpdateSymbols) then any open strategies that were referencing the modified dataset, and were showing N symbol(s) loaded immediately flipped over to "Need to Load Data" (in the strategy window's lower left corner) indicating it was aware a data load was needed because the dataset had been updated. This worked even if the dataset's symbols did not change.

Here's the code. Notice the Application.Current.Dispatcher.Invoke call so it runs on the main thread as it should.
CODE:
using System.Windows; using WealthLab.Backtest; using WealthLab.Core; namespace WealthLabStrategies.MovingAverage { public class TryDataSetFactory : UserStrategyBase { private const string DataSetName = "Test Data Set"; public override void Initialize(BarHistory bars) { // must run on the main thread Application.Current.Dispatcher.Invoke(() => { var ds = DataSetFactory.Instance.Find(DataSetName); if (ds == null) { WriteToDebugLog($"Hey, I couldn't find data set named {DataSetName}"); return; } // note that this is using C# version 12 DataSetFactory.Instance.UpdateSymbols(ds, [ "F", "MSFT", "TSLA" ]); // go find the dataset again and check what symbols are present ds = DataSetFactory.Instance.Find(DataSetName); foreach (var symbol in ds.Symbols) { WriteToDebugLog(symbol); } }); } public override void Execute(BarHistory bars, int idx) { } } }
3
Best Answer
Glitch8
 ( 10.13% )
- ago
#19
Nice!!
0
ww58
- ago
#20
@paul1986, your solution works like a charm. Thank you!
0

Reply

Bookmark

Sort