Overall Statistics |
Total Trades 8 Average Win 25.41% Average Loss -1.83% Compounding Annual Return 29.549% Drawdown 16.300% Expectancy 12.047 Net Profit 366.278% Sharpe Ratio 1.209 Loss Rate 12% Win Rate 88% Profit-Loss Ratio 13.91 Alpha 0.128 Beta 0.91 Annual Standard Deviation 0.235 Annual Variance 0.055 Information Ratio 0.661 Tracking Error 0.17 Treynor Ratio 0.313 |
-no value-
/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Indicators; using QuantConnect.Models; namespace QuantConnect.Algorithm.Examples { /// <summary> /// Constructs a displaced moving average ribbon and buys when all are lined up, liquidates when they all line down /// Ribbons are great for visualizing trends /// Signals are generated when they all line up in a paricular direction /// A buy signal is when the values of the indicators are increasing (from slowest to fastest) /// A sell signal is when the values of the indicators are decreasing (from slowest to fastest) /// </summary> public class DisplacedMovingAverageRibbon : QCAlgorithm { private const string Symbol = "SPY"; private Indicator[] ribbon; public override void Initialize() { SetStartDate(2009, 01, 01); SetEndDate(2015, 01, 01); AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute); int count = 6; int offset = 5; int period = 15; // define our sma as the base of the ribbon var sma = new SimpleMovingAverage(period); ribbon = Enumerable.Range(0, count).Select(x => { // define our offset to the zero sma, these various offsets will create our 'displaced' ribbon var delay = new Delay(offset*(x+1)); // define an indicator that takes the output of the sma and pipes it into our delay indicator var delayedSma = delay.Of(sma); // register our new 'delayedSma' for automaic updates on a daily resolution RegisterIndicator(Symbol, delayedSma, Resolution.Daily, data => data.Value); return delayedSma; }).ToArray(); } private DateTime previous; public void OnData(TradeBars data) { // wait for our entire ribbon to be ready if (!ribbon.All(x => x.IsReady)) return; // only once per day if (previous.Date == data.Time.Date) return; Plot(Symbol, "Price", data[Symbol].Price); Plot(Symbol, ribbon); // check for a buy signal var values = ribbon.Select(x => x.Value.Data).ToArray(); var holding = Portfolio[Symbol]; if (holding.Quantity <= 0 && IsAscending(values)) { SetHoldings(Symbol, 1.0); } else if (holding.Quantity > 0 && IsDescending(values)) { Liquidate(Symbol); } previous = data.Time; } /// <summary> /// Returns true if the specified values are in ascending order /// </summary> private bool IsAscending(IEnumerable<decimal> values) { decimal? last = null; foreach (var val in values) { if (last == null) { last = val; continue; } if (last.Value < val) { return false; } last = val; } return true; } /// <summary> /// Returns true if the specified values are in descending order /// </summary> private bool IsDescending(IEnumerable<decimal> values) { decimal? last = null; foreach (var val in values) { if (last == null) { last = val; continue; } if (last.Value > val) { return false; } last = val; } return true; } } }
/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace QuantConnect.Indicators { /// <summary> /// This indicator is capable of wiring up two separate indicators into a single indicator /// such that data will be pumped into the First, and the output of the First will be pumped /// into the Second, after the First IsReady /// </summary> public class SequentialIndicator : Indicator { /// <summary> /// Gets the first indicator to receive data /// </summary> public Indicator First { get; private set; } /// <summary> /// Gets the second indicator that receives the output from the first as its input data /// </summary> public Indicator Second { get; private set; } /// <summary> /// Gets a flag indicating when this indicator is ready and fully initialized /// </summary> public override bool IsReady { get { return Second.IsReady && First.IsReady; } } /// <summary> /// Creates a new SequentialIndicator that will pipe the output of the first into the second /// </summary> /// <param name="name">The name of this indicator</param> /// <param name="first">The first indicator to receive data</param> /// <param name="second">The indicator to receive the first's output data</param> public SequentialIndicator(string name, Indicator first, Indicator second) : base(name) { First = first; Second = second; } /// <summary> /// Creates a new SequentialIndicator that will pipe the output of the first into the second /// </summary> /// <param name="first">The first indicator to receive data</param> /// <param name="second">The indicator to receive the first's output data</param> public SequentialIndicator(Indicator first, Indicator second) : base(string.Format("SEQUENTIAL({0}->{1})", first.Name, second.Name)) { First = first; Second = second; } /// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="previousValue">The most recent value of this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IndicatorDataPoint previousValue, IndicatorDataPoint input) { First.Update(input); if (!First.IsReady) { // if the first isn't ready just send out a default value return 0m; } Second.Update(First.Value); return Second.Value.Data; } } }
/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace QuantConnect.Indicators { /// <summary> /// An indicator that delays its input for a certain period /// </summary> public class Delay : WindowIndicator { /// <summary> /// Creates a new Delay indicator that delays its input by the specified period /// </summary> /// <param name="period">The period to delay input, must be greater than zero</param> public Delay(int period) : this("DELAY" + period, period) { } /// <summary> /// Creates a new Delay indicator that delays its input by the specified period /// </summary> /// <param name="period">The period to delay input, must be greater than zero</param> public Delay(string name, int period) : base(name, period) { } /// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="previousValue">The previous value of this indicator</param> /// <param name="input">The input value to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint previousValue, IndicatorDataPoint input) { if (!window.IsReady) { // grab the initial value until we're ready return window[window.Count - 1]; } return window.MostRecentlyRemoved; } } }
/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace QuantConnect.Indicators { /// <summary> /// Provides extension methods for Indicator /// </summary> public static class IndicatorExtensions { /// <summary> /// Creates a new SequentialIndicator such that data from 'first' is piped into 'second' /// </summary> /// <param name="second">The indicator that wraps the first</param> /// <param name="first">The indicator to be wrapped</param> /// <returns>A new SequentialIndicator that pipes data from first to second</returns> public static SequentialIndicator Of(this Indicator second, Indicator first) { return new SequentialIndicator(first, second); } /// <summary> /// Creates a new SequentialIndicator such that data from 'first' is piped into 'second' /// </summary> /// <param name="second">The indicator that wraps the first</param> /// <param name="first">The indicator to be wrapped</param> /// <param name="name">The name of the new indicator</param> /// <returns>A new SequentialIndicator that pipes data from first to second</returns> public static SequentialIndicator Of(this Indicator second, Indicator first, string name) { return new SequentialIndicator(first, second); } } }