Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-0.273
Tracking Error
0.352
Treynor Ratio
0
Total Fees
$0.00
import pandas as pd
import numpy as np
from Selection.UncorrelatedUniverseSelectionModel import UncorrelatedUniverseSelectionModel

class CalibratedVentralRadiator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)
        self.SetEndDate(2020,9,21) 
        self.SetCash(100000)
        self.fiveminBar = None
        self.symbol_list = list()
        self.UniverseSettings.Resolution = Resolution.Minute
        self.AddUniverseSelection(UncorrelatedUniverseSelectionModel(numberOfSymbols = 20)) 
        
        self.SetWarmUp(30)
        
        # Schedule functions
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9,00), self.ViewUniverse)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9,15), self.registerIndicators)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(13,30), self.ClosePositions)
    
    def registerIndicators(self):
        self.symbolData = dict()
        
        for symbol in self.symbol_list:
            if not self.symbol_list: return
            #symbol = coarse.Value
            if symbol not in self.symbolData:
                consolidator = self.Consolidate(symbol, timedelta(minutes=5), self.OnDataConsolidated)
                self.symbolData[symbol] = SymbolData()
                self.RegisterIndicator(symbol, self.symbolData[symbol].macd, consolidator)
                self.RegisterIndicator(symbol, self.symbolData[symbol].mfi, consolidator)
        
        self.Log(self.symbol_list)
        
    def ViewUniverse(self):
        self.symbol_list = list()
        for universe in self.UniverseManager.Values:
            if universe is UserDefinedUniverse:
                continue
            symbols = universe.Members.Keys
            for symbol in symbols:
                self.symbol_list.append(symbol)
        
    #A function which saves the fiveminBar as bar
    def OnDataConsolidated(self, bar):
        if bar.Time.hour == 10:
            self.fiveminBar = bar
    
    #A function which saves the fiveminBar as bar 
    def OnSecuritiesChanged(self, changes):
        self.changes = changes
        if self.changes is None: return
        if (self.IsWarmingUp): return
        if self.fiveminBar == None : return
        if not self.symbol_list: return
        qnty = 1/len(self.symbol_list)
        
        #history_select = self.Securities.Keys
        self.history = self.History(self.symbol_list, 5, Resolution.Daily)
        
        for coarse in self.changes.AddedSecurities:
            #self.selected.append(symbol.Symbol.Value)
            symbol = coarse.Symbol
            if symbol not in self.symbolData: return
            if not self.symbolData[symbol].is_ready(): return
            macd = self.symbolData[symbol].macd
            moneyfi = self.symbolData[symbol].mfi
            
            fast = macd.Fast.Current.Value
            slow = macd.Slow.Current.Value
            mfi = moneyfi.Current.Value
            self.Log(str(fast) + ' :' + str(slow))
            
            if not self.history.empty:
                symbol_df = self.history.loc[symbol]
            
            holdings = self.Portfolio[symbol].Quantity
            
            if not self.Portfolio[symbol].Invested:
                #Buy at range high break out and confirm with the indicators
                if symbol_df.close[-1] > self.fiveminBar.High:
                    if fast > slow and mfi < 30:
                        max_stop = self.fiveminBar.High - (self.fiveminBar.High-self.fiveminBar.Low)/2
                        takeprofit = self.fiveminBar.High + (self.fiveminBar.High-self.fiveminBar.Low)
                        self.SetHoldings(symbol, qnty)
                        self.Log('LONG POSITION: {}'.format(symbol))
                        self.stopMarketTicket = self.StopMarketOrder(symbol, holdings, max_stop)
                        self.takeProfitTicket = self.LimitOrder(symbol, holdings, takeprofit)
                #Sell at range low break out and confirm with the indicators
                if symbol_df.close[-1] < self.fiveminBar.Low:
                    if slow > fast and mfi > 70:
                        min_stop = self.fiveminBar.High + (self.fiveminBar.High-self.fiveminBar.Low)/2
                        takeprofit = self.fiveminBar.High - (self.fiveminBar.High-self.fiveminBar.Low)
                        self.SetHoldings(symbol, -qnty)
                        self.Log('SHOT POSITION: {}'.format(symbol))
                        self.stopMarketTicket = self.StopMarketOrder(symbol, -holdings, min_stop)
                        self.takeProfitTicket = self.LimitOrder(symbol, -holdings, takeprofit)
                        
        for security in self.changes.RemovedSecurities:
            self.Liquidate(security.Symbol)
                
    #close all open positions by end of day
    def ClosePositions(self):
        self.fiveminBar = None
        self.Liquidate()
            
    
    # Order event function
    def OnOrderEvent(self, orderEvent):
        if not (orderEvent.Status == 'Filled'):
            return
        if self.stopMarketTicket == None and self.takeProfitTicket == None:
            return
        if self.stopMarketTicket.OrderId == orderEvent.OrderId:
            self.takeProfitTicket.Cancel
        if self.takeProfitTicket.OrderId == orderEvent.OrderId:
            self.stopMarketTicket.Cancel

class SymbolData(object):
    
    def __init__(self):
        #strategy parameters
        self.fastPeriod = 12
        self.slowPeriod = 26
        self.signalPeriod = 9
        self.mfiPeriod = 14
        
        #indicators
        self.macd = MovingAverageConvergenceDivergence(self.fastPeriod, self.slowPeriod, self.signalPeriod)
        self.mfi = MoneyFlowIndex(self.mfiPeriod)
    
    def is_ready(self):
        return self.macd.IsReady and self.mfi.IsReady