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
Molowing
Hi again,
I have just update subscriber to read from local file and in addition I have updated FDAX in order to inherits from TraderBar and it seemsl that now it´s working
Is it necessary to update anything else ?
ThanKs
David
Molowing
Hi again,
After previous updates I have found a new issue with my five-minute and one-day "consolidated tradebars". High, Low and Close appears to be 0 for all bars .
Taking a look to de CallStack the first thing I can see is related to DataConsolidator.Update(IBaseData data) method.
data comes in following way (see attached image)
So, I wonder why the "Close" it´s ok and the rest is failing. Am I missing something =
Thanks
David
Molowing
Hi again,
I have just updated the FDAX OHLC properties by including "override" modifier and now it´s wowking....
Is a valid solution ?
Do I need to provide some alternative approach for avoiding loosing backtesting stability ?
public override decimal Open { get; set; } public override decimal High { get; set; }; public override decimal Low { get; set; }; public override decimal Close { get; set; };
Thanks
David
Alexandre Catarino
Hi Molowing ,
Sorry about the wait. It looks like you have figured it out by yourself. Good job!
Yes, using override is a valid solution and you might as well inherit from TradeBar.
In the original, version I've seen two issues.
URL: https://www.dropbox.com/s/75ps7zle5ehozee/FDAX102019.csv?dl=1 (you had zero, instead of one)
Column separation: ";", not " "
Molowing
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!