- ago
Hi,

Here is a weird one...Run strategy in Strategy Monitor...got for signals...did auto stage and went to Order Manager. Press place (via IB) and two orders placed perfectly fine and two did not . So it is reporting that it cannot find code....yet, I can open chart, get streaming quotes and find it in TWS, not a problem...Log reports slightly different error . Nothing of note is on IB Gateway side.

Many thanks
0
534
Solved
6 Replies

Reply

Bookmark

Sort
Cone8
 ( 15.37% )
- ago
#1
See Help (F1) > Extensions > Interactive Brokers and look for IBContracts.txt. You must identify contracts you trade or request data for. Presumably your data source was not IB, that's why you were able to get signals, but IB couldn't identify the contract for those symbols.

Frankly, with the .AU suffix, I would have expect no problem with either of those symbols. But since it didn't work, you'll need to create records for those symbols in IBContracts.txt.

There's a script you can modify and run to aid in that task here -
https://www.wealth-lab.com/Discussion/Obtaining-data-from-IB-TWS-for-non-US-exchanges-11357
0
Best Answer
- ago
#2
Many thanks. The issue was that while one was missing (added it manually) the definition, some codes in the file were .au and some were .AU. The ones with .AU are fine and working but ones with .au struggled. I think this is the issue with the whole Norgate data set that is .au and IB is .AU.

Best,

Peter
0
Cone8
 ( 15.37% )
- ago
#3
IB by itself doesn't know anything about suffixes like "au" or "AU".
WL's IB Provider recognizes both cases and automatically assigns currency "AUD" and exchange "ASX" when attempting to identify the contract. If the symbol matches a contract with AUD/ASX, then you really don't even need to create the contract records. In fact, two records with both cases will be created automatically.
0
Cone8
 ( 15.37% )
- ago
#4
Hmm, I tried it myself and both version were indeed created...
CODE:
AAI.au=AAI|AUD|STK|ASX|ASX|AAI|||1.7976931348623157E+308| AAI.AU=AAI|AUD|STK|ASX|ASX|AAI|||1.7976931348623157E+308|
.. but that 1.7976931348623157E+308 value in the Strike field could be messing up identifying the contract.

If you see values like that, do this:
1. Close WealthLab
2. Search and replace "1.7976931348623157E+308" with "" (nothing)
3. Save.

I'll get a fix out for that.
0
Cone8
 ( 15.37% )
- ago
#5
Disregard. Although it won't hurt to do that process, the provider already ignores that value.
0
- ago
#6
Many thanks.

So on the back of the code provided in earlier script, here is a code that other people can use to maintain their IBContracts.txt if they are in the similar situation with their broker

