public static void LoadExternalFeatureBinary(Asset asset, ExternalFeatureData externalFeature, MessageDelegate messageDelegate) { //Read the results into the bars from the binary file that python has written over PreCalculatedFeatures pcFeatures = new PreCalculatedFeatures(); //[ASSET] is used as a placeholder so insert the assetname here string filename = externalFeature.BinaryFilepath.Replace("[ASSET]", asset.Name); byte[] bytes = File.ReadAllBytes(filename); //Traverse the byte array to add in the values to the Data attribute of the corresponding bar int i = 0; while (i < bytes.Length) { //Read the required data from the byte array and increment the index long timestamp = BitConverter.ToInt64(bytes, i); i += 8; //convert from python to .net date DateTime dt = DateTime.FromBinary(timestamp / 100).AddYears(1969); //Add a new bar Dictionary <string, double?> barData = new Dictionary <string, double?>(); pcFeatures.Data.Add(dt, barData); foreach (string field in externalFeature.FieldNames) { double val = BitConverter.ToDouble(bytes, i); barData.Add(field, val); i += 8; } } //add this data to the asset (or overwrite if exists) if (!asset.Data.ContainsKey(externalFeature.Timeframe)) { asset.Data.Add(externalFeature.Timeframe, pcFeatures); } else { asset.Data[externalFeature.Timeframe] = pcFeatures; } }
public static void PythonFeatureBuilder(PythonBridge pb, Asset asset, ExternalFeatureData externalFeatureData, MessageDelegate messageDelegate = null) { messageDelegate?.Invoke(asset.Name + " Precalcualting Features ..."); //Record start time of process for time taken message DateTime now = DateTime.Now; //build the features into a semicolon sepearated string string featureCommand = externalFeatureData.FeatureCommands; //get the dataset for this timeframe Dictionary <int, Bar[]> timeframes = DataBuilder.BuildTimeFrames(asset, new int[] { externalFeatureData.Timeframe }); //Use a temporary Share directory for this data string filename = asset.DataPath.Replace(".bin", "_Share.bin"); //Generate a tempory binary file containing the datafeed to be used for calculation and save to disk string datasetType = "single"; if (externalFeatureData.CalculateOn == DataFeedType.Ask || externalFeatureData.CalculateOn == DataFeedType.Bid) //otherwise include all bid or ask OHLC and volume. { datasetType = "whole"; DataBuilder.DatasetToBinary(filename, timeframes[externalFeatureData.Timeframe], externalFeatureData.CalculateOn); } else //Faster way if just need a single data feed { DataBuilder.DatasetToBinarySingle(filename, timeframes[externalFeatureData.Timeframe], externalFeatureData.CalculateOn); } //[ASSET] is a placeholder string transformedFilename = externalFeatureData.BinaryFilepath.Replace("[ASSET]", asset.Name); //Bridge python to calculate the data string[] commands = new string[] { datasetType, filename, transformedFilename, externalFeatureData.FeatureCommands }; pb.RunScript(FeatureBuildPath, commands); File.Delete(filename); messageDelegate?.Invoke(asset.Name + " feature calculations took: " + (DateTime.Now - now).TotalSeconds + " secs"); }