Overall Statistics |
Total Trades 28 Average Win 4.43% Average Loss -1.34% Compounding Annual Return 54.647% Drawdown 12.000% Expectancy 1.304 Net Profit 54.174% Sharpe Ratio 1.727 Loss Rate 46% Win Rate 54% Profit-Loss Ratio 3.30 Alpha 0.376 Beta 0.122 Annual Standard Deviation 0.223 Annual Variance 0.05 Information Ratio 1.285 Tracking Error 0.242 Treynor Ratio 3.149 Total Fees $1012.21 |
using System; using System.Linq; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { public partial class SwingTraderPro : QCAlgorithm { //Initialize: Storage for our custom data: //Source: http://www.wunderground.com/history/ //Make sure to link to the actual file download URL if using dropbox. //private string url = "https://www.dropbox.com/s/txgqzv2vp5lzpqc/10065.csv"; private Signal yesterday; private int rebalanceFrequency = 1, tradingDayCount = 0; private const string Symbol = "USO"; decimal leverage = 1m; private SimpleMovingAverage sma; private SimpleMovingAverage smanow; private SimpleMovingAverage[] ribbon; ///<summary> /// Initialize our algorithm: ///</summary> public override void Initialize() { SetStartDate(2014,7, 01); SetEndDate(2015, 6, 30); SetCash(100000); AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute, false, leverage, false); SetRunMode(RunMode.Series); AddData<Signal>("SignalStregth", Resolution.Minute); // create a 15 day exponential moving average sma = SMA(Symbol, 5, Resolution.Daily); // create a 30 day exponential moving average smanow = SMA(Symbol, 1, Resolution.Daily); // note how we can easily define these indicators to receive hourly data int ribbonCount = 7; int ribbonInterval = 15*8; ribbon = new SimpleMovingAverage[ribbonCount]; for(int i = 0; i < ribbonCount; i++) { ribbon[i] = SMA(Symbol, (i + 1)*ribbonInterval, Resolution.Hour); } } //Save the instance of the weather. public void OnData(Signal data) { yesterday = data; } ///<summary> /// When we have a new event trigger, buy some stock: ///</summary> private DateTime previous; public void OnData(TradeBars data) { // wait for our slow ema to fully initialize if (!sma.IsReady) return; // only once per day if (previous.Date == data.Time.Date) return; var holdings = Portfolio[Symbol].Quantity; //Rebalance every 10 days: if (tradingDayCount >= rebalanceFrequency) { if (yesterday != null) { if ((yesterday.Sig1m > 0 && smanow > sma) || (yesterday.Sig1m < 0 && smanow < sma)){ if (yesterday.Sig7d > 0 && holdings <= 0 ){ SetHoldings(Symbol, 1.0); tradingDayCount = 0;} if (yesterday.Sig7d < 0 && holdings >= 0 ){ SetHoldings(Symbol, -1.0); tradingDayCount = 0;} } else { SetHoldings(Symbol, 0); tradingDayCount = 0; } } } Plot(Symbol, "Price", data[Symbol].Price); // easily plot indicators, the series name will be the name of the indicator Plot(Symbol, smanow, sma); previous = data.Time; } ///<summary> /// After each trading day ///</summary> public override void OnEndOfDay() { tradingDayCount++; } } /// <summary> /// Weather based rebalancing /// </summary> public class Signal : BaseData { public decimal Sig7d = 0; public decimal Sig14d = 0; public decimal Sig1m = 0; public string errString = ""; public Signal() { this.Symbol = "SignalStregth"; } public override string GetSource(SubscriptionDataConfig config, DateTime date, DataFeedEndpoint datafeed) { return "https://www.dropbox.com/s/46g0psa9fws031p/S%26P500_withoutnontradingsignaldates_01072014_01072015.csv?dl=1"; } public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, DataFeedEndpoint datafeed) { Signal signal = new Signal(); try { string[] data = line.Split(','); signal.Time = DateTime.Parse(data[0]).AddHours(20); // Make sure we only get this data AFTER trading day - don't want forward bias. signal.Sig7d = Convert.ToDecimal(data[1]); signal.Sig14d = Convert.ToDecimal(data[2]); signal.Sig1m = Convert.ToDecimal(data[3]); } catch (Exception err) { return null; } return signal; } } }