backtesting.py icon indicating copy to clipboard operation
backtesting.py copied to clipboard

Why Sharpe, Sortino and Calmar Ratio all show 0?

Open jefferror404 opened this issue 1 year ago • 2 comments

Expected Behavior

I am using the backtesting.py to carry out a simple backtest strategy about the simple moving average crossing. But Sharpe, Sortino and Calmar Ratio all show 0. What's wrong with my code or data? Kindly ask for your help. The 3 ratios show proper values when I used the test GOOG dataset from the library, which is in daily interval. My data is in 5minute interval.

Not sure if the issue is related to the timestamp column of my dataset which is a csv. On the other hand, I tried to use a dataset from yfinance python library for AAPL which loads the data and datetimeindex automatically and the analysis runs properly with the all the 3 ratios shown. However, in my original dataset, I have to use below to set the timestamp column and index.

A subset of the csv data from binance is here: https://drive.google.com/file/d/1y3cfelTStSOjjPxhM7ZnXwnoV7fYvRbC/view?usp=drive_link

Steps to Reproduce

btc['timestamp'] = pd.to_datetime(btc['timestamp'], format="%d/%m/%Y %H:%M")

btc.set_index('timestamp', inplace=True)

def SMA(values, n):
   return pd.Series(values).rolling(n).mean()

class SmaCross(Strategy):
  n1 = 5
  n2 = 10

  def init(self):
    self.sma1 = self.I(SMA, self.data.Close, self.n1)
    self.sma2 = self.I(SMA, self.data.Close, self.n2)


  def next(self):
    if crossover(self.sma1, self.sma2):
      self.position.close()
      self.buy(size=1)
    elif crossover(self.sma2, self.sma1):
      self.position.close()
      self.sell(size=1)

bt = Backtest(btc, SmaCross, cash = 1000000)
stats = bt.run()
print(stats)

Additional info

results data info data head

jefferror404 avatar Nov 01 '23 12:11 jefferror404

I am also uncertain if it is just because a negative sharpe ratio is not allowed. However, I do have a friend who runs another analysis which shows a negative sharpe ratio.

jefferror404 avatar Nov 01 '23 18:11 jefferror404

you need to add a date time column in and set that as the index prior to running your backtest:

df['datetime'] = pd.to_datetime(df['datetime']) df.set_index('datetime', inplace=True)

BL0987 avatar Jun 08 '24 21:06 BL0987