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)