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.06k stars 990 forks source link

Trying to use backtesting.py to backtest sentiment analysis. Using timestamps and sentiment. #1026

Open jontstaz opened 11 months ago

jontstaz commented 11 months ago

Hi all,

I've got a strategy which essentially analyses articles about a particular cryptocurrency as they are posted and determines whether the sentiment is positive or negative. It's rudimentary but what I want to do is as follows.

I have a csv file containing ms timestamps with a corresponding sentiment ("positive" or "negative") on each line. I also have a function which downloads 1m kline data from Binance between the start_date and end_date which is used as the data.

I want to run the backtest and execute a self.buy() whenever there's a "positive" sentiment for a timestamp which falls within the current kline or execute a self.sell() whenever there's a "negative" sentiment for a timestamp.

How can I achieve this? I was looking for some param in the docs which keeps track of/indicates the time the backtest is up to. Thanks in advance/

jontstaz commented 11 months ago

I think I may have figured it out. Here's what I'm thinking:

import backtesting
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA
import pandas as pd

class SentimentStrategy(Strategy):
    def __init__(self):
        super().__init__()
        self.sentiment_data = pd.read_csv('sentiment_data.csv', names=['timestamp', 'sentiment'], index_col=0, parse_dates=True)

    def next(self):
        current_timestamp = self.data.index[-1].timestamp()
        sentiment = self.sentiment_data.loc[self.sentiment_data.index <= current_timestamp].tail(1)['sentiment'].values[0]

        if sentiment == 'positive':
            self.buy()
        elif sentiment == 'negative':
            self.sell()

data = load_binance_data(start_date, end_date)  # downloads Binance 1m Kline data and stores it in dataframe with Columns(Timestamp, Open, High, Low, Close, Volume)
bt = Backtest(data, SentimentStrategy)
result = bt.run()

result.plot()
print(result)

Keep in mind the may not run as I'm on my phone at the moment and haven't tested the code but the logic is there.