ゆとり世代の自由研究

勉強が一生終わりません

sqliteとbacktesting.py

from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA
from pandas_datareader import data
import pandas as pd
import numpy as np
import datetime as dt
import sqlite3

# 変更する部分:複数の銘柄コードをリストで指定
codes = ['6927', '6752', '3607', '7014']
start = '2021/01/01'
end = dt.date.today()  # 取得終了日

# SQLiteデータベースに接続
conn = sqlite3.connect('stock_data.db')

# 変更する部分:各銘柄コードに対して繰り返し処理
for code in codes:
    df = data.DataReader(code+'.JP', 'stooq', start, end)

    # DataFrameをSQLiteデータベースに保存
    df.to_sql('stock_data_' + code, conn, if_exists='replace', index=True)

# データベース接続を閉じる
conn.close()


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

    def init(self):  # 初期設定
        price = self.data.Close
        self.ma1 = self.I(SMA, price, self.n1)
        self.ma2 = self.I(SMA, price, self.n2)

    def next(self):  # 売買条件
        if crossover(self.ma1, self.ma2):
            self.buy()
        elif crossover(self.ma2, self.ma1):
            self.sell()
            # self.position.close(): 保有ポジションの手仕舞


# 変更する部分:各銘柄コードに対して繰り返し処理
for code in codes:
    # SQLiteデータベースからデータを読み込む
    conn = sqlite3.connect('stock_data.db')
    query = f"SELECT * FROM stock_data_{code}"
    df = pd.read_sql_query(query, conn)
    conn.close()

    # Backtestを使用して戦略を実行
    bt = Backtest(df, SmaCross, cash=200000, commission=.002,
                  exclusive_orders=True)
    stats = bt.run()
    bt.plot()

    print(stats)

    # 最適化
    output2 = bt.optimize(n1=range(10, 70, 5), n2=range(10, 70, 5))
    print(output2)
    bt.plot()
    print(output2._strategy)