| Overall Statistics |
|
Total Trades 852 Average Win 0.18% Average Loss -0.12% Compounding Annual Return 0.319% Drawdown 5.900% Expectancy 0.013 Net Profit 0.585% Sharpe Ratio 0.112 Loss Rate 59% Win Rate 41% Profit-Loss Ratio 1.49 Alpha -0.028 Beta 1.584 Annual Standard Deviation 0.033 Annual Variance 0.001 Information Ratio -0.487 Tracking Error 0.033 Treynor Ratio 0.002 Total Fees $852.00 |
from datetime import datetime, timedelta
import numpy as np
import decimal as d
import dateutil
from QuantConnect.Brokerages import *
### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
'''Basic template algorithm simply initializes the date range and cash'''
def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates
for your algorithm. All algorithms must initialized.'''
self.total_cash = 20000
self.SetStartDate(2017, 2, 1) # Set Start Date
self.SetEndDate(2018, 12, 1) # Set End Date
self.SetCash(self.total_cash) # Set Strategy Cash
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
self.capital_per_trade = 10000 #self.total_cash/2.0
self.symbol = "IWM"
# Find more symbols here: http://quantconnect.com/data
self.AddEquity(self.symbol, Resolution.Minute)
self.prev_vidya = 0.0
self.vidya_period = 14
self.adx_period = 14
self.stop_loss = 4
self.profit_target = 0.3
self.adx_threshold = 28
self.per_stop_loss = self.stop_loss/100
self.per_profit_target = self.profit_target/100
self.enter_price = 0.0
self.enter = False
self.exit = False
# define our 30 minute trade bar consolidator. we can
# access the 30 minute bar from the DataConsolidated events
thirtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=30))
# attach our event handler. The event handler is a function that will
# be called each time we produce a new consolidated piece of data.
thirtyMinuteConsolidator.DataConsolidated += self.ThirtyMinuteBarHandler
# this call adds our 30-minute consolidator to
# the manager to receive updates from the engine
self.SubscriptionManager.AddConsolidator(self.symbol, thirtyMinuteConsolidator)
# dailyConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
# self.SubscriptionManager.AddConsolidator(self.symbol, dailyConsolidator)
# dailyConsolidator.DataConsolidated += self.dailyBarHandler
self.adx = self.ADX(self.symbol, self.adx_period, Resolution.Daily)
self.cmo = self.CMO(self.symbol, self.vidya_period)
self.RegisterIndicator(self.symbol, self.adx, Resolution.Daily)
# self.RegisterIndicator(self.symbol, self.cmo, thirtyMinuteConsolidator)
# def dailyBarHandler(self, sender, bar):
# Chart('ADX')
# self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose(self.symbol),
# self.update_plots)
def determine_vidya(self, period, cmo , prev_vidya, close):
alpha = 2 / period * 1
float_close = float(close)
float_cmo = float(cmo)
# vidya1 = alpha + prev_vidya * (1 - alpha * cmo)
vidya = float_close * alpha + prev_vidya * (1 - alpha * float_cmo)
return vidya
def ThirtyMinuteBarHandler(self, sender, bar):
'''This is our event handler for our 30-minute trade bar defined above in Initialize().
So each time the consolidator produces a new 30-minute bar, this function will be called
automatically. The sender parameter will be the instance of the IDataConsolidator that
invoked the event '''
printafterdate = "2018-11-18"
odate = dateutil.parser.parse(printafterdate)
currentdatetime = str(self.Time)
currentdate = currentdatetime[:10]
ocurrentdate = dateutil.parser.parse(currentdate)
self.cmo.Update(bar.EndTime, bar.Close)
processafterdate = "2017-10-30"
oprocessdate = dateutil.parser.parse(processafterdate)
if self.adx.IsReady and self.cmo.IsReady and (ocurrentdate > oprocessdate):
vidya = self.determine_vidya(self.vidya_period, self.cmo.Current.Value, self.prev_vidya,
bar.Close)
self.prev_vidya = vidya
# if ocurrentdate > odate:
# self.Debug(str(self.Time) + ":" + str(bar) + ",ADX:" + str(self.adx.Current.Value) +
# ",CMO:" + str(self.cmo.Current.Value) + ",CMOTime:" + str(bar.EndTime))
if not self.Portfolio.Invested:
tech1_cond = float(self.adx.Current.Value) > self.adx_threshold
if (tech1_cond):
self.Debug(str(bar.EndTime) + ":" + "Tech1 condition met")
tech2_cond = vidya > float(bar.High)
if (tech2_cond):
self.Debug(str(bar.EndTime) + ":" + "Tech2 condition met")
if tech1_cond and tech2_cond:
self.enter = True
self.Debug(str(bar.EndTime) + ":" + "Enter condition met")
if self.Portfolio.Invested:
stoploss_level = self.enter_price * (1 + self.per_stop_loss)
stoploss_cond = bar.Close > stoploss_level
if (stoploss_cond):
self.Debug(str(bar.EndTime) + ":" + "Stoploss condition met")
profit_level = self.enter_price * (1 - self.per_profit_target)
profit_cond = bar.Close < profit_level
if (profit_cond):
self.Debug(str(bar.EndTime) + ":" + "Profit condition met")
tech_cond = vidya < float(bar.Low)
if tech_cond or stoploss_cond or profit_cond:
self.exit = True
self.Debug(str(bar.EndTime) + ":" + "Exit condition met")
if self.enter == True:
# per_quantity = 0.5 * self.capital_per_trade/float(bar.Open)
self.SetHoldings(self.symbol, -0.5)
self.enter_price = float(bar.Open)
self.enter = False
if (self.exit == True):
self.Liquidate(self.symbol)
self.exit_price = float(bar.Open)
self.exit = False
# else:
# self.Debug(str(self.Time) + ":" + str(bar))
# # self.Debug("Daily Bar Handler" + str(self.Time) + " " + str(bar) + str(adx))
# float_bar_close = float(bar.Close)
# self.determine_vma(float_bar_close)
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will
be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
def update_plots(self):
if not self.adx.IsReady:
return
# Plots can also be created just with this one line command.
self.Plot('ADX', self.adx)