Quant BuffetRelax, Not Over Thinking

Overnight Seasonality in Bitcoin

Log in to collect

Academic paper

Seasonality, Trend-following, and Mean reversion in Bitcoin

AuthorsMatus Padysak; Radovan Vojtko

Institute
  • SKComenius University Bratislava
  • ?Comenius University - Faculty of Mathematics, Physics and Informatics
  • ?Quantpedia.com

Strategy in a nutshell

Universe: Bitcoin (Gemini exchange). Long BTC at 22:00 UTC, hold for 2 hours, then close the position.

Economic rationale

The BTC 22:00–24:00 seasonality may arise because all major traditional markets are closed, leaving BTC as one of the few actively traded assets. Statistical analysis shows significant positive returns during this period, with negligible negative returns, making it a favorable short-term window.

Backtest performance

Annualised return33.01%
Volatility20.93%
Beta0.068
Sharpe ratio1.49
Sortino ratio1.06
Maximum drawdown-22.45%
Win rate52%

Full Python code

from AlgorithmImports import *
# endregion

class OvernightSeasonalityinBitcoin(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2016, 1, 1)
self.SetCash(100000)

# NOTE Coinbase Pro, CoinAPI, and Bitfinex data is all set in UTC Time. This means that when accessing data from this brokerage, all data will be time stamped in UTC Time.
self.crypto = self.AddCrypto("BTCUSD", Resolution.Minute, Market.Bitfinex)
self.crypto.SetLeverage(10)
self.crypto.SetFeeModel(CustomFeeModel())
self.crypto = self.crypto.Symbol

self.open_trade_hour:int = 22
self.close_trade_hour:int = 0

def OnData(self, data):
if self.crypto in data and data[self.crypto]:
    time:datetime.datetime = self.UtcTime

    # open long position
    if time.hour == self.open_trade_hour and time.minute == 0:
        self.SetHoldings(self.crypto, 1)
    
# close position
if time.hour == self.close_trade_hour and time.minute == 0:
    if self.Portfolio[self.crypto].Invested:
        self.Liquidate(self.crypto)

class CustomFeeModel(FeeModel):
def GetOrderFee(self, parameters):
fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.00005
return OrderFee(CashAmount(fee, "USD"))