Overall Statistics |
Total Trades 71 Average Win 2.45% Average Loss -0.86% Compounding Annual Return 1670.083% Drawdown 10.500% Expectancy 1.312 Net Profit 45.970% Sharpe Ratio 15.749 Probabilistic Sharpe Ratio 95.550% Loss Rate 40% Win Rate 60% Profit-Loss Ratio 2.85 Alpha 7.107 Beta 0.356 Annual Standard Deviation 0.469 Annual Variance 0.22 Information Ratio 12.962 Tracking Error 0.51 Treynor Ratio 20.746 Total Fees $83.03 Estimated Strategy Capacity $4000.00 Lowest Capacity Asset SUSHIUSD 2PF |
#region imports from AlgorithmImports import * #endregion class Pair_Stoch_Algo(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 9, 20) # Set Start Date self.SetEndDate(2022, 11, 7) #Set End Date #self.SetAccountCurrency("USD") self.SetCash(500) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.FTXUS, AccountType.Cash) self.symbol = self.AddCrypto("SUSHIUSD", Resolution.Hour, Market.FTXUS).Symbol self.symbol_2 = self.AddCrypto("MATICUSD", Resolution.Hour, Market.FTXUS).Symbol self.sto = Stochastic(14, 1, 3) self.sto_2 = Stochastic(14, 1, 3) chart = Chart("SUSHIUSD") #chart.AddSeries(Series('faststoch', SeriesType.Line, "0")) chart.AddSeries(Series('Sushi stochk', SeriesType.Line, "0")) chart.AddSeries(Series('Sushi stochd', SeriesType.Line, "0")) chart.AddSeries(Series('Sushi stochastic', SeriesType.Line, "0")) #chart.AddSeries(Series('Price', SeriesType.Line, "0")) chart_2 = Chart("MATICUSD") chart.AddSeries(Series('Solana stochk', SeriesType.Line, "0")) chart.AddSeries(Series('Solana stochd', SeriesType.Line, "0")) chart.AddSeries(Series('Solana stochastic', SeriesType.Line, "0")) self.highestPrice = 0 self.highestPrice_2 =0 self.AddChart(chart) self.AddChart(chart_2) 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 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() ### Sushi 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 ### Solana Data Time Frame ### if data.QuoteBars.ContainsKey(self.symbol_2): self.sto_2.Update(data.QuoteBars[self.symbol_2]) if self.sto_2.IsReady: indicator_value = self.sto_2.Current.Value ### Sushi Stoch Values ### #sushi_fast_stoch = self.sto.FastStoch.Current.Value sushi_stoch_k = self.sto.StochK.Current.Value sushi_stoch_d = self.sto.StochD.Current.Value ### Solana Stoch Values ### #fast_stoch = self.sto.FastStoch.Current.Value solana_stoch_k = self.sto_2.StochK.Current.Value solana_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 sushi_stoch_d <= 14 and sushi_stoch_d > 6 and self.Time > self.next_trade_time: quantity = self.CalculateOrderQuantity("SUSHIUSD", 0.75) self.Log("Sushi order quantity set") self.Log("Sushi buy Order @ >> {0}".format(self.Securities["SUSHIUSD"].Price)) self.Log("Sushi stoch D @ >> {0}".format(self.sto.StochD.Current.Value)) self.entryTicket = self.MarketOrder("SUSHIUSD", quantity) self.entryPrice = price ### Solana Trade Code ### if not self.Portfolio[self.symbol_2].Invested and not self.Transactions.GetOpenOrders(self.symbol_2): if solana_stoch_d <= 18 and solana_stoch_d > 15 and self.Time > self.next_trade_time_2: quantity_2 = self.CalculateOrderQuantity("MATICUSD", 0.25) self.Log("Solana order quantity set") self.Log("Solana buy order @ >> {0}".format(self.Securities["MATICUSD"].Price)) self.Log("Solana stoch D @ >> {0}".format(self.sto_2.StochD.Current.Value)) self.entryTicket_2 = self.MarketOrder("MATICUSD", quantity_2) self.entryPrice_2 = price_2 ### Sushi Exit Code ### if self.Portfolio[self.symbol].Invested: if sushi_stoch_k >= 85 and sushi_stoch_k < 90: self.Log("Liquidate @ >> {0}".format(self.Securities["SUSHIUSD"].Price)) self.Log("Stoch @ >> {0}".format(self.sto.StochK.Current.Value)) self.Liquidate("SUSHIUSD") self.next_trade_time = self.Time + timedelta(hours = 5) ### Solana Exit Code ### if self.Portfolio[self.symbol_2].Invested: if solana_stoch_k >= 82 and solana_stoch_k < 90: self.Log("Solana liquidate @ >> {0}".format(self.Securities["MATICUSD"].Price)) self.Log("Solana stoch @ >> {0}".format(self.sto_2.StochK.Current.Value)) self.Liquidate("MATICUSD") self.next_trade_time_2 = self.Time + timedelta(hours = 5) ### Sushi Stop Loss ### if price > self.highestPrice: self.highestPrice = price if self.Securities["SUSHIUSD"].Price < (self.highestPrice * .7): self.Liquidate("SUSHIUSD") self.Log("Sushi stop loss triggered") ### Solana Stop Loss ### if price_2 > self.highestPrice_2: self.highestPrice_2 = price_2 if self.Securities["MATICUSD"].Price < (self.highestPrice_2 * .7): self.Liquidate("MATICUSD") self.Log("Solana stop loss triggered") def PlotIndicator(self): ### Sushi Indicators ### #self.Plot("My Indicators", "faststoch", self.sto.FastStoch.Current.Value) self.Plot("SUSHIUSD", "Sushi stochk", self.sto.StochK.Current.Value) self.Plot("SUSHIUSD", "Sushi stochd", self.sto.StochD.Current.Value) self.Plot("SUSHIUSD", "Sushi Price", self.Securities["SUSHIUSD"].Price) ### Solana Indicators ### self.Plot("MATICUSD", "Solana stochk", self.sto_2.StochK.Current.Value) self.Plot("MATICUSD", "Solana stochd", self.sto_2.StochD.Current.Value) self.Plot("MATICUSD", "Solana Price", self.Securities["MATICUSD"].Price) #self.Plot("My Indicators", "RSI", self.rsi.Current.Value) def OnBrokerageDisconnect(self) -> None: self.Debug("Brokerage connection lost") def OnBrokerageReconnect(self) -> None: self.Debug("Brokerage connection restored")