- ago
The following code reads from a file that contains a list of pairs symbols and their weights:

CODE:
   string fileName = Path.Combine(WLHost.Instance.DataFolder, "pairs2024_FebEODHD.csv");                if (!File.Exists(fileName))                   throw new FileNotFoundException("Pairs file not found: " + fileName);                string[] lines = File.ReadAllLines(fileName);                foreach (string line in lines)                {                   if (line.Trim() == "")                      continue;                   string[] tokens = line.Split(';');                   string[] pairTokens = tokens[0].Split('/');                   (string, double) pw;                   pw.Item1 = pairTokens[1];                                  pw.Item2 = Double.Parse(tokens[1], CultureInfo.InvariantCulture);                   _pairs[pairTokens[0]] = pw;                }


The previous version of this code is identical apart from the file name and reads the symbols in IB symbology format without issue. However, the modified version of the file (with symbols in EODHD format that have a trailing ".US") causes symbol not found errors for all symbols.

For instance:

CODE:
Initialize Exception (ABCB.US) Line 64 - Symbol not found in Pairs file: ABCB.US


...even though the first line of the symbols file is:
CODE:
ABCB.US/CADE.US;0.071


I've tried escaping the "." in the symbol names in case that was the issue but no luck.

0
217
Solved
9 Replies

Reply

Bookmark

Sort
- ago
#1
You totally forgot your declaration for the _pairs[...] array.

And I don't follow your declaration for pw. Do you mean:
CODE:
      struct Items       {          public string item1;          public double item2;       }       Items pw = new Items();
Understand, you have to declare the pw structure somewhere. And you need the "new" operator somewhere to allocate storage on the heap (dynamic memory) for item1 and item2.

Which line is Line 64 that's throwing the error?
0
- ago
#2
Many thanks for response. That's all present elsewhere and works (this was a concierge job - I'd paste the whole script except that this not my exclusive IP - apologies for not making that clear). The script has been in live production for a while with no issues. FYI Line 64 is:

CODE:
if (!_pairs.ContainsKey(bars.Symbol))             throw new InvalidOperationException("Symbol not found in Pairs file: " + bars.Symbol);
0
- ago
#3
So is _pairs declared as a Dictionary<string,Items> datatype somewhere? Is the "new" operator in there somewhere so heap storage is allocated for the individual Dictionary elements? (It doesn't look like it.)

I don't think the forum can troubleshoot this successfully without more of the code. I would email this problem to the person that coded this up for you and have him fix it.

I don't "think" the problem is related to the ".US" extension from what I see in the code. The Split method doesn't care about this extension.
0
- ago
#4
thanks again - here's the segment of the code that reads the pairs data where you can see the _pairs declaration:

CODE:
   public override void BacktestBegin()       {          Backtester.PositionSize.StartingCapital = Parameters[0].AsDouble;          Backtester.CurrentCash = Parameters[0].AsDouble;          lock (_lock)          {             //check global memory             if (HasGlobal("PairsData"))                _pairs = (Dictionary<string, (string, double)>)GetGlobal("PairsData");             //create pairs dictionary on-demand             if (_pairs == null)             {                _pairs = new Dictionary<string, (string, double)>();                SetGlobal("PairsData", _pairs);                //load pairs file contents                string fileName = Path.Combine(WLHost.Instance.DataFolder, "pairs2024_FebEODHD.csv");                if (!File.Exists(fileName))                   throw new FileNotFoundException("Pairs file not found: " + fileName);                string[] lines = File.ReadAllLines(fileName);                foreach (string line in lines)                {                   if (line.Trim() == "")                      continue;                   string[] tokens = line.Split(';');                   string[] pairTokens = tokens[0].Split('/');                   (string, double) pw;                   pw.Item1 = pairTokens[1];                                  pw.Item2 = Double.Parse(tokens[1], CultureInfo.InvariantCulture);                   _pairs[pairTokens[0]] = pw;                }             }          }       }


... the thing that's puzzling me is that everything runs flawlessly with a pairs file and data set using IB symbology. The only changes I've made are to create a data set containing the same symbols except in EODHD format and a pairs file that also includes the same symbols in EODHD format. So I'm thinking that the issue is somehow specific to those changes.

I've also double checked the new file for any hidden characters (it was created in Excel), but all it has are the same line feeds as the original file.
0
- ago
#5
There are definitely constructs in this code I'm not familiar with. This must be new in C# version 10.0. For example, the line
CODE:
_pairs = new Dictionary<string, (string, double)>();
I would write like this after including the Items declaration shown in Post #1.
CODE:
_pairs = new Dictionary<string, Items>();
and the "new" operator is not being used, which is weird to me. I would have someone familiar with version 10 of C# troubleshoot this for you, which is not me.

It's interesting you are storing the Dictionary in global memory instead of static memory. I'm gathering that's because several unrelated strategies are all referencing this same Dictionary. Interesting.
0
- ago
#6
Many thanks for all your help - I'll do that
0
- ago
#7
@superticker: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-tuples
0
- ago
#8
Interesting. So tuples can be handled differently in C# now so you don't need the struct.

I figure out what's wrong with the code. The line ...
CODE:
_pairs[pairTokens[0]] = pw;
should be changed to ...
CODE:
_pairs[pairTokens[0].Replace(".US",null)] = pw;
because the search is looking for "symbol" instead of "symbol.US" in the Dictionary, so the ".US" needs to be removed when storing new elements in the Dictionary. Oh well, I tried.
0
Best Answer
- ago
#9
Awesome! Many thanks - completely missed that. It works perfectly.
1

Reply

Bookmark

Sort