Overall Statistics |
Total Trades 423 Average Win 0.35% Average Loss -0.26% Compounding Annual Return -31.743% Drawdown 20.600% Expectancy -0.058 Net Profit -6.835% Sharpe Ratio -0.714 Loss Rate 60% Win Rate 40% Profit-Loss Ratio 1.34 Alpha -0.161 Beta 0.185 Annual Standard Deviation 0.221 Annual Variance 0.049 Information Ratio -0.738 Tracking Error 0.237 Treynor Ratio -0.852 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Market; using QuantConnect.Indicators; namespace QuantConnect.Algorithm.Examples { public class MultipleSymbolConsolidationAlgorithm : QCAlgorithm { public readonly TimeSpan BarPeriod = TimeSpan.FromHours(1); public readonly int RollingWindowSize = 20; public readonly Dictionary<string, SymbolData> _data = new Dictionary<string, SymbolData>(); decimal _delta; /*public readonly IReadOnlyList<string> EquitySymbols = new List<string> { "AAPL", "SPY", "IBM" };*/ public readonly IReadOnlyList<string> ForexSymbols = new List<string> { "EURUSD", //"USDJPY", "EURGBP", "EURCHF", "USDCAD", "USDCHF", "AUDUSD", "NZDUSD", }; public override void Initialize() { SetStartDate(2014, 12, 01); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(1000); // initialize our equity data /*foreach (var symbol in EquitySymbols) { _data.Add(symbol, new SymbolData(symbol, SecurityType.Equity, BarPeriod, RollingWindowSize)); }*/ // initialize our forex data foreach (var symbol in ForexSymbols) { _data.Add(symbol, new SymbolData(symbol, SecurityType.Forex, BarPeriod, RollingWindowSize)); } // loop through all our symbols and request data subscriptions and initialize indicatora foreach (var kvp in _data) { // this is required since we're using closures below, for more information // see: http://stackoverflow.com/questions/14907987/access-to-foreach-variable-in-closure-warning var symbolData = kvp.Value; // request data subscription AddSecurity(symbolData.SecurityType, symbolData.Symbol, Resolution.Minute); // define a consolidator to consolidate data for this symbol on the requested period var consolidator = new TradeBarConsolidator(BarPeriod); // define our indicator symbolData._sma1 = new SimpleMovingAverage(symbolData.Symbol + 10, 10); symbolData._sma2 = new SimpleMovingAverage(symbolData.Symbol + 20, 20); symbolData._slow = new SimpleMovingAverage(symbolData.Symbol + 5, 5); // wire up our consolidator to update the indicator consolidator.DataConsolidated += (sender, bar) => { // 'bar' here is our newly consolidated data symbolData._sma1.Update(bar.Time, bar.Close); symbolData._sma2.Update(bar.Time, bar.Close); symbolData._slow.Update(bar.Time, (symbolData._sma1 - symbolData._sma2)); // we're also going to add this bar to our rolling window so we have access to it later symbolData.Bars.Add(bar); }; // we need to add this consolidator so it gets auto updates SubscriptionManager.AddConsolidator(symbolData.Symbol, consolidator); } } public void OnData(TradeBars data) { foreach (var symbolData in _data.Values) { // this check proves that this symbol was JUST updated prior to this OnData function being called if (symbolData.IsReady && symbolData.WasJustUpdated(data.Time)) { _delta = symbolData._sma1 - symbolData._sma2; if (Portfolio[symbolData.Symbol].Invested && _delta < symbolData._slow) { Liquidate(symbolData.Symbol); } if (!Portfolio[symbolData.Symbol].Invested && _delta > symbolData._slow) { MarketOrder(symbolData.Symbol, 1000); } } } } /*public override void OnEndOfDay() { int i = 0; foreach (var kvp in _data.OrderBy(x => x.Value.Symbol)) { // we have too many symbols to plot them all, so plot ever other if (kvp.Value.IsReady && ++i%2 == 0) { Plot(kvp.Value.Symbol, kvp.Value._sma1); } } }*/ public class SymbolData { public readonly string Symbol; public readonly SecurityType SecurityType; public readonly RollingWindow<TradeBar> Bars; public readonly TimeSpan BarPeriod; public SimpleMovingAverage _sma1; public SimpleMovingAverage _sma2; public SimpleMovingAverage _slow; public SymbolData(string symbol, SecurityType securityType, TimeSpan barPeriod, int windowSize) { Symbol = symbol; SecurityType = securityType; BarPeriod = barPeriod; Bars = new RollingWindow<TradeBar>(windowSize); } public bool IsReady { get { return Bars.IsReady && _sma1.IsReady && _sma2.IsReady && _slow.IsReady ;} } public bool WasJustUpdated(DateTime current) { return Bars.Count > 0 && Bars[0].Time == current - BarPeriod; } } } }