Skip to content

Instantly share code, notes, and snippets.

@e96031413
Created September 19, 2023 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save e96031413/90fe56da5a3a591ca5c28bb4b0b95107 to your computer and use it in GitHub Desktop.
Save e96031413/90fe56da5a3a591ca5c28bb4b0b95107 to your computer and use it in GitHub Desktop.
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='0050', start_date='2020-01-01', end_date='2023-06-01')
## 整理資料格式
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