Back

Getting historical closing price

Hello everyone,

I'm new to Quantconnect and I feel a little lost as I still don't know how many things work after having read the documentation. I'm trying to do something very simple for my first test algorithm. It should buy AAPL if the current price is lower than the previous day's closing price and sell it if it reaches a higher price than it was bought for. But I don't know how to get that closing price so I can compare them. I get an error saying my bars object has no .close property. How to do that correctly?

Thank you very much for your help.

Kind Regards,

Christian Lauer

Update Backtest








I'd really appreciate your help :)

0

Hey Christian Lauer, I'll try to help to my best.

First of all, great work! Is clear how hard you worked on this!

From a first view, seems to me you have overengineering something that should be easier.

But I'd like to have a clear sense of what you want to do, the code changed a lot since the first attempt and isn't clear to me what your goals are. Maybe you can give us a pseudocode of what you want to do. Another alternative is commenting the core parts of your actual code with what you expect to achieve.

Best.

JJD

0

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.


Hello JayJayD,

thank you for your message. It's not really that I've worked that hard so far. I just always encounter a new problem 10 minutes after the previous one has been solved, so that's why I've been working two weeks already on something quite simply. What this one should do is the following:

At 9:31 check if there has been a gap at the market open from the previous day. If so and the stock is gapping up and the first minute bar is negative, create a short selling signal. If the stock is gapping down and the first minute bar is postive, create a buying signal.

At the end of the day, if there is a short position, close it. (Here's where the problem occurs I've described above.)

Every second, check the price and if it's higher than the price the stock was bought for times 1.01, close the position.

The second problem is the insufficient buying power error I got on the other backtest I've posted.

Kind regards,

Christian Lauer

0

Hey Christian Lauer,

Check the attached algorithm, I made just small refactoring like rearranging the conditionals, changing variables names and commenting the code. I didn’t test it in depth but seem it works fine.

I think the key changes are the use of the Liquidate method for closing positions and the IsShort property for checking if the stock is short.

Hope it helps.

1

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.


Hello JayJayD,

thank you so much for your work. The code now looks much more elegant and better to read. I really should have paid more attention to these things. Unfortunately I still have the same two problems. In the backtest you added, there is a short at the 9th of May. But instead of closing the position at the end of the same day, there is another short on the next day, and then both are closed at the 11th. I have no idea how this is caused. Then, when testing from May to July 2013, there are insufficient buying power errors.

Kind regards,

Christian Lauer

0

I made just few changes:

  • I added a conditional before sell at threshold reach.
  • Maybe on 2015-05-09 the market closed earlier, so I used the TimeRules.BeforeMarketClose, this seems to fix the no sell at close problem. The problem is you cannot set the time at second resolution, just minutes.
  • I added a plot to follow the Portfolio.MarginRemaining to help you debugging the insufficient buying power issue.
  • I added the overridden OnEndOfAlgorithm method to close all position once the algorithm finishes.

Finally, if you already found when the problems arise, then you can make a more detailed debug just for those moments. Now you have some more tools to pin down the issues, good luck!

1

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.


I am also new to algo trading. I dont know if it is appropriate to ask on someone elses thread so I apologise in advance. 

I am also trying to create an algo similar to Christian's. The difference is that I want to buy a stock when the current price (checked every sec) is greater than 0,6% from pre-open last market price (not previous day's last trade price). Then, sell it when it is 1,6% greater than pre-open last market price.

Different from Christian's algo I want it to make multiple trades per day: i.e. if the price increase from 0,6% to 1,6% then sell at 1,6% and buy again at the same price (at 1,6% level). Then sell and buy at 2,6%, sell and buy at 3,6% and so on. Basically there would be thresholds at 0,6%, 1,6%, 2,6% etc and if triggered (if last minute bar is positive) then buy/sell trade would occur.

I am just a beginner at programming trying to learn from examples and tutorials. Tried to program my algo with Python as well as C# but with no success. Then I stumbled upon this algo in this thread and I noticed that it is really similiar to what I am trying to achieve. If somenone could help me by applying and modifying Christian's algo I would really appreciate. Thank you!    

