Overall Statistics |
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 16.001% Drawdown 7.200% Expectancy 0 Net Profit 0% Sharpe Ratio 1.39 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.165 Beta -0.063 Annual Standard Deviation 0.111 Annual Variance 0.012 Information Ratio -0.097 Tracking Error 0.163 Treynor Ratio -2.464 Total Fees $1.00 |
namespace QuantConnect { /* * Keltner Channel indicator demostration * * * */ public class volatility : QCAlgorithm { ///Initialise the keltner channels KeltnerChannels KC; string _symbol = "SPY"; //Initialize the data and resolution you require for your strategy: public override void Initialize() { //Start and End Date range for the backtest: SetStartDate(2013, 1, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(25000); ///Set keltner channel variables KC = new KeltnerChannels(14, 1.5m); //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Equity, _symbol, Resolution.Daily); //Register kelter channels for updates RegisterIndicator(_symbol, KC, Resolution.Daily); } //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol. public void OnData(TradeBars data) { ///check if indicator is ready if(!KC.IsReady) return; ///Simple volatility entry var holdings = Portfolio[_symbol].Quantity; var trigger = data[_symbol].High > KC.UpperBand ? true : false; if (holdings==0 && trigger) { SetHoldings(_symbol, 1); } ///plot Plot("Keltner Channels",_symbol, Securities[_symbol].Price); Plot("Keltner Channels","Upper Band", KC.UpperBand); Plot("Keltner Channels","Lower Band", KC.LowerBand); } } }
namespace QuantConnect.Indicators { /// <summary> /// This indicator creates a moving average (middle band) with an upper band and lower band /// fixed at k average true range away from the middle band /// </summary> public class KeltnerChannels : TradeBarIndicator { /// Set up of variables private IndicatorBase<IndicatorDataPoint> _MiddleBand; private IndicatorBase<TradeBar> _UpperBand; private IndicatorBase<TradeBar> _LowerBand; private IndicatorBase<TradeBar> _ATR; /// <summary> /// Initializes a new instance of the KeltnerChannels class /// </summary> /// <param name="period">The period of the average true range and moving average (middle band)</param> /// <param name="k">The number of multiplies specifying the distance between the middle band and upper or lower bands</param> /// <param name="movingAverageType">The type of moving average to be used</param> public KeltnerChannels(int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple) : this(string.Format("KC({0},{1})", period, k), period, k, movingAverageType) { } /// <summary> /// Initializes a new instance of the KeltnerChannels class /// </summary> /// <param name="name">The name of this indicator</param> /// <param name="period">The period of the average true range and moving average (middle band)</param> /// <param name="k">The number of multiples specifying the distance between the middle band and upper or lower bands</param> /// <param name="movingAverageType">The type of moving average to be used</param> public KeltnerChannels(string name, int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple) : base(name) { ///Initialise ATR and SMA _ATR = new AverageTrueRange(name + "_AverageTrueRange", period, movingAverageType); _MiddleBand = new SimpleMovingAverage(name + "_SimpleMovingAverage", period); ///Compute Lower Band _LowerBand = new FunctionalIndicator<TradeBar>(name + "_LowerBand", input => ComputeLowerBand(k, period, input), fastStoch => _MiddleBand.IsReady, () => _MiddleBand.Reset() ); ///Compute Upper Band _UpperBand = new FunctionalIndicator<TradeBar>(name + "_UpperBand", input => ComputeUpperBand(k, period, input), fastStoch => _MiddleBand.IsReady, () => _MiddleBand.Reset() ); } /// <summary> /// calculates the lower band /// </summary> private decimal ComputeLowerBand(decimal k, int period, TradeBar input) { var lowerBand = _MiddleBand.Samples >= period ? _MiddleBand - Decimal.Multiply(_ATR,k): new decimal(0.0); return lowerBand; } /// <summary> /// calculates the upper band /// </summary> private decimal ComputeUpperBand(decimal k, int period, TradeBar input) { var upperBand = _MiddleBand.Samples >= period ? _MiddleBand + Decimal.Multiply(_ATR,k): new decimal(0.0); return upperBand; } /// <summary> /// Gets a flag indicating when this indicator is ready and fully initialized /// </summary> public override bool IsReady { get { return _MiddleBand.IsReady && _UpperBand.IsReady && _LowerBand.IsReady; } } /// <summary> /// Returns the Upper band of the kelter channel /// </summary> public decimal UpperBand { get { return _UpperBand;} } /// <summary> /// Returns the Lower band of the kelter channel /// </summary> public decimal LowerBand { get { return _LowerBand;} } /// <summary> /// Returns the Middle band of the kelter channel /// </summary> public decimal MiddleBand { get { return _MiddleBand;} } /// <summary> /// Returns the average true range value of the Keltner Channels /// </summary> public decimal TrueRangeAverage { get { return _ATR;} } /// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="input">The TradeBar to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(TradeBar input) { _ATR.Update(input); _MiddleBand.Update(input.Time, input.Close); _LowerBand.Update(input); _UpperBand.Update(input); return _MiddleBand; } public override void Reset() { _ATR.Reset(); _MiddleBand.Reset(); _UpperBand.Reset(); _LowerBand.Reset(); base.Reset(); } } }