Overall Statistics |
Total Trades 3 Average Win 4.35% Average Loss 0% Compounding Annual Return 831.509% Drawdown 11.300% Expectancy 0 Net Profit 12.318% Sharpe Ratio 10.089 Probabilistic Sharpe Ratio 76.992% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 4.826 Beta 0.66 Annual Standard Deviation 0.456 Annual Variance 0.208 Information Ratio 12.568 Tracking Error 0.393 Treynor Ratio 6.979 Total Fees $3.90 Estimated Strategy Capacity $6000.00 Lowest Capacity Asset SUSHIUSD XJ |
#region imports from AlgorithmImports import * #endregion class Pair_Stoch(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 11, 10) # Set Start Date self.SetEndDate(2022, 11, 28) #Set End Date #self.SetAccountCurrency("USD") self.SetCash(500) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash) self.symbol = self.AddCrypto("SUSHIUSD", Resolution.Hour, Market.GDAX).Symbol self.symbol_2 = self.AddCrypto("SUSHIUSD", Resolution.Hour, Market.GDAX).Symbol self.sto = Stochastic(14, 1, 3) self.sto_2 = Stochastic(14, 1, 3) self.consolidator = QuoteBarConsolidator(timedelta(hours=4)) self.consolidator.DataConsolidated += self.consolidation_handler self.SubscriptionManager.AddConsolidator(self.symbol_2, self.consolidator) self.sto_2 = Stochastic(14, 1, 3) self.RegisterIndicator(self.symbol_2, self.sto_2, self.consolidator) self.highestPrice = 0 self.highestPrice_2 =0 self.next_trade_time = datetime.min self.next_trade_time_2 = datetime.min self.entryPrice = 0 self.entryPrice_2 = 0 self.entryTicket = None self.entryTicket_2 = None self.month = 0 def consolidation_handler(self, sender: object, consolidated_bar: QuoteBar) -> None: self.Plot(consolidated_bar.Symbol.Value, "4HourBar", consolidated_bar.Close) def IsRebalanceDue(self, time): if time.month == self.month or time.month not in [1, 4, 7, 10]: return None self.month = time.month return time def OnData(self, data): self.PlotIndicator() ### Symbol Data Time Frame ### if data.QuoteBars.ContainsKey(self.symbol): self.sto.Update(data.QuoteBars[self.symbol]) if self.sto.IsReady: indicator_value = self.sto.Current.Value ### Symbol Stoch Values ### #Sushi__fast_stoch = self.sto.FastStoch.Current.Value Hour_stoch_k = self.sto.StochK.Current.Value Hour_stoch_d = self.sto.StochD.Current.Value ### AAVE Stoch Values ### #fast_stoch = self.sto.FastStoch.Current.Value Four_Hour_stoch_k = self.sto_2.StochK.Current.Value Four_Hour_stoch_d = self.sto_2.StochD.Current.Value price = self.Securities[self.symbol].Price price_2 = self.Securities[self.symbol_2].Price ### Sushi Trade Code ### if not self.Portfolio[self.symbol].Invested and not self.Transactions.GetOpenOrders(self.symbol): if Hour_stoch_d <= 12 and Hour_stoch_d > 2 and self.Time > self.next_trade_time: quantity = self.CalculateOrderQuantity(self.symbol, 0.5) self.Log("1 Hour Sushi Order Quantity Set") self.Log("1 Hour Sushi Buy Order @ >> {0}".format(self.Securities["SUSHIUSD"].Price)) self.Log("1 Hour Sushi Stoch D @ >> {0}".format(self.sto.StochD.Current.Value)) self.entryTicket = self.MarketOrder(self.symbol, quantity) self.entryPrice = price ### AAVE Trade Code ### if not self.Portfolio[self.symbol_2].Invested and not self.Transactions.GetOpenOrders(self.symbol_2): if Four_Hour_stoch_k <= 20 and Four_Hour_stoch_k > 2 and self.Time > self.next_trade_time_2: quantity_2 = self.CalculateOrderQuantity(self.symbol_2, 0.5) self.Log("4 Hour Sushi order quantity set") self.Log("4 Hour Sushi buy order @ >> {0}".format(self.Securities["AAVEUSD"].Price)) self.Log("4 Hour Sushi stoch K @ >> {0}".format(self.sto_2.StochK.Current.Value)) self.entryTicket = self.MarketOrder(self.symbol, quantity_2) self.entryPrice_2 = price_2 ### 1 Hour Sushi Exit Code ### if self.Portfolio[self.symbol].Invested: if Hour_stoch_d >= 96 and Hour_stoch_d < 110: self.Log("1 Hour Sushi liquidate @ >> {0}".format(self.Securities["SUSHIUSD"].Price)) self.Log("1 Hour Sushi stoch @ >> {0}".format(self.sto.StochK.Current.Value)) self.Liquidate(self.symbol) self.next_trade_time = self.Time + timedelta(hours = 4) ### 4 Hour Sushi Exit Code ### if self.Portfolio[self.symbol_2].Invested: if Four_Hour_stoch_k >= 95 and Four_Hour_stoch_k < 100: self.Log("4 Hour Sushi liquidate @ >> {0}".format(self.Securities["SUSHIUSD"].Price)) self.Log("4 Hour Sushi stoch @ >> {0}".format(self.sto_2.StochK.Current.Value)) self.Liquidate(self.symbol_2) self.next_trade_time_2 = self.Time + timedelta(hours = 4) ### 1 Hour Sushi Stop Loss ### if self.Securities[self.symbol].Price < (self.entryPrice * .95): self.Liquidate(self.symbol) self.Log("1 Hour Sushi stop loss triggered") ### 4 Hour Stop Loss ### if self.Securities[self.symbol_2].Price < (self.entryPrice_2 * .95): self.Liquidate(self.symbol_2) self.Log("4 Four Sushi stop loss triggered") def PlotIndicator(self): ### Sushi Indicators ### self.Plot("1 Hour Sushi Indicators", "1 Hour stochk", self.sto.StochK.Current.Value) self.Plot("1 Hour Sushi Indicators", "1 Hour stochd", self.sto.StochD.Current.Value) ### AAVE Indicators ### self.Plot("4 Hour Sushi Indicators", "4 Hour stochk", self.sto_2.StochK.Current.Value) self.Plot("4 Hour Sushi Indicators", "4 Hour stochd", self.sto_2.StochD.Current.Value) def OnBrokerageDisconnect(self) -> None: self.Debug("Brokerage connection lost") def OnBrokerageReconnect(self) -> None: self.Debug("Brokerage connection restored")