CODE:
using WealthLab.Backtest; using WealthLab.Core; using System; using System.IO; using System.Linq; using System.Collections.Generic; namespace WealthScript2 {    public class MyStrategy : UserStrategyBase    {       // OPERATING MODES       // DryRun = true => log only, write no files       // DryRun = false + AutoReplaceWhenChanged = false => write rebuilt/audit files only       // DryRun = false + AutoReplaceWhenChanged = true => write files + backup + replace IBContracts.txt       const bool DryRun = false ;       const bool AutoReplaceWhenChanged = false ;       static bool _runOnce = false;       static string _timestamp = "";       static string _dataFolder = "";       static string _inputPath = "";       static string _rebuiltPath = "";       static string _auditPath = "";       static List<string> _preservedLines = new List<string>();       static List<string> _matchedEntries = new List<string>();       static List<string> _staleEntries = new List<string>();       static List<string> _newEntries = new List<string>();       static Dictionary<string, string> _existingManagedLines = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);       static Dictionary<string, string> _targetManagedLines = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);       public class ExchangeConfig       {          public bool Enabled { get; set; }          public string RegionCode { get; set; }          public string DataSetName { get; set; }          public string Currency { get; set; }          public string SecType { get; set; }          public string Exchange { get; set; }          public string PrimaryExchange { get; set; }          public string Suffix { get; set; }          public string FormatLine(string ticker)          {             // Current exact working AU format             if (Suffix.Equals(".AU", StringComparison.OrdinalIgnoreCase))                return $"{ticker}.AU={ticker}|{Currency}|{SecType}|{Exchange}|{PrimaryExchange}|{ticker}||||";             // Generic fallback for future expansion             return $"{ticker}{Suffix}={ticker}|{Currency}|{SecType}|{Exchange}|{PrimaryExchange}|{ticker}||||";          }          public string NormalizeKey(string ticker)          {             return ticker.ToUpperInvariant() + Suffix.ToUpperInvariant();          }       }       static List<ExchangeConfig> ManagedExchanges = new List<ExchangeConfig>     {        new ExchangeConfig        {          Enabled = true,          RegionCode = "AU",          DataSetName = "All Ordinaries",          Currency = "AUD",          SecType = "STK",          Exchange = "ASX",          PrimaryExchange = "ASX",          Suffix = ".AU"        }, // Scaffold for future use new ExchangeConfig        {          Enabled = false,          RegionCode = "US",          DataSetName = "",          Currency = "USD",          SecType = "STK",          Exchange = "SMART",          PrimaryExchange = "SMART",          Suffix = ""        }     };       public override void BacktestBegin()       {          _timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");          _dataFolder = WLHost.Instance.DataFolder;          _inputPath = Path.Combine(_dataFolder, "IBContracts.txt");          _rebuiltPath = Path.Combine(_dataFolder, $"IBContracts_{_timestamp}.txt");          _auditPath = Path.Combine(_dataFolder, $"IBContracts_Audit_{_timestamp}.txt");          WriteToDebugLog("IBContracts maintenance run started");          WriteToDebugLog("Input: " + _inputPath);          WriteToDebugLog("Output: " + _rebuiltPath);          WriteToDebugLog("Audit: " + _auditPath);          WriteToDebugLog("");          if (!File.Exists(_inputPath))          {             WriteToDebugLog("ERROR: IBContracts.txt not found: " + _inputPath);             return;          }          ParseExistingIbContracts();       }       public override void Initialize(BarHistory bars)       {          if (_runOnce)             return;          _runOnce = true;          BuildTargetManagedUniverse();       }       public override void BacktestComplete()       {          if (!File.Exists(_inputPath))          {             WriteToDebugLog("Aborting because input file was not found.");             return;          }          foreach (var kvp in _existingManagedLines.OrderBy(k => k.Key))          {             if (_targetManagedLines.ContainsKey(kvp.Key))                _matchedEntries.Add(_targetManagedLines[kvp.Key]);             else                _staleEntries.Add(kvp.Value);          }          foreach (var kvp in _targetManagedLines.OrderBy(k => k.Key))          {             if (!_existingManagedLines.ContainsKey(kvp.Key))                _newEntries.Add(kvp.Value);          }          List<string> finalLines = new List<string>();          finalLines.AddRange(_preservedLines           .Where(s => !string.IsNullOrWhiteSpace(s))           .Distinct(StringComparer.OrdinalIgnoreCase)           .OrderBy(s => s, StringComparer.OrdinalIgnoreCase));          finalLines.Add("");          finalLines.Add($"### AUTO-MANAGED EQUITY BLOCK [{_timestamp}] ###");          finalLines.AddRange(_targetManagedLines.Values           .Distinct(StringComparer.OrdinalIgnoreCase)           .OrderBy(s => s, StringComparer.OrdinalIgnoreCase));          HandleOutputs(finalLines);          PrintSummaryToLog();       }       public override void Execute(BarHistory bars, int idx)       {       }       private void BuildTargetManagedUniverse()       {          foreach (ExchangeConfig cfg in ManagedExchanges.Where(x => x.Enabled))          {             if (string.IsNullOrWhiteSpace(cfg.DataSetName))             {                WriteToDebugLog($"WARNING: Enabled region {cfg.RegionCode} has no DataSetName. Skipping.");                continue;             }             DataSet ds = DataSetFactory.Instance.Find(cfg.DataSetName);             if (ds == null)             {                WriteToDebugLog($"WARNING: DataSet not found for {cfg.RegionCode}: {cfg.DataSetName}");                continue;             }             foreach (string rawSymbol in ds.Symbols)             {                if (string.IsNullOrWhiteSpace(rawSymbol))                   continue;                string symbol = rawSymbol.Trim().ToUpperInvariant();                string[] parts = symbol.Split('.');                string ticker = parts[0].Trim().ToUpperInvariant();                if (string.IsNullOrWhiteSpace(ticker))                   continue;                string key = cfg.NormalizeKey(ticker);                string line = cfg.FormatLine(ticker);                _targetManagedLines[key] = line;             }          }       }       private void ParseExistingIbContracts()       {          foreach (string rawLine in File.ReadAllLines(_inputPath))          {             string line = rawLine.Trim();             if (string.IsNullOrWhiteSpace(line))                continue;             if (!line.Contains("="))             {                _preservedLines.Add(line);                continue;             }             string[] eqParts = line.Split(new char[] { '=' }, 2);             string lhs = eqParts[0].Trim();             string rhs = eqParts.Length > 1 ? eqParts[1].Trim() : "";             ExchangeConfig cfg = MatchManagedExchange(lhs, rhs);             if (cfg == null)             {                _preservedLines.Add(line);                continue;             }             if (!IsManagedStockEntry(rhs, cfg))             {                _preservedLines.Add(line);                continue;             }             string key = NormalizeExistingKey(lhs, rhs, cfg);             if (string.IsNullOrWhiteSpace(key))                _preservedLines.Add(line);             else                _existingManagedLines[key] = line;          }       }       private ExchangeConfig MatchManagedExchange(string lhs, string rhs)       {          string[] fields = rhs.Split('|');          string exch = fields.Length > 3 ? fields[3].Trim() : "";          string primaryExch = fields.Length > 4 ? fields[4].Trim() : "";          foreach (ExchangeConfig cfg in ManagedExchanges.Where(x => x.Enabled))          {             if (!string.IsNullOrWhiteSpace(cfg.Suffix) &&                lhs.EndsWith(cfg.Suffix, StringComparison.OrdinalIgnoreCase))                return cfg;             if (exch.Equals(cfg.Exchange, StringComparison.OrdinalIgnoreCase) ||                primaryExch.Equals(cfg.PrimaryExchange, StringComparison.OrdinalIgnoreCase))                return cfg;          }          return null;       }       private bool IsManagedStockEntry(string rhs, ExchangeConfig cfg)       {          string[] fields = rhs.Split('|');          if (fields.Length < 5)             return false;          string currency = fields[1].Trim();          string secType = fields[2].Trim();          if (!currency.Equals(cfg.Currency, StringComparison.OrdinalIgnoreCase))             return false;          if (!secType.Equals(cfg.SecType, StringComparison.OrdinalIgnoreCase))             return false;          return true;       }       private string NormalizeExistingKey(string lhs, string rhs, ExchangeConfig cfg)       {          string left = lhs.Trim().ToUpperInvariant();          if (!string.IsNullOrWhiteSpace(cfg.Suffix) &&             left.EndsWith(cfg.Suffix, StringComparison.OrdinalIgnoreCase))          {             return left.Substring(0, left.Length - cfg.Suffix.Length) + cfg.Suffix.ToUpperInvariant();          }          if (!left.Contains(".") && !string.IsNullOrWhiteSpace(left))             return left + cfg.Suffix.ToUpperInvariant();          string[] fields = rhs.Split('|');          if (fields.Length > 0)          {             string ticker = fields[0].Trim().ToUpperInvariant();             if (!string.IsNullOrWhiteSpace(ticker))                return ticker + cfg.Suffix.ToUpperInvariant();          }          return "";       }       private void HandleOutputs(List<string> finalLines)       {          bool hasChanges = _newEntries.Count > 0 || _staleEntries.Count > 0;          if (!hasChanges)          {             WriteToDebugLog("No changes detected. IBContracts.txt not modified.");             return;          }          if (DryRun)          {             WriteToDebugLog("DRY RUN ENABLED — changes detected but no files written.");             return;          }          File.WriteAllLines(_rebuiltPath, finalLines);          WriteAuditFile(finalLines);          WriteToDebugLog("Rebuilt file written: " + _rebuiltPath);          WriteToDebugLog("Audit file written: " + _auditPath);          if (!AutoReplaceWhenChanged)          {             WriteToDebugLog("AutoReplace disabled — IBContracts.txt not replaced.");             return;          }          string backupPath = Path.Combine(_dataFolder, $"IBContracts_backup_{_timestamp}.txt");          File.Copy(_inputPath, backupPath, true);          File.Copy(_rebuiltPath, _inputPath, true);          WriteToDebugLog("Original IBContracts.txt backed up to:");          WriteToDebugLog(backupPath);          WriteToDebugLog("IBContracts.txt successfully replaced.");       }       private void PrintSummaryToLog()       {          WriteToDebugLog("");          WriteToDebugLog("===== SUMMARY =====");          WriteToDebugLog("Target managed symbols: " + _targetManagedLines.Count);          WriteToDebugLog("Existing managed entries found in IBContracts.txt: " + _existingManagedLines.Count);          WriteToDebugLog("Preserved non-managed lines: " + _preservedLines.Count);          WriteToDebugLog("Matched entries: " + _matchedEntries.Count);          WriteToDebugLog("Stale entries removed: " + _staleEntries.Count);          WriteToDebugLog("New entries appended: " + _newEntries.Count);          WriteToDebugLog("");          if (!DryRun)          {             WriteToDebugLog("Rebuilt file path: " + _rebuiltPath);             WriteToDebugLog("Audit file path: " + _auditPath);             WriteToDebugLog("");          }          WriteFullSectionToLog("===== NEW ENTRIES =====", _newEntries);          WriteFullSectionToLog("===== STALE ENTRIES REMOVED =====", _staleEntries);       }       private void WriteFullSectionToLog(string header, List<string> items)       {          WriteToDebugLog(header);          if (items.Count == 0)          {             WriteToDebugLog("None");             WriteToDebugLog("");             return;          }          foreach (string item in items.OrderBy(s => s, StringComparer.OrdinalIgnoreCase))             WriteToDebugLog(item, false);          WriteToDebugLog("");       }       private void WriteAuditFile(List<string> finalLines)       {          List<string> audit = new List<string>();          audit.Add("IBContracts Maintenance Audit");          audit.Add("Run Time: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));          audit.Add("Input File: " + _inputPath);          audit.Add("Output File: " + _rebuiltPath);          audit.Add("");          audit.Add("SUMMARY");          audit.Add("Target managed symbols: " + _targetManagedLines.Count);          audit.Add("Existing managed entries found in IBContracts.txt: " + _existingManagedLines.Count);          audit.Add("Preserved non-managed lines: " + _preservedLines.Count);          audit.Add("Matched entries: " + _matchedEntries.Count);          audit.Add("Stale entries removed: " + _staleEntries.Count);          audit.Add("New entries appended: " + _newEntries.Count);          audit.Add("");          audit.Add("MATCHED ENTRIES");          if (_matchedEntries.Count == 0)             audit.Add("None");          else             audit.AddRange(_matchedEntries.OrderBy(s => s, StringComparer.OrdinalIgnoreCase));          audit.Add("");          audit.Add("STALE ENTRIES FOUND NOT MATCHED");          if (_staleEntries.Count == 0)             audit.Add("None");          else             audit.AddRange(_staleEntries.OrderBy(s => s, StringComparer.OrdinalIgnoreCase));          audit.Add("");          audit.Add("NEW ENTRIES");          if (_newEntries.Count == 0)             audit.Add("None");          else             audit.AddRange(_newEntries.OrderBy(s => s, StringComparer.OrdinalIgnoreCase));          audit.Add("");          audit.Add($"FINAL BLOCK [{_timestamp}]");          audit.AddRange(finalLines);          File.WriteAllLines(_auditPath, audit);       }    } }
0

Reply

Bookmark

Sort