Overall Statistics |
Total Trades 27683 Average Win 0.36% Average Loss -0.07% Compounding Annual Return 11.573% Drawdown 19.100% Expectancy 0.042 Net Profit 89.501% Sharpe Ratio 0.466 Sortino Ratio 0.56 Probabilistic Sharpe Ratio 11.195% Loss Rate 82% Win Rate 18% Profit-Loss Ratio 4.86 Alpha 0 Beta 0 Annual Standard Deviation 0.15 Annual Variance 0.022 Information Ratio 0.606 Tracking Error 0.15 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $8700000.00 Lowest Capacity Asset QQQ RIWIV7K5Z9LX Portfolio Turnover 2233.05% |
# region imports from AlgorithmImports import * from QuantConnect.Data import Slice # endregion # Fee model to test zero fees class CustomFeeModel(FeeModel): def __init__(self): pass def GetOrderFee(self, parameters: OrderFeeParameters) -> OrderFee: return OrderFee.Zero # Buying power model so that we can aoivd trading single shares class MinimumOrderSizeBuyingPowerModel(BuyingPowerModel): def __init__(self, min_order_size): self.min_order_size = min_order_size def GetMinimumOrderQuantityForResolution(self, security, targetOrderValue): return OrderQuantity(self.min_order_size, 0) def GetBuyingPower(self, parameters): return BuyingPower(self.Portfolio.Cash, 0) class Vwaptrend(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) self.SetEndDate(2023, 11, 1) self.SetCash(25000) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) # Equal weighting with assets self.SetExecution(ImmediateExecutionModel()) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.asset1 = self.AddEquity("QQQ", Resolution.Minute) self.asset1.SetDataNormalizationMode(DataNormalizationMode.Raw) self.asset1.SetBuyingPowerModel(MinimumOrderSizeBuyingPowerModel(10)) # Set minimum order size to 10 so that insights don't trade single shares self.asset1_vwap = self.VWAP(self.asset1.Symbol) self.asset1_long = None self.period = timedelta(days=1) # Insight period, but we're not using it here as the execution model is with market orders # turn off fees self.asset1.SetFeeModel(CustomFeeModel()) def OnData(self, slice: Slice) -> None: if not self.asset1_vwap.IsReady or (self.Time.hour == 9 and self.Time.minute == 30) or (self.Time.hour == 16 and self.Time.minute == 0): return # exit position EOD if self.Time.hour == 15 and self.Time.minute == 59: asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Flat) self.EmitInsights(asset1_insight) self.Log(f'Exiting position at EOD') self.asset1_long = None return # if getting second data but don't want to trade every second # if not self.Time.second == 0: # return # if we want to trade every 5 minutes # if not self.Time.minute % 5 == 0: # return price = self.asset1.Close if price > self.asset1_vwap.Current.Value and (not self.asset1_long or self.asset1_long is None): asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Up) self.EmitInsights(asset1_insight) self.asset1_long = True self.Log(f'vwap: {round(self.asset1_vwap.Current.Value, 2)} price: {price} Flipping to long') if price < self.asset1_vwap.Current.Value and (self.asset1_long or self.asset1_long is None): asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Down) self.EmitInsights(asset1_insight) self.asset1_long = False self.Log(f'vwap: {round(self.asset1_vwap.Current.Value, 2)} price: {price} Flipping to short') # do this every few minutes # if self.Time.minute % 1 == 0: # self.Plot("IntradayVwap", "vwap", self.asset1_vwap.Current.Value) # self.Plot("IntradayVwap", "price", price) # self.Log(f"vwap: {self.asset1_vwap.Current.Value} price: {price}")
# region imports from AlgorithmImports import * from QuantConnect.Data import Slice # endregion class CustomFeeModel(FeeModel): def __init__(self): pass def GetOrderFee(self, parameters: OrderFeeParameters) -> OrderFee: return OrderFee.Zero class MinimumOrderSizeBuyingPowerModel(BuyingPowerModel): def __init__(self, min_order_size): self.min_order_size = min_order_size def GetMinimumOrderQuantityForResolution(self, security, targetOrderValue): return OrderQuantity(self.min_order_size, 0) def GetBuyingPower(self, parameters): return BuyingPower(self.Portfolio.Cash, 0) class Vwaptrend(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) self.SetEndDate(2023, 11, 1) self.SetCash(30000) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.asset1 = self.AddEquity("QQQ", Resolution.Minute) self.asset1.SetDataNormalizationMode(DataNormalizationMode.Raw) self.asset1.SetBuyingPowerModel(MinimumOrderSizeBuyingPowerModel(10)) # Set minimum order size to 100 self.asset1_vwap = self.VWAP(self.asset1.Symbol) self.asset1_long = None self.period = timedelta(days=1) self.asset1.SetFeeModel(CustomFeeModel()) def OnData(self, slice: Slice) -> None: if not self.asset1_vwap.IsReady or (self.Time.hour == 9 and self.Time.minute == 30) or (self.Time.hour == 16 and self.Time.minute == 0): return if not self.Time.second == 0: return # exit position EOD if self.Time.hour == 15 and self.Time.minute == 59: asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Flat) self.EmitInsights(asset1_insight) self.Log(f'Exiting position at EOD') self.asset1_long = None return # if not self.Time.minute % 5 == 0: # return price = self.asset1.Close if price > self.asset1_vwap.Current.Value and (not self.asset1_long or self.asset1_long is None): asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Up) self.EmitInsights(asset1_insight) self.asset1_long = True self.Log(f'vwap: {round(self.asset1_vwap.Current.Value, 2)} price: {price} Flipping to long') if price < self.asset1_vwap.Current.Value and (self.asset1_long or self.asset1_long is None): asset1_insight = Insight.Price(self.asset1.Symbol, self.period, InsightDirection.Down) self.EmitInsights(asset1_insight) self.asset1_long = False self.Log(f'vwap: {round(self.asset1_vwap.Current.Value, 2)} price: {price} Flipping to short') # do this every few minutes # if self.Time.minute % 1 == 0: # self.Plot("IntradayVwap", "vwap", self.asset1_vwap.Current.Value) # self.Plot("IntradayVwap", "price", price) # self.Log(f"vwap: {self.asset1_vwap.Current.Value} price: {price}")