LSTM除了用在 NLP 外,亦可應用在語音辨識,語言翻譯等。每次在做資料分析之前,資料收集都是困難且費時難。
本篇說明台灣股市的預測,而台股的預測需要收盤價及交易量,可以由 tejapi 及 yfinance 二個套件取得。tejapi 需要付費,而 yfinance 則是免費的,所以建議使用 yfinance。
tejapi
tejapi 是台灣經濟新報 TEJ 推出的套件,需要付費,但可以申請試用。試用可下載的資料有限,所以不建議使用,本段只是作為記錄而以。
請到 TEJAPI 網站 https://api.tej.com.tw/trial.html 申請試用金鑰,申請時會傳送驗証碼到手機中,然後會將金鑰傳送到 eMail 中。
這組金鑰只能下載試用資料庫,資料庫名稱及欄位請由 https://api.tej.com.tw/datatables.html?db=TRAIL&t=%E8%A9%A6%E7%94%A8%E8%B3%87%E6%96%99%E5%BA%AB 查詢。我們選擇 “上市(櫃)未調整股價(日)” 查詢台積電的股價,試用金鑰只能查到 2022 一整年的資料。
請先安裝tejapi套件
pip install tejapi
程式碼使用 tejapi.get 取得資料,傳回的資料為 panda 格式,代碼如下
import tejapi import pandas as pd def getData(coid): tejapi.ApiConfig.api_key = "your key" tejapi.ApiConfig.ignoretz = True mdate={'gte':'2020-01-01', 'lte':'2023-12-31'} opts={'columns': ['coid','mdate','open_d','high_d','low_d','close_d','amount']} data = tejapi.get('TRAIL/TAPRCD', coid = coid, mdate=mdate, opts=opts, paginate=True) return data display=pd.options.display display.max_columns=None display.max_rows=None display.width=None display.max_colwidth=None print(getData(2330)) 結果: coid mdate open_d high_d low_d close_d amount None 0 2330 2022-01-03 619.0 632.0 618.0 631.0 4.624972e+07 1 2330 2022-01-04 645.0 656.0 644.0 656.0 5.918820e+07 2 2330 2022-01-05 669.0 669.0 646.0 650.0 4.758283e+07 3 2330 2022-01-06 638.0 646.0 636.0 644.0 3.681764e+07 4 2330 2022-01-07 643.0 646.0 632.0 634.0 2.535824e+07 5 2330 2022-01-10 628.0 645.0 627.0 643.0 2.505214e+07 6 2330 2022-01-11 646.0 651.0 639.0 651.0 2.336159e+07 .......
Yahoo Finance
Yahoo Finance 提供 yfinance 套件讓 Python 可以免費下載台股資訊,這是最好用的套件。
安裝套件指令如下
pip install yfinance
yf.Ticker() 函數可以下載美股的資訊。
yf.download() 函數可下載台股資訊,函數中的 tickers 參數需給定要下載的股票代碼,比如
大盤 : “^TWII”
台積電 : “2330.TW”
電子股 : ” ^TELI”
相關股票代號可以由 https://tw.stock.yahoo.com/t/idx.php 查詢
下載代碼如下
import yfinance as yf import pandas as pd display=pd.options.display display.max_columns=None display.max_rows=None display.width=None display.max_colwidth=None #df = yf.Ticker('AAPL').history(period = 'max') df=yf.download("^TWII", start="2023-10-01", end="2023-10-22") print(df) 結果: [*********************100%%**********************] 1 of 1 completed Date Open High Low Close Adj Close Volume 2023-10-02 16382.959961 16575.310547 16382.959961 16557.310547 16557.310547 2669600 2023-10-03 16520.240234 16571.660156 16453.800781 16454.339844 16454.339844 2697100 2023-10-04 16419.480469 16419.480469 16203.339844 16273.379883 16273.379883 2624800 2023-10-05 16313.889648 16477.609375 16313.889648 16453.519531 16453.519531 2503200 2023-10-06 16482.929688 16539.130859 16482.929688 16520.570312 16520.570312 2296800 2023-10-11 16567.429688 16729.500000 16567.429688 16672.029297 16672.029297 3635100 2023-10-12 16698.849609 16825.910156 16684.429688 16825.910156 16825.910156 2917100 2023-10-13 16815.910156 16815.910156 16726.429688 16782.570312 16782.570312 2955800 2023-10-16 16712.929688 16712.929688 16614.099609 16652.240234 16652.240234 2843500 2023-10-17 16678.279297 16770.640625 16618.300781 16642.550781 16642.550781 2965400 2023-10-18 16608.019531 16612.250000 16398.759766 16440.910156 16440.910156 3844900 2023-10-19 16416.539062 16479.349609 16382.400391 16452.730469 16452.730469 2608200 2023-10-20 16434.429688 16462.560547 16271.820312 16440.720703 16440.720703 3035200
yfinance 共有Date(日期)、Open(開盤)、High(最高)、Low(最低)、Close(收盤)、Adj Close(盤後交易)、Volume(交易量) 共 7 個欄位。
完整代碼
底下可繪出黃金期貨走勢圖及預測值,請先安裝如下套件
pip install plotly yfinance scikit-learn pandas
完整代碼如下
from datetime import datetime, timedelta import pandas as pd from dateutil.relativedelta import relativedelta from sklearn.linear_model import LinearRegression display=pd.options.display display.max_columns=None display.max_rows=None display.width=None display.max_colwidth=None import yfinance as yf import plotly.graph_objects as go """ 大盤 : ^TWII 黃金期貨 : GC=F """ stock='GC=F' df=yf.download(stock, start='2023-10-01', end='2024-05-12') fig=go.Figure() fig.add_trace( go.Scatter( x=df.index, y=df['Close'].values, mode='lines', name='實際價格', line=dict(color='royalblue', width=2) ) ) ma1=5#5日平均線 ma2=10#10日平均線 df=df.dropna() df['s1']=df['Close'].rolling(window=ma1).mean() df['s2']=df['Close'].rolling(window=ma2).mean() df=df.dropna() train=df[['Close','s1','s2']] train['next_day_price']=train['Close'].shift(-1) train=train.dropna() x_train=train[['s1', 's2']] y_train=train['next_day_price'] model=LinearRegression() model.fit(x_train, y_train) df['predict_price']=model.predict(df[['s1', 's2']]) pred=df[['predict_price']] s=(pred.tail(1).index+timedelta(days=1))[0] dates=pd.date_range(s, periods=1) pred.loc[dates[0]]=[0] pred['predict_price']=pred['predict_price'].shift(1) print(pred) fig.add_trace( go.Scatter( x=pred.index, y=pred['predict_price'].values, mode='lines', name='AI預測', line=dict(color='orange', width=1) ) ) current = datetime.now() xrange = [(current - relativedelta(months=6)).strftime("%Y-%m-%d"), current.strftime("%Y-%m-%d")] yrange = [df['Close'].tail(180).min(), df['Close'].tail(180).max()] fig.update_layout( dragmode="pan", xaxis=go.layout.XAxis( range=xrange, rangeselector=dict( buttons=list([ dict(count=1, label="1 month", step="month", stepmode="backward"), dict(count=6, label="6 month", step="month", stepmode="backward"), dict(count=1, label="1 year", step="year", stepmode="backward"), dict(count=1, label="1 day", step="day", stepmode="todate"), dict(step="all") ]) ), rangeslider=dict( visible=True ), type="date" ), yaxis=dict( fixedrange=False, range=yrange ) ) fig.show()