0

Hi Arvydas Mickus,

If you want to dive into algorithmic trading, you must learn to code algorithms. No shortcuts, no easy path here, just do your homework and learn how to translate your ideas into a language. There are plenty of great resources out there to learn how to code, both coursera and edx have superb introduction courses. Once you have a basic knowledge, the way is learning by doing (and stackoverflow, of course).

Now respect to, your strategy, you are right, is quite similar to Christian’s one, so clone it and try to translate your ideas into code. Then show us where you are stuck and I’ll be here to give you a hand.

2

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.


Thanks JayJayD for the heads up. 

I have logged the prices of last_close, yesterday_daily_close, first_minute_close and first_minute_open. I wanted to check if the prices are correct. I have also modified one_minute_after_open_market to 5 minutes (instead of 1 minute). Looking at the log results for the date 2017-09-06, I dont understand the following:

1) If the schedule is 5 minutes after market open then first_minute_close/open prices should be at the time of 9:34? As I understand RollingWindow value (self.minute_rw[1].Close and self.minute_rw[1].Open) are with index [1] so it should be one minute prior current. But the log result shows the prices at 9:31 (I am referring not to the time stamp of the log but to the time of the price occurance)

2) the prices are a bit off with my source (tradingview.com) at prices on 9:31am:

first_minute_close -  (tradingview) 162.72; (log) 162.77

I have checked other dates as well and there is always some difference of +-3-5 cents. Is it due to different databases used by both platforms and therefore there can be time discrepencies of setting minute bars?

