22 using System.Collections.Generic;
32 private static dynamic _pandas;
33 private static PyObject _concat;
44 var pandas = Py.Import(
"pandas");
47 _concat = pandas.GetAttr(
"concat");
58 public PyObject
GetDataFrame(IEnumerable<Slice> data, Type dataType =
null)
61 var sliceDataDict =
new Dictionary<SecurityIdentifier, PandasData>();
64 var requestedTick = dataType ==
null || dataType == typeof(
Tick) || dataType == typeof(
OpenInterest);
65 var requestedTradeBar = dataType ==
null || dataType == typeof(
TradeBar);
66 var requestedQuoteBar = dataType ==
null || dataType == typeof(
QuoteBar);
68 foreach (var slice
in data)
70 AddSliceDataTypeDataToDict(slice, requestedTick, requestedTradeBar, requestedQuoteBar, sliceDataDict, ref maxLevels);
75 if (sliceDataDict.Count == 0)
77 return _pandas.DataFrame();
79 using var dataFrames = sliceDataDict.Select(x => x.Value.ToPandasDataFrame(maxLevels)).ToPyListUnSafe();
80 using var sortDic = Py.kw(
"sort",
true);
81 var result = _concat.Invoke(
new[] { dataFrames }, sortDic);
83 foreach (var df
in dataFrames)
101 foreach (var datum
in data)
103 if (sliceData ==
null)
108 sliceData.Add(datum);
115 if (sliceData ==
null)
117 return _pandas.DataFrame();
119 return sliceData.ToPandasDataFrame();
132 var pyDict =
new PyDict();
134 foreach (var kvp
in data)
136 AddSeriesToPyDict(kvp.Key, kvp.Value, pyDict);
139 return MakeIndicatorDataFrame(pyDict);
152 using var inputPythonType = data.GetPythonType();
153 var inputTypeStr = inputPythonType.ToString();
154 var targetTypeStr = nameof(PyDict);
155 PyObject currentKvp =
null;
159 using var pyDictData =
new PyDict(data);
160 using var seriesPyDict =
new PyDict();
162 targetTypeStr = $
"{nameof(String)}: {nameof(List<IndicatorDataPoint>)}";
164 foreach (var kvp
in pyDictData.Items())
167 AddSeriesToPyDict(kvp[0].As<string>(), kvp[1].As<List<IndicatorDataPoint>>(), seriesPyDict);
170 return MakeIndicatorDataFrame(seriesPyDict);
174 if (currentKvp !=
null)
176 inputTypeStr = $
"{currentKvp[0].GetPythonType()}: {currentKvp[1].GetPythonType()}";
179 throw new ArgumentException(
Messages.
PandasConverter.ConvertToDictionaryFailed(inputTypeStr, targetTypeStr, e.Message), e);
190 return _pandas ==
null
202 private void AddSeriesToPyDict(
string key, List<IndicatorDataPoint> points, PyDict pyDict)
204 var index =
new List<DateTime>();
205 var values =
new List<double>();
207 foreach (var point
in points)
209 index.Add(point.EndTime);
210 values.Add((
double) point.Value);
212 pyDict.SetItem(key.ToLowerInvariant(), _pandas.Series(values, index));
220 private PyObject MakeIndicatorDataFrame(PyDict pyDict)
222 return _pandas.DataFrame(pyDict, columns: pyDict.Keys().Select(x => x.As<
string>().ToLowerInvariant()).OrderBy(x => x));
229 private PandasData GetPandasDataValue(IDictionary<SecurityIdentifier, PandasData> sliceDataDict, Symbol symbol,
object data, ref
int maxLevels)
232 if (!sliceDataDict.TryGetValue(symbol.ID, out value))
234 sliceDataDict[symbol.ID] = value =
new PandasData(data);
235 maxLevels = Math.Max(maxLevels, value.Levels);
244 private void AddSliceDataTypeDataToDict(
Slice slice,
bool requestedTick,
bool requestedTradeBar,
bool requestedQuoteBar, IDictionary<SecurityIdentifier, PandasData> sliceDataDict, ref
int maxLevels)
246 HashSet<SecurityIdentifier> _addedData =
null;
248 for (
int i = 0; i < slice.
AllData.Count; i++)
250 var baseData = slice.
AllData[i];
251 var value = GetPandasDataValue(sliceDataDict, baseData.Symbol, baseData, ref maxLevels);
253 if (value.IsCustomData)
259 var tick = requestedTick ? baseData as
Tick :
null;
263 if (requestedTradeBar && requestedQuoteBar)
265 _addedData ??=
new();
266 if (!_addedData.Add(baseData.Symbol.ID))
274 var tradeBar = requestedTradeBar ? baseData as
TradeBar :
null;
275 if (tradeBar !=
null)
281 quoteBar = requestedQuoteBar ? baseData as
QuoteBar :
null;
282 if (quoteBar !=
null)
287 value.Add(tradeBar, quoteBar);