Overall Statistics Total Trades852Average Win0.18%Average Loss-0.12%Compounding Annual Return0.319%Drawdown5.900%Expectancy0.013Net Profit0.585%Sharpe Ratio0.112Loss Rate59%Win Rate41%Profit-Loss Ratio1.49Alpha-0.028Beta1.584Annual Standard Deviation0.033Annual Variance0.001Information Ratio-0.487Tracking Error0.033Treynor Ratio0.002Total 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)```