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