3) As I understand QC uses pre-market closing prices (not previous trading day's closing price) which is what I need. However, after numerous backtests with different stocks the logs always show me the price of yesterday_daily_close which is two days old. In the backtest attached the result of Pr day close on 09.06 is $164.04. But on the nasdaq website (as per screenshot) this (similar) closing price only occurs on 09.01 $164.05. Shouldn't the closing price be of the date 09.05 $162.08 as self.daily_rw[1].Close is at index [1]? Even If I change it to [0] I get a price of $161.47 which does not even match any closing price at any date.

I apologise if these questions are due to my lack of basic knowledge of programming but I tried researching for answers but there are not many sources that would explain simple concepts in python in QC context. Therefore, this is my last resort (as far as I know) to get my answers so I really appreciate anyones' input and help. Thank you!

0


Arvydas Mickus,

> If the schedule is 5 minutes after market open then first_minute_close/open prices should be at the time of 9:34? 

No, that would be looking-ahead-bias.

Lean is looking-ahead-bias free, that means that in time t you cannot receive data from time t+1. On the other hand the consolidators works with trade bars, and every trade bar has a property CLOSE that is the last traded price in the trade bar. So, assuming the market opens at 9:30:00 and minute resolution, you will receive the first trade bar at 9:31:00, and it’ll be the trade bar for the complete 9:30 minute. Following the same reasoning, five minutes after market open will be at the minute 9:35:00

> The prices are a bit off with my source (tradingview.com) at prices on 9:31am:

That’s common, here is a nice explanation why.

> Shouldn't the closing price be of the date 09.05 $162.08 as self.daily_rw[1].Close is at index [1]? Even If I change it to [0] I get a price of $161.47 which does not even match any closing price at any date.

You are using a RollingWindow, and the last observation is pointed with the index 0. And, using index 0 will give you different values for the reasons mentioned above.

0

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.


JayJayD,

 

Thank you for your help. However I dont understand your first explanation. If I schedule to fire the code 5 minutes after market open and RollingWindow with index 0 then it should get me a trade bar at the minute 9:35:00. If it was index 1 it should get a trade bar at the minute 9:34:00. But now for some reason at index 1 it gets a price from 9:31:00. Why?

0

I have attached my modified code which is applied to my strategy. My strategy is this:

"I want to buy a stock when the current price (checked every sec) is greater than 0,6% from pre-open last market price (not previous day's last trade price). Then, sell it when it is 1,6% greater than pre-open last market price.

Different from Christian's algo I want it to make multiple trades per day: i.e. if the price increase from 0,6% to 1,6% then sell at 1,6% and buy again at the same price (at 1,6% level). Then sell and buy at 2,6%, sell and buy at 3,6% and so on. Basically there would be thresholds at 0,6%, 1,6%, 2,6% etc and if triggered (if last minute bar is positive) then buy/sell trade would occur."

I get this error: 

Runtime Error: Python.Runtime.PythonException: ArgumentOutOfRangeException : Must be between 0 and -1
Parameter name: i
Actual value was 0.
at QuantConnect.Indicators.RollingWindow`1[T].get_Item

This is due row lines 113-115 RollingWindow. I am trying to constantly get yesterday's closing price. So I have selected index 0. I assume its incorrect but index 1 also does not work. I dont understand why in the error log it says "Must be between 0 and -1" which it is in my code (at 0). Thank you for your guidance (for some reason my backtests are not found in order for me to select them and attach in the comment).

#
# QuantConnect Basic Template:
# Fundamentals to using a QuantConnect algorithm.
#
# You can view the QCAlgorithm base class on Github:
# https://github.com/QuantConnect/Lean/tree/master/Algorithm
#

from QuantConnect.Data.Market import TradeBar
from datetime import timedelta
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
import decimal as d


class MyAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2017, 8, 21) # Set Start Date
self.SetEndDate(2017, 9, 13)
self.SetCash(10000) # Set Strategy Cash
self.symbol = self.AddEquity("AAPL", Resolution.Second).Symbol

consolidator_daily = TradeBarConsolidator(timedelta(1))
consolidator_daily.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator(self.symbol, consolidator_daily)

consolidator_minute = TradeBarConsolidator(60)
consolidator_minute.DataConsolidated += self.OnMinuteData
self.SubscriptionManager.AddConsolidator(self.symbol, consolidator_minute)

self.daily_rw = RollingWindow[TradeBar](2)
self.minute_rw = RollingWindow[TradeBar](2)
self.window = RollingWindow[TradeBar](2)

self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.AfterMarketOpen(self.symbol, 5),
Action(self.five_minutes_after_open_market))

self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.BeforeMarketClose(self.symbol, 1),
Action(self.before_close_market))

# Add daily bar to daily rolling window
def OnDailyData(self, sender, bar):
self.daily_rw.Add(bar)

def OnMinuteData(self, sender, bar):
self.minute_rw.Add(bar)

def five_minutes_after_open_market(self):

if not (self.window.IsReady and self.daily_rw.IsReady and self.minute_rw.IsReady): return
last_close = self.window[0].Close
#self.Log(last_close)
yesterday_daily_close = self.daily_rw[0].Close
last_minute_close = self.minute_rw[0].Close
last_minute_open = self.minute_rw[0].Open
curr_price = self.Securities(symbol)

gap = (last_close - yesterday_daily_close)/yesterday_daily_close*100
last_minute_bar = last_minute_close - last_minute_open
stop_price06 = yesterday_daily_close*d.Decimal(0.6)
stop_price12 = yesterday_daily_close*d.Decimal(1.2)
stop_price18 = yesterday_daily_close*d.Decimal(1.8)
stop_price24 = yesterday_daily_close*d.Decimal(2.4)
stop_price30 = yesterday_daily_close*d.Decimal(3.0)
stop_price36 = yesterday_daily_close*d.Decimal(3.6)
stop_price42 = yesterday_daily_close*d.Decimal(4.2)
stop_price48 = yesterday_daily_close*d.Decimal(4.8)


if not self.Portfolio[self.symbol].Invested:

if last_close < stop_price06 and last_minute_bar > 0:
self.StopMarketOrder(self.symbol, 60, stop_price06)
self.Log('GOING LONG @ 0.6')
self.Log('Last bar close: {0}'.format(last_close))
self.Log('Pr day close: {0}'.format(yesterday_daily_close))
self.Log('Last min close: {0}'.format(last_minute_close))
self.Log('Last min open: {0}'.format(last_minute_open))

elif last_close < stop_price12 and last_minute_bar > 0:
self.StopMarketOrder(self.symbol, 60, stop_price12)
self.Log('GOING LONG @ 1.2')
#self.SetHoldings(self.symbol, -1)
#self.Log('GOING SHORT')
elif last_close < stop_price18 and last_minute_bar > 0:
self.StopMarketOrder(self.symbol, 60, stop_price18)
self.Log('GOING LONG @ 1.8')

def before_close_market(self):
"""
At the end of the day, if there is a short position, close it.
"""
if self.Portfolio[self.symbol].IsShort:
self.Liquidate(self.symbol)
self.Log('LIQUIDATE SHORT End of Day')

# Add second bar to window rolling window
def OnData(self, data):
if data[self.symbol] is None:
return
self.window.Add(data[self.symbol])
if not (self.window.IsReady):
return
# self.Log("haha")
factor = d.Decimal(1.006)

currBar = self.window[0].High
curr_price = data[self.symbol]
last_minute_close = self.minute_rw[0].Close
last_minute_open = self.minute_rw[0].Open
yesterday_daily_close = self.daily_rw[0].Close
last_minute_bar = last_minute_close - last_minute_open
stop_price06 = yesterday_daily_close*d.Decimal(0.6)
stop_price12 = yesterday_daily_close*d.Decimal(1.2)
stop_price18 = yesterday_daily_close*d.Decimal(1.8)
stop_price24 = yesterday_daily_close*d.Decimal(2.4)
stop_price30 = yesterday_daily_close*d.Decimal(3.0)
stop_price36 = yesterday_daily_close*d.Decimal(3.6)
stop_price42 = yesterday_daily_close*d.Decimal(4.2)
stop_price48 = yesterday_daily_close*d.Decimal(4.8)

if not self.Portfolio[self.symbol].Invested:
if curr_price == stop_price06 and last_minute_bar > 0:
self.SetHoldings(self.symbol, 1)
self.Log('GOING LONG @ 0.6')
elif curr_price == stop_price12 and last_minute_bar > 0:
self.SetHoldings(self.symbol, 1)
self.Log('GOING LONG @ 1.2')
elif curr_price == stop_price18 and last_minute_bar > 0:
self.SetHoldings(self.symbol, 1)
self.Log('GOING LONG @ 1.8')

# Every second, check the price and if it's higher than the price the stock was bought for times 1.006, close the position.
if self.Portfolio[self.symbol].Invested and self.Portfolio[self.symbol].AveragePrice * factor <= curr_price:
self.Liquidate(self.symbol)
self.Log('LIQUIDATE AT THRESHOLD REACHED.')
0

Here in Argentina we have a saying the cow is eaten steak by steak; and you are trying to eat the cow at once. You’re trying hard but in the wrong direction.

So, take my advice. First, RTFM. Then, learn how every single piece (consolidators, event handlers, indicators, schedules, etc.) works by its own using just simple examples with low resolution (daily, hourly).

Maybe I seems a little cranky but if I write the code and give it to you I’m no helping you at all.

Finally, respect to the error in the RollingWindow index, Alexandre Catarino is the right person to ask.

Good luck.

2

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.


The runtime error related with the RollingWindow is due to accessing a window that is not ready. 
If we do not set a warm up period (self.SetWarmup in Initialize), it is good practice to check whether all indicators are ready:

if not (self.window.IsReady and self.minute_rw.IsReady and self.daily_rw.IsReady):
return

There were other bugs in the code.
You were using symbol instead of self.symbol and accessing the dictionary as if it were a method:

curr_price = self.Securities(symbol) # Wrong
curr_price = self.Securities[self.symbol].Price # Right


 

0

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.


Thank you JayJayD and Alexandre Catarino for your helpful input!

0

Update Backtest





0

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.


Loading...

This discussion is closed