Hi!
I'm using the following code to detect the intraday High of Day.
But it seems that so many times it gets updated with a delay compared to the current price...
For instance if you take a look at logs:
2021-03-25 14:50:00 :Current AIG price 46.24002021-03-25 14:50:00 :Current HOD AIG price 46.1500Why don't we have the current HOD AIG price as 46.24, just as current AIG price?
Derek Melchin
Hi Emiliano Fraticelli,
The algorithm above subscribes to minute-resolution data for the securities, but subscribes the `_identity_x` indicators to use daily data. As a result, when we call
_identity_spy.Current.Value
intraday, the value corresponds to the HOD from the previous trading day.
To get the HOD price of the current day, we can:
#1 Create a class member
_spy_max = 0.0M;
#2 Update the class member with each minute bar that's passed to OnData
_spy_max = Math.Max(_spy_max, data["SPY"].High);
#3 Reset the class member at the end of each day
public override void OnEndOfDay() { _spy_max = 0.0M; }
See the attached backtest for reference
Best,
Derek Melchin
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.
Emiliano Fraticelli
Thank you Derek...
I implemented a solution by myself already that seems similar to one of the yours
using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data.Fundamental; using QuantConnect.Data.UniverseSelection; using QuantConnect.Securities; using static System.DateTime; using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data; using QuantConnect.Data.Custom; using QuantConnect.Data.Market; using QuantConnect.Indicators; using QuantConnect.Securities.Equity; using QuantConnect.Interfaces; namespace QuantConnect { /// <summary> /// Basic template algorithm simply initializes the date range and cash /// </summary> public class DailyIdentityAlgorithm : QCAlgorithm { private decimal highOfTheDaySpy=0; private decimal highOfTheDayAIG=0; ////////////////////////////////////// SPY VARIABLES ////////////////////////////////////////////////// private Symbol _spy = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA); private SimpleMovingAverage _sma_spy; private Identity _identity_spy; ////////////////////////////////////// AIG VARIABLES ////////////////////////////////////////////////// private Symbol _aig = QuantConnect.Symbol.Create("AIG", SecurityType.Equity, Market.USA); private SimpleMovingAverage _sma_aig; private Identity _identity_aig; ////////////////////////////////////// BTX VARIABLES ////////////////////////////////////////////////// private Symbol _btx = QuantConnect.Symbol.Create("BTX", SecurityType.Equity, Market.USA); private SimpleMovingAverage _sma_btx; private Identity _identity_btx; /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2021, 03 ,24); //Set Start Date SetEndDate(2021, 08, 27); //Set End Date SetCash(Convert.ToDouble(GetParameter("cash"))); //Set Strategy Cash double cash = Convert.ToDouble(GetParameter("cash")); double perActionFunds= Convert.ToDouble(GetParameter("per action fund")); //////////////////////// Manual Universe Selection /////////////////////////////////////////////////////////////// ////////////////////////////////////// SPY VARIABLES INITIALIZAZTION ////////////////////////////////////////////////// AddEquity("SPY", Resolution.Minute); _sma_spy = SMA("SPY", 60, Resolution.Daily, x => ((TradeBar)x).Volume); _identity_spy = Identity("SPY", Resolution.Daily, Field.High); ////////////////////////////////////// AIG VARIABLES INITIALIZAZTION ////////////////////////////////////////////////// AddEquity("AIG", Resolution.Minute); _sma_aig = SMA("AIG", 60, Resolution.Daily, x => ((TradeBar)x).Volume); _identity_aig = Identity("AIG", Resolution.Daily, Field.High); ////////////////////////////////////// BTX VARIABLES INITIALIZAZTION ////////////////////////////////////////////////// AddEquity("BTX", Resolution.Minute); _sma_btx = SMA("BTX", 60, Resolution.Daily, x => ((TradeBar)x).Volume); _identity_btx = Identity("BTX", Resolution.Daily, Field.High); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // schedule an event to fire every trading day for a security // the time rule here tells it to fire 10 minutes before SPY's market close bool liquidate = Convert.ToBoolean(GetParameter("liquidate")); if (liquidate = true){ Schedule.On(DateRules.EveryDay("SPY"), TimeRules.BeforeMarketClose("SPY", 10), () => //Don't have to change it for every instrument in the portfolio { Liquidate();//Liquidate entire portfolio }); } // schedule an event to fire every trading day for a security // the time rule here tells it to fire 10 minutes after SPY's market open Schedule.On(DateRules.EveryDay("SPY"), TimeRules.At(23, 59), () => { highOfTheDaySpy=0; highOfTheDayAIG=0; }); } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { TradeBars bars = data.Bars; ////// JUST FOR SPY VOLUME /////////////////////////////////// //Debug("60d volume "+_sma_spy.Current.Value); //Debug("Current Volume "+bars["SPY"].Volume); /////////////////////////////////////////////////// if (data.ContainsKey("SPY")){ if (bars["SPY"].Price > highOfTheDaySpy){ highOfTheDaySpy = bars["SPY"].Price; Debug("we have a new intraday HOD here !!"); Debug("Current SPY price "+bars["SPY"].Price); Debug("Current HOD SPY price " + highOfTheDaySpy); } } if (data.ContainsKey("AIG")){ if (bars["AIG"].Price > highOfTheDayAIG){ highOfTheDayAIG = bars["AIG"].Price; Debug("we have a new intraday HOD here !!"); Debug("Current AIG price "+bars["AIG"].Price); Debug("Current HOD AIG price " + highOfTheDayAIG); } } /* if (data.ContainsKey("SPY") && bars["SPY"].Price > _identity_spy.Current.Value && _identity_spy.IsReady){ Debug("Current SPY price "+bars["SPY"].Price); Debug("Current HOD SPY price "+_identity_spy.Current.Value); //SetHoldings("SPY",0.1); } if (data.ContainsKey("AIG") && bars["AIG"].Price > _identity_aig.Current.Value && _identity_aig.IsReady){ Debug("Current AIG price "+bars["AIG"].Price); Debug("Current HOD AIG price "+_identity_aig.Current.Value); //SetHoldings("AIG",0.1); } if (data.ContainsKey("BTX") && bars["BTX"].Price > _identity_btx.Current.Value && _identity_btx.IsReady){ Debug("Current BTX price "+bars["BTX"].Price); Debug("Current HOD BTX price "+_identity_btx.Current.Value); //SetHoldings("BTX",0.1); } */ }//closes OnData } }
Emiliano Fraticelli
But will consider yours, too. Thanks!
Derek Melchin
Hi Emiliano Fraticelli,
Yes, the algorithm above is similar to this one. But to get the true HOD price, we should replace
if (bars["SPY"].Price > highOfTheDaySpy){ highOfTheDaySpy = bars["SPY"].Price;
with
if (bars["SPY"].High > highOfTheDaySpy){ highOfTheDaySpy = bars["SPY"].High;
Best,
Derek Melchin
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.
Emiliano Fraticelli
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!