| Overall Statistics |
|
Total Trades 287 Average Win 2.35% Average Loss -1.25% Compounding Annual Return 1.614% Drawdown 32.200% Expectancy 0.047 Net Profit 6.616% Sharpe Ratio 0.155 Probabilistic Sharpe Ratio 2.087% Loss Rate 64% Win Rate 36% Profit-Loss Ratio 1.88 Alpha 0.002 Beta 0.157 Annual Standard Deviation 0.115 Annual Variance 0.013 Information Ratio -0.586 Tracking Error 0.145 Treynor Ratio 0.114 Total Fees $30315.13 Estimated Strategy Capacity $440000.00 Lowest Capacity Asset O R735QTJ8XC9X |
from LimitOrdersAlphaModel import LimitOrdersAlphaModelConfig
from LimitOrdersAlphaModel import LimitOrdersAlphaModel
RESOLUTION = Resolution.Minute
STARTING_CASH = 1000000
O = Symbol.Create("O", SecurityType.Equity, Market.USA)
O_LimitOrdersAlphaModelConfig = LimitOrdersAlphaModelConfig(O)
class WeightedConstructionModel(PortfolioConstructionModel):
def CreateTargets(self, algorithm, insights):
targets = []
for insight in insights:
targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, insight.Weight))
return targets
class LimitSpreadExecutionModel(ExecutionModel):
def __init__(self, acceptingSpreadPercent=0.005):
self.targetsCollection = PortfolioTargetCollection()
self.acceptingSpreadPercent = Math.Abs(acceptingSpreadPercent)
def Execute(self, algorithm, targets):
self.targetsCollection.AddRange(targets)
if self.targetsCollection.Count > 0:
for target in self.targetsCollection.OrderByMarginImpact(algorithm):
symbol = target.Symbol
unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target)
if unorderedQuantity != 0:
security = algorithm.Securities[symbol]
if self.SpreadIsFavorable(security):
#algorithm.MarketOrder(symbol, unorderedQuantity)
if unorderedQuantity > 0:
algorithm.LimitOrder(symbol, unorderedQuantity, security.Close * 1.1)
elif unorderedQuantity < 0:
algorithm.LimitOrder(symbol, unorderedQuantity, security.Close * 0.9)
self.targetsCollection.ClearFulfilled(algorithm)
def SpreadIsFavorable(self, security):
return security.Exchange.ExchangeOpen \
and security.Price > 0 and security.AskPrice > 0 and security.BidPrice > 0 \
and (security.AskPrice - security.BidPrice) / security.Price <= self.acceptingSpreadPercent
class Fullblend(QCAlgorithm):
def Initialize(self):
self.SetBrokerageModel(BrokerageName.AlphaStreams)
self.SetCash(STARTING_CASH)
self.SetStartDate(2016, 1, 1)
self.SetEndDate(2020, 1, 1)
# entire tradable universe
self.UniverseSettings.Resolution = RESOLUTION
self.AddUniverseSelection(ManualUniverseSelectionModel([O]))
# set alpha models
self.AddAlpha(LimitOrdersAlphaModel(self, O_LimitOrdersAlphaModelConfig))
# set portfolio weightings
self.SetPortfolioConstruction(WeightedConstructionModel())
# set execution model
self.SetExecution(LimitSpreadExecutionModel())
# set risk management model
self.AddRiskManagement(NullRiskManagementModel())import numpy as np
class LimitOrdersAlphaModelConfig:
def __init__(self,
SYMBOL
):
if not SYMBOL:
raise ValueError("[{}] No symbol".format(self.__class__.__name__))
self.SYMBOL = SYMBOL
class LimitOrdersAlphaModel(AlphaModel):
def __init__(self, algorithm, CONFIG):
self.algorithm = algorithm
self.config = CONFIG
self.symbol = CONFIG.SYMBOL
self.symbol_roc = RateOfChange(20)
self.weight = 1.0
self.Warmup(
[self.symbol],
30,
Resolution.Hour,
[self.symbol_roc],
)
def Warmup(self, symbols, lookback, resolution, indicators):
history = self.algorithm.History(symbols, lookback, Resolution.Hour)
for time, row in history["close"].unstack(level = 0).iterrows():
indicators[0].Update(time, row[symbols[0]])
def Update(self, algorithm, data):
insights = []
if algorithm.Time.minute == 0:
if (self.symbol in data.Bars):
self.symbol_roc.Update(algorithm.Time, data.Bars[self.symbol].Close)
cutloss = algorithm.Securities[self.symbol].Holdings.UnrealizedProfitPercent < -0.05
if algorithm.Portfolio[self.symbol].Quantity != 0 and cutloss:
insights.append(Insight.Price(self.symbol, timedelta(minutes = 300), InsightDirection.Flat, None, None, None, 0.00))
if algorithm.Time.hour == 10:
if (self.symbol_roc.Current.Value > 0):
if algorithm.Portfolio[self.symbol].Quantity == 0:
insights.append(Insight.Price(self.symbol, timedelta(minutes = 300), InsightDirection.Up, None, None, None, self.weight))
elif algorithm.Portfolio[self.symbol].Quantity != 0:
insights.append(Insight.Price(self.symbol, timedelta(minutes = 300), InsightDirection.Flat, None, None, None, 0.00))
return Insight.Group(insights)