kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
https://kernc.github.io/backtesting.py/
GNU Affero General Public License v3.0
5.07k stars 991 forks source link

`buy()` method does not work. #510

Open arturnawrot opened 2 years ago

arturnawrot commented 2 years ago

When I'm importing data from Coinbase API (you don't need any API keys to reproduce the issue, just copy-paste the snippet below) self.buy() and self.sell() do not work at all. Although self.plot() works flawlessly and the data is normally plotted, trades are not executed at all. Possibly there's something wrong with data formatting but it does not return any warning nor errors, so I'm not sure whether it's an issue with my data or the backtesting.py library.

When I used Forex data for this script then everything worked.

You may need to install cbpro pip install cbpro

import pandas as pd
from backtesting import Strategy
from backtesting import Backtest
import pandas as pd
import cbpro

public_client = cbpro.PublicClient()

data = public_client.get_product_historic_rates('ETH-USD', granularity=900)

# data = [
#   [1634928300, 3964.4, 3975.74, 3968.12, 3965.88, 624.23484212],
#   [1634927400, 3940.56, 3973.95, 3942.74, 3968.12, 3112.89691445],
#   [1634926500, 3915.02, 3948.26, 3931.91, 3942.69, 2164.6179708] ... and more
# ]

data = pd.DataFrame(data)
data.columns= ["Date","Low","High","Open","Close","Volume"]
data['Date'] = pd.to_datetime(data['Date'], unit='s')
data.set_index('Date', inplace=True)

# data
# Date                 Low      High     Open     Close    Volume
# 2021-10-22 18:45:00  3956.44  3975.74  3968.12  3962.28  1056.597933
# 2021-10-22 18:30:00  3940.56  3973.95  3942.74  3968.12  3112.896914
# 2021-10-22 18:15:00  3915.02  3948.26  3931.91  3942.69  2164.617971
# ... and more

class SmaCross(Strategy):

    def init(self):
        pass

    def next(self):
        self.buy(limit=4100, tp=4500, sl=3900) 
       # even self.buy() without any parameters does not work, but with Forex data it executes at the very beginning and ends
       # on the last candle.

bt = Backtest(data, SmaCross, cash=1000)

stats = bt.run()

print(stats)

bt.plot(resample=False)

# stats
# Start                     2021-10-19 16:15:00
# End                       2021-10-22 19:00:00
# Duration                      3 days 02:45:00
# Exposure Time [%]                         0.0
# Equity Final [$]                       1000.0
# Equity Peak [$]                        1000.0
# Return [%]                                0.0
# Buy & Hold Return [%]                4.345899
# Return (Ann.) [%]                         0.0
# Volatility (Ann.) [%]                     0.0
# Sharpe Ratio                              NaN
# Sortino Ratio                             NaN
# Calmar Ratio                              NaN
# Max. Drawdown [%]                        -0.0
# Avg. Drawdown [%]                         NaN
# Max. Drawdown Duration                    NaN
# Avg. Drawdown Duration                    NaN
# # Trades                                    0
# Win Rate [%]                              NaN
# Best Trade [%]                            NaN
# Worst Trade [%]                           NaN
# Avg. Trade [%]                            NaN
# Max. Trade Duration                       NaN
# Avg. Trade Duration                       NaN
# Profit Factor                             NaN
# Expectancy [%]                            NaN
# SQN                                       NaN
# _strategy                            SmaCross
# _equity_curve                             ...
# _trades                   Empty DataFrame
# ...
# dtype: object
kernc commented 2 years ago

Do you see any warnings issued?

arturnawrot commented 2 years ago

No

kernc commented 2 years ago

I believe you should have seen this warning printed: https://github.com/kernc/backtesting.py/blob/267d99f0d48745acf98156b2e69150c02d42f761/backtesting/backtesting.py#L1073-L1077 See https://github.com/kernc/backtesting.py/issues/134.

stellenberger commented 3 weeks ago

For anyone having this issue; the size of the buy needs to be set to 1, and you need to give it enough cash to buy whole bitcoins. Just times the BTC price by 10.