I've been trying to import 5-min intraday data. I have my own files (.csv) with ES futures 5-min data (OHLC) of various length of time. DATE in yyyymmdd format in column A, and TIME in hhmm or hh:mm format in Column B. I have created links on Dropbox (as was recommended in CustomDataNIFTYAlgorithm.cs) for GetSource method.
However, I have not found a way how to initialize a Start Time (in hrs and min) and End Time inside a certain date.
I am certain there is an easy solution, but I am relatively new to programming and QC and this is where I am stuck, so a detailed help would be very appreciated
Boris Sachakov
I guess I just need help with setting start time (hr, min) and end time (hr, min) of the day
Jared Broad
Hi Boris, each row of your file is a bar / data point. You specify the bar start time with the Time property of the data.
You can combine the two columns to make the the final time: e.g.
//Psuedo Code DateTime date = GetDateColumn(); TimeSpan time = GetTimeColumn(); this.Time = date + time;
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.
Boris Sachakov
Thank you Jared for your comment.
If I may ask you, Jared, to give me a little bit more of help and write a little bit more of code/algorithm, since I am not sure where to use the above code.
Alexandre Catarino
Boris, I think I don't understand your question, because I don't get what you mean by "setting start time and end time".
Let me guess. You have 5-min data that can be found in several files. In this case, you need to keep data from the same day in one file or several days in one file. In other words, you cannot break data from one day in more than one file, since the algorithm only checks for different data source once per day in backtesting mode.
If my answer is too off, could you please give us more details?
Boris Sachakov
Alexandre,
Actually, I have data in both ways:
1. 5-min data for a particular date (2016/11/29 , for example) in one .csv file; and
2. 5-min data for a range of dates (entire 2015, for example) in another . csv file.
Column A: Date (yyyymmdd); B: Time (hhmmss); C: Open; D: High; E: Low; F: Close; G: Vol.
I want to run algorithm based on either of the above data from 9:30 am to 12:00 pm (as an example) to check for certain intraday candlesticks patterns.
My original question was how to initialize this time period.
Alexandre Catarino
Ok. First, follwing Jared's comment, we need to include the time (hhmmss) to the date. Please edit the Reader method as follows:
public long Volume = 0; public override BaseData Reader( SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) { //New Nifty object Nifty index = new Nifty(); try { var data = line.Split(','); var date = DateTime.Parse(data[0], CultureInfo.InvariantCulture); var time = TimeSpan.ParseExact(data[1], "HHmmss", CultureInfo.InvariantCulture); index.Time = date + time; index.Open = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture); index.High = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture); index.Low = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); index.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture); index.Volume = Convert.ToInt32(data[5], CultureInfo.InvariantCulture); index.Symbol = "NIFTY"; index.Value = index.Close; } catch { } return index; }
If you want to limit the data to the period from 9:30 am to 12:00 pm, you can introduce a condition in the OnData method:
public void OnData(Nifty data) { if( data.Time.TimeOfDay < new TimeSpan(9, 30, 00) || data.Time.TimeOfDay > new TimeSpan(12, 00, 00)) { return; } /* Trading logics continue here */ }
Boris Sachakov
Thank you so much.
Let me take some time to look the above code over and then I might have some more questions.
Boris Sachakov
@Alexandre, Jared + everybody,
I followed your recommendations and created what at first appeared a good immitation. I set it to start and end the same day - just to accomplish one trade (to buy on Open at 9:30am). I included the link to Dropbox, which leads to my file with 5-min data of ES future for entire 2016 until now. The file is 4.8MB (less than 10MB maximum allowed). I ran it on both the Visual Basic and on QC. Nothing. No trade was recorded.
Maybe you can review and critique my work. Thanks in advance.
Boris Sachakov
Any suggestions on how to fix my above algorithm are welcome.
Alexandre Catarino
When the algorithm tries to parse the date string, a format exception is thrown and the Reader returns an "empty" Emini object. In this case, the algorithm will not pass the information through, since it is invalid.
To fix that we need to use DateTime.ParseExact method for the date (first column) too.
Let's also parse the date and time in one operation. Please modify the following lines:
var nowDate = DateTime.Parse(data[0], CultureInfo.InvariantCulture); var nowTime = TimeSpan.ParseExact(data[1], "HHmmss", CultureInfo.InvariantCulture); index.Time = nowDate + nowTime;
for:
index.Time = DateTime.ParseExact(data[0] + data[1], "yyyyMMddhhmmss", CultureInfo.InvariantCulture);
Boris Sachakov
@Alexandre,
Thank you so much. The above substitution did the job and algorithm worked.
Question: how did you figure out what needed to be fixed? Or is there anywhere that says: "a format exception is thrown and the Reader returns an "empty" Emini object". How can I know this next time? And how did you know that [parse the date and time in one operation] would work? Trial and error? Or is there a rule?
I am attaching my algorithm and the backtest for everybody to use, since I didn't see any algorithms with intraday data download.
Alexandre Catarino
We have a try/catch where the catch does nothing. This hides any exception that would appear when we are parsing the string array items into date, time, decimal and integer. That was my clue.
To test that, I ran the code locally (you can download and run Lean in your machine).
We should not use empty catch before we are sure that we know and understand what can fail in the try.
Boris Sachakov
Do you think you will be able to explain here in couple of sentences how try-catch statements work? Previously I already looked it up on https://msdn.microsoft.com/en-us/library/0yd65esw.aspx, but I still don't have a clear understanding of how it works and what it does for us. Thanks.
Alexandre Catarino
Say we write some code and when we run it, it thows an exception. In this scenario, the application will be terminated. To avoid this (default) behaviour, we can use the try-catch statement to do something else.
If the code inside the try body throws an exception, the application will continue in the catch body (the exception is caught) where we can deal with it. For instance we can log the errors and returns a default:
try { var dateString = "I am not a date"; return DateTime.Parse(dateString); } catch(Exception exception) { Console.WriteLine(exception.Message); return DateTime.Now; }
Boris Sachakov
Thank you for the above explanation. Things are a lot clearer now. Especially, I like the (exception.Message) inside of the 'catch' block, since it prints on console what the nature of the problem is.
Boris Sachakov
Is it better to leave the 'catch' block totally empty or to have notifications like above (exception.Message) included?
Boris Sachakov
I found the answers to the above questions concerning try-catch myself.
An algorithm may throw an exception (i.e. there is a technical problem) in the 'try' section, but it (exception) will be intercepted (stopped) in the 'catch' section, so the algorithm may continue running regardless of that technical problem. Having {Console.WriteLine(exception.Message);} inside of 'catch' section reveals to you the nature of the exception, but it should only be used if and after algorithm doesn't produce the expected outcome. The reason for not using it all the time is the following: this code will also print irrelevent minor exceptions that do not prevent an algorithm from completing its goal, but will only detract our attention.
Boris Sachakov
@Alexandre,
After much success, I however encountered 2 problems with the code you recommended above:
index.Time = DateTime.ParseExact(data[0] + data[1], "yyyyMMddhhmmss", CultureInfo.InvariantCulture);
1) The time of day in my data goes according to the above formula (hhmmss), such as 104500. However, when I request to find a candle before 10AM, it cannot be found. After significant effort, now I have to presume this is because the time before 10AM has 5 digits, such as 94500, so it doesn't add correctly into the above code.
2) Likewise, I can't find any candles after 12pm. This is less important for me, since I concentrate on morning hours, but nevertheless bothersome.
in my algorithm (see attached), I requested Time, Open and Close of Bar at 9:45, 10:45 and 12:45. Only 10:45 Bar was found and logged (see Logs after Backtest).
Thanks in advance.
Boris Sachakov
I was able to solve the problem concerning importing data prior to 10AM. I had to make a following adjustment: I used "Insert" to add "0" in 0 index position to create 6-digit time of day, such as 094000. Nothing else worked.
var theTime = TimeSpan.ParseExact(data[1].Insert(0, "0"), "hhmmss", CultureInfo.InvariantCulture);
Boris Sachakov
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!