Skip to content

Commit

Permalink
Refactor & changes requested
Browse files Browse the repository at this point in the history
- Removed reflection usage to limit performance impact
- Revisited valid field matching logic
- Added support for volume
- Updated unit test
  • Loading branch information
D1mi3 committed Jun 13, 2024
1 parent 7b59637 commit 4dd139f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
64 changes: 30 additions & 34 deletions Common/Securities/SecurityCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using QuantConnect.Python;
using System.Reflection;
using Python.Runtime;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Util;
Expand Down Expand Up @@ -230,38 +228,6 @@ protected virtual void ProcessDataPoint(BaseData data, bool cacheByType)
return;
}

var pythonData = data as PythonData;
if (pythonData != null && (_lastQuoteBarUpdate != data.EndTime || _lastOHLCUpdate != data.EndTime) && isDefaultDataType)
{
// Get matching pythonData and IBar properties
IDictionary<string, object> storage = pythonData.GetStorageDictionary();
PropertyInfo[] barProperties = typeof(IBar).GetProperties();
List<string> fieldsRequired = barProperties.Select(property => property.Name.ToLowerInvariant()).ToList();
var matches = storage.Where(kvp => fieldsRequired.Contains(kvp.Key) && kvp.Value != null) ;

IDictionary<string, decimal> validOHLC = new Dictionary<string, decimal>();

// Convert OHLC to decimal & update properties
if (matches.Count() == fieldsRequired.Count)
{
foreach (KeyValuePair<string, object> match in matches)
{
decimal.TryParse(match.Value.ToString(), out decimal result);
validOHLC.Add(match.Key, result);
}
_lastOHLCUpdate = data.EndTime;
if (validOHLC["open"] != 0) Open = validOHLC["open"];
if (validOHLC["high"] != 0) High = validOHLC["high"];
if (validOHLC["low"] != 0) Low = validOHLC["low"];
if (validOHLC["close"] != 0)
{
Price = validOHLC["close"];
Close = validOHLC["close"];
}
return;
}
}

var bar = data as IBar;
if (bar != null)
{
Expand Down Expand Up @@ -303,6 +269,36 @@ protected virtual void ProcessDataPoint(BaseData data, bool cacheByType)
Price = data.Price;
}
}

var pythonData = data as PythonData;
if (pythonData != null && (_lastQuoteBarUpdate != data.EndTime || _lastOHLCUpdate != data.EndTime) && isDefaultDataType)
{
IDictionary<string, object> storage = pythonData.GetStorageDictionary();
List<string> validFields = new List<string> { "open", "high", "low", "close", "volume" };
IDictionary<string, decimal> validOHLC = new Dictionary<string, decimal>();

foreach (string fieldName in validFields)
{
if (!storage.ContainsKey(fieldName))
validOHLC.Add(fieldName, 0);
else
{
string match = storage[fieldName].ToString();
decimal.TryParse(match, out decimal result);
validOHLC.Add(fieldName, result);
}
}
_lastOHLCUpdate = data.EndTime;
if (validOHLC["open"] != 0) Open = validOHLC["open"];
if (validOHLC["high"] != 0) High = validOHLC["high"];
if (validOHLC["low"] != 0) Low = validOHLC["low"];
if (validOHLC["volume"] != 0) Volume = validOHLC["volume"];
if (validOHLC["close"] != 0)
{
Price = validOHLC["close"];
Close = validOHLC["close"];
}
}
}

/// <summary>
Expand Down
4 changes: 4 additions & 0 deletions Tests/Common/Securities/SecurityCacheTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ def Reader(self, config, line, date, isLiveMode):
result.High = 4.1
result.low = 2.0
result.close = 3.7
result.volume = 33
result.Time = datetime.strptime(""2022-05-05"", ""%Y-%m-%d"")
return result");

Expand All @@ -392,6 +393,7 @@ def Reader(self, config, line, date, isLiveMode):
Assert.AreEqual(3.7, securityCache.Close);
Assert.AreEqual(2.0, securityCache.Low);
Assert.AreEqual(3.1, securityCache.Open);
Assert.AreEqual(33, securityCache.Volume);

testModule = PyModule.FromString("testModule",
@"
Expand All @@ -406,6 +408,7 @@ def Reader(self, config, line, date, isLiveMode):
result.High = 4
result.low = 2.0
result.Close = ""test""
result.volume = 0
result.Time = datetime.strptime(""2022-05-05"", ""%Y-%m-%d"")
return result");

Expand All @@ -418,6 +421,7 @@ def Reader(self, config, line, date, isLiveMode):
Assert.AreEqual(0, securityCache.Close);
Assert.AreEqual(2.0, securityCache.Low);
Assert.AreEqual(3.1, securityCache.Open);
Assert.AreEqual(0, securityCache.Volume);
}
}

Expand Down

0 comments on commit 4dd139f

Please sign in to comment.