| 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 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
from Selection.QC500UniverseSelectionModel import QC500UniverseSelectionModel
from Alphas.HistoricalReturnsAlphaModel import HistoricalReturnsAlphaModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from HistoricalReturnsAlphaModel import HistoricalReturnsAM
class BasicTemplateFrameworkAlgorithm(QCAlgorithmFramework):
def Initialize(self):
# Set requested data resolution
self.UniverseSettings.Resolution = Resolution.Minute
self.SetStartDate(2018, 12, 3) #Set Start Date
self.SetEndDate(2019, 4, 3) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.SetUniverseSelection(QC500UniverseSelectionModel())
self.SetAlpha(HistoricalReturnsAM(14, Resolution.Daily))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(NullRiskManagementModel())
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Filled:
# self.Debug("Purchased Stock: {0}".format(orderEvent.Symbol))
pass# Your New Python File# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from clr import AddReference
AddReference("QuantConnect.Algorithm.Framework")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
from QuantConnect import *
from QuantConnect.Indicators import *
from QuantConnect.Algorithm.Framework.Alphas import *
from datetime import timedelta
from collections import deque
class HistoricalReturnsAM(AlphaModel):
'''Uses Historical returns to create insights.'''
def __init__(self, *args, **kwargs):
'''Initializes a new default instance of the HistoricalReturnsAlphaModel class.
Args:
lookback(int): Historical return lookback period
resolution: The resolution of historical data'''
self.lookback = kwargs['lookback'] if 'lookback' in kwargs else 1
self.resolution = kwargs['resolution'] if 'resolution' in kwargs else Resolution.Daily
self.predictionInterval = Time.Multiply(Extensions.ToTimeSpan(self.resolution), self.lookback)
self.symbolDataBySymbol = {}
def Update(self, algorithm, data):
'''Updates this alpha model with the latest data from the algorithm.
This is called each time the algorithm receives data for subscribed securities
Args:
algorithm: The algorithm instance
data: The new data available
Returns:
The new insights generated'''
insights = []
for symbolData in self.symbolDataBySymbol.values():
symbolData.Update(algorithm.Securities[symbolData.symbol.Symbol].Close)
return insights
def OnSecuritiesChanged(self, algorithm, changes):
'''Event fired each time the we add/remove securities from the data feed
Args:
algorithm: The algorithm instance that experienced the change in securities
changes: The security additions and removals from the algorithm'''
# clean up data for removed securities
#algorithm.Log(changes.AddedSecurities[0].Fundamentals.ValuationRatios.TotalYield)
for removed in changes.RemovedSecurities:
symbolData = self.symbolDataBySymbol.pop(removed.Symbol, None)
# initialize data for added securities
symbols = [ x.Symbol for x in changes.AddedSecurities ]
for added in changes.AddedSecurities:
if added.Symbol not in self.symbolDataBySymbol:
self.symbolDataBySymbol[added.Symbol]= SymbolData(added)
self.symbolDataBySymbol[added.Symbol].WarmUp(algorithm)
class SymbolData:
'''Contains data specific to a symbol required by this model'''
def __init__(self, symbol):
self.symbol = symbol
self.sixMonthsInDays = 100
self.twelveMonthsInDays = 200
self.queue = deque(maxlen=self.twelveMonthsInDays)
def Return(self, period):
return self.queue[0]/self.queue[period]-1
def Update(self, value):
self.queue.appendleft(value)
count = len(self.queue)
self.IsReady = count == self.queue.maxlen
def WarmUp(self, qcContext):
history = qcContext.History(self.symbol.Symbol, self.twelveMonthsInDays, Resolution.Daily)
if str(self.symbol) in history.index:
for tuple in history.itertuples(): self.Update(tuple.close)
#Scoring according to https://letyourmoneygrow.com/2018/03/09/susan-levermann-approach-an-investment-strategy-that-works/
def Score(self):
score = 0
#1 One year RoE >20%: +1 ; <10%: -1
if self.symbol.Fundamentals.OperationRatios.ROE.OneYear > 0.2:
score = score + 1
elif self.symbol.Fundamentals.OperationRatios.ROE.OneYear < 0.1:
score = score - 1
#2 EBIT One Year >12%: +1 ; <6%: -1
if self.symbol.Fundamentals.OperationRatios.EBITMargin.OneYear > 0.12:
score = score + 1
elif self.symbol.Fundamentals.OperationRatios.EBITMargin.OneYear < 0.06:
score = score - 1
#3 Equity Ratio one year >25%: +1 ; <15%: -1
if 1/self.symbol.Fundamentals.OperationRatios.FinancialLeverage.OneYear>0.25:
score = score + 1
elif 1/self.symbol.Fundamentals.OperationRatios.FinancialLeverage.OneYear<0.15:
score = score - 1
#4 P/E one Year <12: +1 ; >16: -1
if self.symbol.Fundamentals.ValuationRatios.PERatio.OneYear<12:
score = score +1
elif self.symbol.Fundamentals.ValuationRatios.PERatio.OneYear>16:
score = score - 1
#5 P/E five years <13: +1 ; >17: -1
if self.symbol.Fundamentals.ValuationRatios.PERatio.FiveYear<13:
score = score +1
elif self.symbol.Fundamentals.ValuationRatios.PERatio.FiveYear>17:
score = score - 1
#6 Analyst Opinions
#7 Real price reaction in % on quarterly EPS report >1%: +1 ; <-1%: -1
#8 Current FQ Est EPS% change >5%: +1 ; <-5%: -1
#9 6 months price change >5%: +1 ; <-5%: -1
if self.Return(self.sixMonthsInDays) > 0.05: score = score+1
elif self.Return(self.sixMonthsInDays)<-0.05: score = score-1
#10 12 months price change >5%: +1 ; <-5%: -1
if self.Return(self.twelveMonthsInDays) > 0.05: score = score+1
elif self.Return(self.twelveMonthsInDays)<-0.05: score = score-1
#11 EPS growth: Change of current to next FY Est EPS >5%: +1; <-5%: -1
#12 Momentum: if 6 months price change > 5% and 12 month price change < -5%: 1
# if 6 months price change < -5% and 12 month price change > 5%: -1
if self.Return(self.sixMonthsInDays) > 0.05 and self.Return(self.twelveMonthsInDays)<-0.05: score = score+1
elif self.Return(self.sixMonthsInDays) <0.05 and self.Return(self.twelveMonthsInDays)>0.05: score = score+1
#13 Reversal: if better than benachmark: 1 ; if worse than benchmark -1
return score
def __str__(self, **kwargs):
return 'Symbol'