Overall Statistics |
Total Trades 124 Average Win 0.38% Average Loss -0.01% Compounding Annual Return -0.201% Drawdown 0.400% Expectancy -0.045 Net Profit -0.019% Sharpe Ratio -0.137 Loss Rate 98% Win Rate 2% Profit-Loss Ratio 58.24 Alpha 0.003 Beta -0.019 Annual Standard Deviation 0.012 Annual Variance 0 Information Ratio -3.734 Tracking Error 0.069 Treynor Ratio 0.085 Total Fees $1729.01 |
using System; namespace QuantConnect { /* * QuantConnect University: Full Basic Template: * * The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect. * We have explained some of these here, but the full algorithm can be found at: * https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs */ public class BasicTemplateAlgorithm : QCAlgorithm { static int universe = 2; static string[] syb = new string[2]; //RollingWindow<TradeBar> _window = new RollingWindow<TradeBar>(20); VolumeWeightedAveragePriceIndicator[] vwap = new VolumeWeightedAveragePriceIndicator[universe]; ExponentialMovingAverage[] fast = new ExponentialMovingAverage[universe]; ExponentialMovingAverage[] slow = new ExponentialMovingAverage[universe]; //Initialize the data and resolution you require for your strategy: public override void Initialize() { //syb[0] = "JCP"; //syb[2] = "FB"; //syb[3] = "AAPL"; //syb[4] = "JCP"; //syb[4] = "FB"; //syb[4] = "MGM"; //syb[5] = "DAL"; //Start and End Date range for the backtest: SetStartDate(2016, 7, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(1000000); //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Equity, "MS", Resolution.Minute); AddSecurity(SecurityType.Equity, "DAL", Resolution.Minute); AddSecurity(SecurityType.Equity, "MGM", Resolution.Minute); AddSecurity(SecurityType.Equity, "JCP", Resolution.Minute); AddSecurity(SecurityType.Equity, "PBR", Resolution.Minute); AddSecurity(SecurityType.Equity, "FB", Resolution.Minute); AddSecurity(SecurityType.Equity, "NVDA", Resolution.Minute); AddSecurity(SecurityType.Equity, "BAC", Resolution.Minute); AddSecurity(SecurityType.Equity, "SAN", Resolution.Minute); AddSecurity(SecurityType.Equity, "JPM", Resolution.Minute); AddSecurity(SecurityType.Equity, "BAC", Resolution.Minute); AddSecurity(SecurityType.Equity, "GOOG", Resolution.Minute); AddSecurity(SecurityType.Equity, "PG", Resolution.Minute); AddSecurity(SecurityType.Equity, "AAPL", Resolution.Minute); AddSecurity(SecurityType.Equity, "MSFT", Resolution.Minute); syb[0] = "MS"; syb[1] = "NVDA"; for (int i=0;i<vwap.Length;i++){ vwap[i] = VWAP(syb[i], 60,Resolution.Minute); fast[i] = EMA(syb[i], 5,Resolution.Hour); slow[i] = EMA(syb[i], 20,Resolution.Hour); } } //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) { /* decimal High = data[sybl].High; decimal Low = data[sybl].Low; long Volume = data[sybl].Volume; decimal Open = data[sybl].Open; double[] adv = new double[period]; long adv20=0; decimal advclose20; decimal[] advclose = new decimal[period]; for(int i =0;i<period;i++){ adv[i] = _window[i].Volume; advclose[i] = _window[i].Close; } //adv20 =(_window[0].Volume+_window[19].Volume)/2; double max = adv.Max(); double min = adv.Min(); int holdings = Portfolio[sybl].Quantity; //quantity_new =0; //quantity_old =0; */ //int period = 180; int[] sign = new int[universe]; //if (!_window.IsReady) return; if(!fast[0].IsReady || !slow[0].IsReady) return; //double[] adv = new double[period]; //long adv20=0; //decimal advclose20; //decimal[] advclose = new decimal[period]; decimal[] Close = new decimal[universe]; double[] quantity_portion = new double[universe]; long[] Volume = new long[universe]; double[] quantity_new = new double[universe]; double[] quantity_old = new double[universe]; double[] portion = new double[universe]; for(int i=0;i<syb.Length;i++){ Close[i] = data[syb[i]].Close; Volume[i] = data[syb[i]].Volume; if(fast[i]>slow[i]) { sign[i]= 1; } else{ sign[i]=-1; } if(Close[i]>vwap[i]){ //Close[i]>=vwap[i] |Close[i]<vwap[i] /* for(int i =0;i<period;i++){ adv[i] = _window[i].Volume; advclose[i] = _window[i].Close; } */ //quantity_new[i] = ( ((double)Close[i] - (int)vwap[i]) * (double)Close[i] * sign[i] * Volume[i]); quantity_new[i] = (double)Close[i]; quantity_portion[i] = Math.Abs(quantity_new[i]); //quantity_old1 = quantity_new1; //quantity_old2 = quantity_new2; //Plot("portion1",portion1); }else{ quantity_new[i] = (double)Close[i]; quantity_portion[i] = Math.Abs(quantity_new[i]); } } Schedule.On(DateRules.EveryDay("SPY"), TimeRules.AfterMarketOpen("SPY", 10), () =>{ for(int i=0;i<syb.Length;i++){ if(quantity_portion[i] ==0){ portion[i] = 0; }else{ portion[i] = (double)quantity_portion[i] / (double)quantity_portion.Sum(); } Debug("Purchased " + portion[i] +" on " + Time.ToShortDateString()); SetHoldings(syb[i],portion[i]/4); } }); Plot("portion" + universe,"%",portion[0]); if(Portfolio[syb[0]].UnrealizedProfit<(int)-0.01*Portfolio.Cash | Portfolio[syb[0]].UnrealizedProfit>(int)1.01*Portfolio.Cash){ Liquidate(syb[0]); }else if(Portfolio[syb[1]].UnrealizedProfit<(int)-0.01*Portfolio.Cash | Portfolio[syb[1]].UnrealizedProfit>(int)1.01*Portfolio.Cash){ Liquidate(syb[1]); }else{ Schedule.On(DateRules.EveryDay("SPY"), TimeRules.BeforeMarketClose("SPY", 10), () =>{ Liquidate(syb[0]); Liquidate(syb[1]); }); } } /* public override void OnEndOfDay(){ Debug("PLOTTING"); Plot("portion1", (Math.Abs(quantity_new1))); Plot("portion2", (Math.Abs(quantity_new2))); } */ } }