Skip to content

'Empty dataframe' when using a dataframe that has been imported from a file #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AlgoQ opened this issue Jul 23, 2020 · 3 comments
Closed
Labels
invalid This is not a (valid) bug report

Comments

@AlgoQ
Copy link

AlgoQ commented Jul 23, 2020

When I'm using another dataframe from a file an try out the backtesting Quick Start strategy I get the message at the parameter '_trades' that the Dataframe empty is, although it isn't.
Can someone help me out?

Code:

import numpy as np
import pandas as pd
import json

from backtesting import Strategy, Backtest
from backtesting.test import GOOG
from backtesting.lib import crossover

# Define ohlcv
with open('E:/Work/histCryptoDatafeed/ohlcv_binanceF_BTCUSDT_14days.json') as json_file:
    data = json.load(json_file)

ohlcv = pd.DataFrame(data, columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])
ohlcv['Date'] = pd.to_datetime(ohlcv['Date'], unit='ms')
ohlcv = ohlcv.set_index('Date')

def SMA(values, n):
    """
    Return simple moving average of `values`, at
    each step taking into account `n` previous values.
    """
    return pd.Series(values).rolling(n).mean()

class SmaCross(Strategy):
    # Define the two MA lags as *class variables*
    # for later optimization
    n1 = 5
    n2 = 10
    
    def init(self):
        # Precompute the two moving averages
        self.sma1 = self.I(SMA, self.data.Close, self.n1)
        self.sma2 = self.I(SMA, self.data.Close, self.n2)
    
    def next(self):
        # If sma1 crosses above sma2, close any existing
        # short trades, and buy the asset
        if crossover(self.sma1, self.sma2):
            self.position.close()
            self.buy()

        # Else, if sma1 crosses below sma2, close any existing
        # long trades, and sell the asset
        elif crossover(self.sma2, self.sma1):
            self.position.close()
            self.sell()
print(ohlcv)
bt = Backtest(ohlcv, SmaCross, cash=1000, commission=.0003)

stats = bt.run()

print(stats)

Output:

                        Open     High      Low    Close  Volume
Date
2020-07-09 08:16:00  9400.80  9400.81  9399.45  9399.77  20.350
2020-07-09 08:17:00  9399.78  9400.46  9398.36  9398.62  41.819
2020-07-09 08:18:00  9398.94  9399.87  9398.26  9399.87  24.911
2020-07-09 08:19:00  9399.87  9399.87  9398.31  9398.31  13.406
2020-07-09 08:20:00  9398.32  9399.80  9398.00  9398.20  86.632
...                      ...      ...      ...      ...     ...
2020-07-23 05:31:00  9480.73  9482.37  9480.00  9482.36  49.347
2020-07-23 05:32:00  9482.37  9482.50  9482.00  9482.01  11.154
2020-07-23 05:33:00  9482.01  9482.01  9480.90  9481.46   9.794
2020-07-23 05:34:00  9481.45  9482.00  9478.64  9479.04  67.269
2020-07-23 05:35:00  9479.03  9479.04  9478.33  9479.01  20.141

[20000 rows x 5 columns]
Start                     2020-07-09 08:16:00
End                       2020-07-23 05:35:00
Duration                     13 days 21:19:00
Exposure Time [%]                           0
Equity Final [$]                         1000
Equity Peak [$]                          1000
Return [%]                                  0
Buy & Hold Return [%]                0.842999
Max. Drawdown [%]                          -0
Avg. Drawdown [%]                         NaN
Max. Drawdown Duration                    NaN
Avg. Drawdown Duration                    NaN
# Trades                                    0
Best Trade [%]                            NaN
Worst Trade [%]                           NaN
Avg. Trade [%]                            NaN
Max. Trade Duration                       NaN
Avg. Trade Duration                       NaN
Profit Factor                             NaN
Expectancy [%]                            NaN
SQN                                       NaN
Sharpe Ratio                              NaN
Sortino Ratio                             NaN
Calmar Ratio                              NaN
_strategy                            SmaCross
_equity_curve                             ...
_trades                   Empty DataFrame
...
dtype: object

Zipped data file:
ohlcv_binanceF_BTCUSDT_14days.zip

  • Backtesting version:
    0.2.0
@kernc
Copy link
Owner

kernc commented Jul 26, 2020

Initial cash is 1000; prices are over 9000. Not a single unit can be bought.

@kernc kernc closed this as completed Jul 26, 2020
@kernc kernc added the invalid This is not a (valid) bug report label Jul 26, 2020
@AlgoQ
Copy link
Author

AlgoQ commented Jul 26, 2020

Oow okay, I thought it would buy smaller parts of a single unit. Good to know.

@kernc
Copy link
Owner

kernc commented Jul 27, 2020

Yeah, few asset classes allow fractional ownership. And buying size=0.1 of something in Backtesting.py already means "spend 10% of available equity". For crypto like Bitcoin, you need to trade in fractional units, e.g. satoshis.

kernc added a commit that referenced this issue Oct 13, 2020
Goblincomet pushed a commit to Goblincomet/forex-trading-backtest that referenced this issue Jul 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This is not a (valid) bug report
Projects
None yet
Development

No branches or pull requests

2 participants