| 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")