Skip to content

Instantly share code, notes, and snippets.

@e96031413
Created April 28, 2024 04:05
Show Gist options
  • Save e96031413/fed388c5bb2c31b040dfae195a4b6825 to your computer and use it in GitHub Desktop.
Save e96031413/fed388c5bb2c31b040dfae195a4b6825 to your computer and use it in GitHub Desktop.
Backtesting TW stock with pandas, backtesting, talib, and FinMind
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from FinMind.data import DataLoader
import pandas as pd
import talib
from talib import abstract
## 取得資料
dl = DataLoader()
df = dl.taiwan_stock_daily(stock_id='2330', start_date='2008-01-01', end_date='2023-1-1')
## 整理資料格式
df = df.rename(columns={"date": "Date"})
df.set_index("Date" , inplace=True)
df = df.set_index(pd.DatetimeIndex(pd.to_datetime(df.index)))
## backtesting.py 格式
df1 = df.rename(columns={"open": "Open", "max": "High", "min": "Low", "close": "Close", "Trading_Volume": "Volume"})
## ta-lib 格式
df2 = df.rename(columns={"max": "high", "min": "low", "Trading_Volume": "Volume"})
## 取得 KD 值
df_kd = abstract.STOCH(df2,fastk_period=9, slowk_period=3,slowd_period=3)
## 合併資料
df1 = pd.merge(df1, df_kd, on="Date")
"""
KD 策略(K<20買;K>80賣)
"""
class KdCross(Strategy):
def init(self):
super().init()
def next(self):
if crossover(20, self.data.slowk): ## K<20 買進
self.buy()
elif crossover(self.data.slowk, 80): ## K>80 平倉
self.position.close()
bt = Backtest(df1, KdCross, cash=10000, commission=0.001798) ## 交易成本 0.1798%
output = bt.run()
print(output)
bt.plot()
"""
跌破季線買進;K>80賣出
Strategy: 跌破60日均線買進, K>80賣出
"""
# class PriceBelowMAandKDJ(Strategy):
# def init(self):
# super().init()
# self.ma_60 = self.I(talib.MA, self.data.Close, timeperiod=60) # 60-day moving average
# def next(self):
# if self.data.Close < self.ma_60: # Price falls below 60-day MA
# self.buy()
# elif self.data.slowk > 80: # KDJ > 80
# self.position.close()
# bt = Backtest(df1, PriceBelowMAandKDJ, cash=10000, commission=0.001798) # 交易成本 0.1798%
# output = bt.run()
# print(output)
# bt.plot()
"""
跌破月線的兩個標準差買進;收盤價大於5日線的兩個標準差平倉
"""
## Calculate 20-day mean and standard deviation
# df1['5_Day_MA'] = df1['Close'].rolling(window=5).mean()
# df1['5_Day_STD'] = df1['Close'].rolling(window=5).std()
# df1['20_Day_MA'] = df1['Close'].rolling(window=20).mean()
# df1['20_Day_STD'] = df1['Close'].rolling(window=20).std()
# class MeanReversionStrategy(Strategy):
# def init(self):
# super().init()
# def next(self):
# if self.data.Close < self.data['20_Day_MA']:
# self.buy()
# elif self.data.Close > self.data['5_Day_MA']:
# self.position.close()
# bt = Backtest(df1, MeanReversionStrategy, cash=10000, commission=0.001798) # 交易成本 0.1798%
# output = bt.run()
# print(output)
# bt.plot()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment