Overall Statistics |
Total Orders 1173 Average Win 4.23% Average Loss -2.59% Compounding Annual Return 55.527% Drawdown 57.600% Expectancy 0.340 Start Equity 100000 End Equity 7598293.77 Net Profit 7498.294% Sharpe Ratio 1.135 Sortino Ratio 1.011 Probabilistic Sharpe Ratio 46.684% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 1.63 Alpha 0.411 Beta 0.403 Annual Standard Deviation 0.391 Annual Variance 0.153 Information Ratio 0.918 Tracking Error 0.396 Treynor Ratio 1.102 Total Fees $209888.75 Estimated Strategy Capacity $680000.00 Lowest Capacity Asset BTCUSD 2XR Portfolio Turnover 32.47% |
# https://quantpedia.com/strategies/mean-reversion-and-trend-following-based-on-min-and-max-in-btc/ # # The investment universe consists of Bitcoin, and the data are obtained from the Gemini exchange. As the first step, at day t, calculate the past ten-days maximum (MAX) and minimum (MIN) price (including the price at day t). # If the price at day t is equal to the MAX, long the BTC and hold the position for one day. If the price at day t is equal to the MIN, long the BTC and hold the position for one day. # # QC implementation changes: # - BTC data are obtained from Coinbase (GDAX) exchange. # - Daily close is considered at US session UTC close time. # region imports from AlgorithmImports import * # endregion class MeanreversionandTrendFollowingBasedonMINandMAXinBTC(QCAlgorithm): def Initialize(self): self.SetStartDate(2015, 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:Crypto = self.AddCrypto("BTCUSD", Resolution.Minute, Market.GDAX) self.crypto.SetLeverage(10) self.crypto.SetFeeModel(CustomFeeModel()) self.crypto:Symbol = self.crypto.Symbol self.period:int = 10 self.daily_prices:RollingWindow = RollingWindow[float](self.period) self.daily_close_hour:int = 22 def OnData(self, data): if self.crypto in data and data[self.crypto]: time:datetime.datetime = self.Time if time.hour == self.daily_close_hour and time.minute == 0: price:float = data[self.crypto].Value self.daily_prices.Add(price) if self.daily_prices.IsReady: daily_prices:list[float] = [x for x in self.daily_prices] daily_max:float = np.max(daily_prices) daily_min:float = np.min(daily_prices) # open/rebalance long position if price == daily_max or price == daily_min: self.SetHoldings(self.crypto, 1) else: # close position 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"))