| 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)));
}
*/
}
}