| Overall Statistics |
|
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 15.566% Drawdown 9.600% Expectancy 0 Net Profit 0% Sharpe Ratio 1.257 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.016 Beta 0.984 Annual Standard Deviation 0.12 Annual Variance 0.014 Information Ratio 0.886 Tracking Error 0.016 Treynor Ratio 0.153 Total Fees $2.55 |
namespace QuantConnect
{
public class MultiTimeFrameRollingWindowIndicatorAlgorithm : QCAlgorithm
{
private int _period = 30;
private Dictionary<int, RollingWindow<IndicatorSuiteState>> _window = new Dictionary<int, RollingWindow<IndicatorSuiteState>>();
public override void Initialize()
{
SetStartDate(2016, 1, 1);
AddEquity("SPY", Resolution.Minute);
foreach (var minute in new int[] { 5, 10, 15, 20, 30 })
{
// Create Consolidator
var consolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(minute));
// Create indicators
var suite = new IndicatorSuite(minute.ToString(), 14, 14, 10, 20);
// Add new rolling window to the _window dictionary
_window.Add(minute, new RollingWindow<IndicatorSuiteState>(_period));
// Register indicators to the consolidator to be updated at its frequency
RegisterIndicator("SPY", suite, consolidator);
// Updates the rolling window using an anonymous method
consolidator.DataConsolidated += (s, bar) =>
{
if (!suite.IsReady) return;
// Uses a wrapper to save only the state of the indicator suite
_window[bar.Period.Minutes].Add(new IndicatorSuiteState(suite));
};
// Add the consolidator to the subscription manager to get updated with data from security
SubscriptionManager.AddConsolidator("SPY", consolidator);
}
}
public override void OnData(Slice data)
{
if (!Portfolio.HoldStock) SetHoldings("SPY", 1);
}
// At end of day, plot the indicators for visual sanity check
public override void OnEndOfDay()
{
if (!_window[30].IsReady) return;
// Last IndicatorSuite (index 0) of the 30 min consolidator
var suite = _window[30][0];
Plot("Indicators", "ADX", suite.ADX.Current);
Plot("Indicators", "RSI", suite.RSI.Current);
Plot("Indicators", "Fast SMA", suite.FastSMA.Current);
Plot("Indicators", "Slow SMA", suite.SlowSMA.Current);
}
}
public class IndicatorSuite : BarIndicator
{
public AverageDirectionalIndex ADX;
public RelativeStrengthIndex RSI;
public SimpleMovingAverage FastSMA;
public SimpleMovingAverage SlowSMA;
public override bool IsReady { get { return ADX.IsReady && RSI.IsReady && FastSMA.IsReady && SlowSMA.IsReady; } }
public IndicatorSuite(string name, int adxPeriod, int rsiPeriod, int fastSmaPeriod, int slowSmaPeriod)
: base(name)
{
ADX = new AverageDirectionalIndex("", adxPeriod);
RSI = new RelativeStrengthIndex(rsiPeriod);
FastSMA = new SimpleMovingAverage(fastSmaPeriod);
SlowSMA = new SimpleMovingAverage(slowSmaPeriod);
}
protected override decimal ComputeNextValue(IBaseDataBar input)
{
ADX.Update(input);
RSI.Update(input.EndTime, input.Value);
FastSMA.Update(input.EndTime, input.Value);
SlowSMA.Update(input.EndTime, input.Value);
return 0;
}
}
public class IndicatorSuiteState
{
public AverageDirectionalIndexState ADX;
public RelativeStrengthIndexState RSI;
public SimpleMovingAverageState FastSMA;
public SimpleMovingAverageState SlowSMA;
public IndicatorSuiteState(IndicatorSuite suite)
{
ADX = new AverageDirectionalIndexState(suite.ADX);
RSI = new RelativeStrengthIndexState(suite.RSI);
FastSMA = new SimpleMovingAverageState(suite.FastSMA);
SlowSMA = new SimpleMovingAverageState(suite.SlowSMA);
}
public class AverageDirectionalIndexState
{
public readonly string Name;
public readonly IndicatorDataPoint Current;
public readonly IndicatorBase<IndicatorDataPoint> NegativeDirectionalIndex;
public readonly IndicatorBase<IndicatorDataPoint> PositiveDirectionalIndex;
public AverageDirectionalIndexState(AverageDirectionalIndex adx)
{
Name = adx.Name;
Current = adx.Current;
NegativeDirectionalIndex = adx.NegativeDirectionalIndex;
PositiveDirectionalIndex = adx.PositiveDirectionalIndex;
}
public override string ToString()
{
return Name + ":" + Current;
}
}
public class RelativeStrengthIndexState
{
public readonly string Name;
public readonly IndicatorDataPoint Current;
public RelativeStrengthIndexState(RelativeStrengthIndex rsi)
{
Name = rsi.Name;
Current = rsi.Current;
}
public override string ToString()
{
return Name + ":" + Current;
}
}
public class SimpleMovingAverageState
{
public readonly string Name;
public readonly IndicatorDataPoint Current;
public SimpleMovingAverageState(SimpleMovingAverage sma)
{
Name = sma.Name;
Current = sma.Current;
}
public override string ToString()
{
return Name + ":" + Current;
}
}
}
}