I have a need to keep a history (rolling window) of X number of past indicator values. In the simple code below, I'm trying to keep the past 180 fifteen minute periods of a bollinger band by storing them in a RollingWindow just as I do with the consolidated TradeBars. Unfortunately, it is not working and all elements of the the _bbwindow data structure end up being the same, presumably because upon calling the _bbwindow.Add() function to store the bollinger band, it is probably storing a pointer to the bollinger band object. Can someone help explain what the preferred method of storing historical values of indicators are?
Thanks so much!!
using System;
using System.Collections.Generic;
using QuantConnect.Data.Consolidators;
using QuantConnect.Indicators;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm
{
public class ForexBollinger : QCAlgorithm
{
BollingerBands _bb;
//Use our new consolidator class - 15 minutes / 15 bars joined.
decimal _price;
decimal stopPrice;
string symbol = "EURUSD";
static int Hist = 180;
static int Inputs = 4;
RollingWindow
RollingWindow
public override void Initialize()
{
SetStartDate(2014, 5, 1);
SetEndDate(2015,6,4);
SetCash(200000);
AddSecurity(SecurityType.Forex, symbol, Resolution.Minute);
_bb = new BollingerBands(20, 2, MovingAverageType.Simple);
var fifteenConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(15));
fifteenConsolidator.DataConsolidated += OnDataFifteen;
SubscriptionManager.AddConsolidator(symbol,fifteenConsolidator);
RegisterIndicator(symbol, _bb, fifteenConsolidator, x => x.Value);
}
public void OnData(TradeBars data)
{
if (!_bb.IsReady) return;
if (!Portfolio.HoldStock)
{
Order("EURUSD", 1000);
Debug("Purchased EURUSD on " + Time.ToShortDateString());
}
foreach(string symbol in Securities.Keys){
if (Securities [symbol].Holdings.IsLong) {
if (data[symbol].Close <= stopPrice) {
Liquidate(symbol);
Debug ("Hit StopLoss: " + data[symbol].Close);
}
}
if (Securities [symbol].Holdings.IsShort) {
if (data[symbol].Close >= stopPrice) {
Liquidate(symbol);
Debug ("Hit StopLoss: " + data[symbol].Close);
}
}
}
}
private void OnDataFifteen(object sender,TradeBar consolidated)
{
_price = consolidated.Close;
if (!_bb.IsReady) return;
_datawindow.Add(consolidated);
// **** _bbwindow does not really keep a history of the Bollingerbands!!
_bbwindow.Add (_bb);
if (!_datawindow.IsReady) return;
if (!_bbwindow.IsReady) return;
Plot("BB", "Price", _price);
Plot("BB", _bb.UpperBand, _bb.MiddleBand, _bb.LowerBand);
}
// Fire plotting events once per day:
public override void OnEndOfDay()
{
//Log("EndOfDay");
}
}
}
Jared Broad
decimal x = _bb + _bb2; RollingWindow _bbwindow = new RollingWindow(Hist);
The by making the rolling window use decimal type, you're triggering the operator overload to return a decimal value for the BB value which will be stored permanently as a value-type (instead of reference type like a class). The UpperBand/LowerBand properties are sub-indicators, so they have the same class-operator-overload behavior. You should probably save these to the rolling window, I think the middle BB band is just the SMA.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.
Michael Handschuh
Gene Wildhart
Dan Hill
Hey @MichaelH
Has something changed with the method?
I noticed that this example now thows an error:
Backtest Error: Error initializing algorithm: This may be because history is using fake data while pre-analyzing an algorithm for a backtest
Backtest Error: Error initializing algorithm: Type mismatch found between consolidator and symbol. Symbol: EURUSD expects type QuoteBar but tried to register consolidator with input type TradeBar
Alexandre Catarino
Since a forex bar is now QuoteBar (they include Bid/Ask information).
We need to update the code above accordingly:
// Declare RollingWindow of type QuoteBar instead of TradeBar RollingWindow<QuoteBar> _datawindow = new RollingWindow<QuoteBar>(Hist);
In Initialize, we change the consolidator:
var fifteenConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(15));
Finally, we need to change the type of the event handler:
private void OnDataFifteen(object sender, QuoteBar consolidated) { // }
Please checkout the attached project with all the changes.
Gene Wildhart
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!