Hi,

I´m working with LEAN under VS2019 (I´m new with QC but no so with C# and VS). I need to model some strategies for DAX future. As far as I know, QC does not provide this data by default, so I have created my first Data Adaptor following the guidelines of CQ documentation and samples.

FDAX Data is a simple csv file public available from DropBox url

When running my "CustomDataFDAXAlgorithm" I´m getting an error at line.Split() inside Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) cause is not getting my csv file

At debugging, It can be seen how the process is taken a xml-format temp file at : %root%\Lean-master-2019\Lean-master\Launcher\bin\Debug\cache\data, the file is 659ca019b17f9be422b1d3a3d213d5a8.custom

Could you please provide me with some details for solving this issue ? 

Why the reader is not using the csv file ? 

Is it possible that I´m missing something at configuration side?

I also see that the timezone and market are setted as "usa" as default, where I can update these settings to "europe" ones ?

Many thanks for your support on this !

Here below dummy code : 

using System; using System.Globalization; using Newtonsoft.Json; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Market; using QuantConnect.Indicators; using QuantConnect.Orders; namespace QuantConnect.Algorithm.CSharp { public class CustomDataFdaxAlgorithm : QCAlgorithm { #region Variables private TradeBar _last; private RollingWindow<TradeBar> contractedDay = new RollingWindow<TradeBar>(1); private RollingWindow<TradeBar> fiveMinutesBars= new RollingWindow<TradeBar>(10); private int ThresholdTrigger=1200; #endregion #region Properties public RollingWindow<TradeBar> ContractedDay { get { return contractedDay; } set { contractedDay = value; } } public RollingWindow<TradeBar> FiveMinutesBars { get { return fiveMinutesBars; } set { fiveMinutesBars = value; } } #endregion public override void Initialize() { //Weather data we have is within these days: SetStartDate(2019, 1, 1); SetEndDate(DateTime.Now.Date.AddDays(-6)); //Set the cash for the strategy: SetCash(10000); AddData<FDAX>("FDAX", Resolution.Minute); // define our 5 minute trade bar consolidator. we can access the 5 minute bar from the DataConsolidated events var fiveMinuteConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5)); // attach our event handler. the event handler is a function that will be called each time we produce a new consolidated piece of data. fiveMinuteConsolidator.DataConsolidated += FiveMinuteBarHandler; // this call adds our 5 minute consolidator to the manager to receive updates from the engine SubscriptionManager.AddConsolidator("FDAX", fiveMinuteConsolidator); // var contractBar = new RollingWindow<TradeBar>(1); } /// <summary> /// Event Handler for Bitfdax Data Events: These weather objects are created from our /// "Weather" type below and fired into this event handler. /// </summary> /// <param name="data">One(1) Weather Object, streamed into our algorithm synchronised in time with our other data streams</param> public void OnData(FDAX data) { if (!Portfolio.Invested) { if (data.Close != 0) { if (!ContractedDay.IsReady) return; // first scape condition if (IsContracted(ContractedDay[0])) { if (Math.Abs(DynamicDensity(FiveMinutesBars[0])) > ThresholdTrigger) { //enter short var newTicket = MarketOrder("FDAX", -2, asynchronous: false); if (newTicket.Status != OrderStatus.Filled) Log("Synchronous short market order was not filled synchronously!"); Console.WriteLine("Shorting FDAX 'Shares': FDAX: " + data.Close); } else { if (Math.Abs(DynamicDensity(FiveMinutesBars[0])) > ThresholdTrigger) { //enter long var newTicket = MarketOrder("FDAX", 2, asynchronous: false); if (newTicket.Status != OrderStatus.Filled) Log("Synchronous long market order was not filled synchronously!"); Console.WriteLine("Buying FDAX 'Shares': FDAX: " + data.Close); } } } } } Console.WriteLine("Time: " + Time.ToStringInvariant("T") + " " + Time.ToStringInvariant("T") + data.Close.ToStringInvariant()); } /// <summary> /// This is our event handler for our 5 minute trade bar defined above in Initialize(). So each time the consolidator /// produces a new 5 minute bar, this function will be called automatically. The 'sender' parameter will be the /// instance of the IDataConsolidator that invoked the event, but you'll almost never need that! /// </summary> private void FiveMinuteBarHandler(object sender, TradeBar consolidated) { //five-minute consolidator code FiveMinutesBars.Add(consolidated); } private void OneDayBarHandler(object sender, TradeBar consolidated) { // define on-daily event ContractedDay.Add(consolidated); } private bool IsContracted(TradeBar consolidated) { // logic for IsContracted to be implemented here return true; } private int DynamicDensity(TradeBar consolidated) { // logic for density to be implemented here return 1000; } public class FDAX : BaseData { [JsonProperty("date")] public DateTime Timestamp = DateTime.Now; [JsonProperty("timeFrom")] public DateTime TimeFrom = DateTime.MinValue; [JsonProperty("timeTo")] public DateTime TimeTo = DateTime.MinValue; [JsonProperty("SecurityID")] public int SecurityID = 0; [JsonProperty("open")] public decimal Open = 0; [JsonProperty("high")] public decimal High = 0; [JsonProperty("low")] public decimal Low = 0; [JsonProperty("close")] public decimal Close = 0; [JsonProperty("volume")] public decimal VolumeFDAX = 0; [JsonProperty("numberOfTicks")] public decimal NumberOfTicks = 0; public FDAX() { Symbol = "FDAX"; } public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode) { return new SubscriptionDataSource("https://www.dropbox.com/s/75ps7zle5ehozee/FDAX102019.csv?dl=0", SubscriptionTransportMedium.RemoteFile); } public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) { var fdax = new FDAX(); if (isLiveMode) { //Example Line Format: //{"date": "", "timeFrom": "", "timeTo": "", "SecurityID": "", "open": "", "high": "", "low": "", "close": "", "volume": "", "numberOfTicks": ""} try { fdax = JsonConvert.DeserializeObject<FDAX>(line); fdax.EndTime = DateTime.UtcNow.ConvertFromUtc(config.ExchangeTimeZone); fdax.Value = fdax.Close; } catch { /* Do nothing, possible error in json decoding */ } return fdax; } //Example Line Format: //Date TimeFrom TimeTo SecurityID Open High Low Close Volume NumberOfTicks //2019-10-01 00:15:00 00:16:00 3905982 12414.5 12414.5 12411.5 12413 37 9 try { string[] data = line.Split(','); fdax.Timestamp = DateTime.Parse(data[0], CultureInfo.InvariantCulture); fdax.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture); fdax.TimeFrom = DateTime.Parse(data[1], CultureInfo.InvariantCulture); fdax.TimeTo = DateTime.Parse(data[2], CultureInfo.InvariantCulture); fdax.SecurityID = Convert.ToInt16(data[3], CultureInfo.InvariantCulture); fdax.Open = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); fdax.High = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture); fdax.Low = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture); fdax.Close = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture); fdax.VolumeFDAX = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture); fdax.NumberOfTicks = Convert.ToDecimal(data[9], CultureInfo.InvariantCulture); fdax.Value = fdax.Close; } catch { /* Do nothing, skip first title row */ } return fdax; } } } }

David

 

Author