大盤融資維持率|Plotly-多重圖組|DashBoard製作教學(3)

  • Post author:
  • Reading time:6 mins read

2022年4月到5月初受FED縮表、通膨超出預期、國內疫情爆發等利空因素引起殺盤,跌得昏天暗地,台積電差點跌破500元,更不用說體質更脆弱的小型股倒一片,OTC指數在2022年已回檔超過20%,融資斷頭ptt文齊發,令投資人煎熬。
可以抄底了沒?到底還要跌多久?是許多人想知道的問題。止跌的關鍵在不穩定籌碼被洗出了沒?只要投機籌碼仍多,股價就容易因利空產生恐慌急殺。

融資維持率是其中一個重要指標,該指標相關介紹可見“大盤融資維持率|地板指標幫你搶長線反彈|0050擇時策略優化?”,利用融資成數、融資保證金計算,正常水位為1.67,近期大盤融資維持率又跌到150上下的偏低水位,搭配融資餘額持續退場,可見浮動籌碼逐漸被洗出場,有機會開始逐底。
若之後融資維持率10日均線開始上揚、融資維持率突破10日均線,則多方籌碼才會再有凝聚現象,不再受到過大的套牢壓力籠罩後,才有機會出現像樣的反彈。
融資維持率不見得每個券商app都有,透過FinLab API與Plotly,我們可以輕易製作出客製化的圖表來觀察融資維持率,只要有Python的基礎都能輕易上手。

生成融資維持率

透過以下簡單的程式,我們能生成繪圖所需要用到的資料。

from finlab import data

融資今日餘額 = data.get('margin_transactions:融資今日餘額')
融資券總餘額 = data.get('margin_balance:融資券總餘額')
融資券總餘額 = 融資券總餘額.loc[融資今日餘額.index.intersection(融資券總餘額.index)]
融資券總餘額['上市融資買賣超'] = (融資券總餘額['上市融資交易金額']-融資券總餘額['上市融資交易金額'].shift()).fillna(0)/100000000
融資券總餘額['上櫃融資買賣超'] = (融資券總餘額['上櫃融資交易金額']-融資券總餘額['上櫃融資交易金額'].shift()).fillna(0)/100000000

close = data.get('price:收盤價')
benchmark = data.get('benchmark_return:發行量加權股價報酬指數').squeeze()
融資總餘額 = 融資券總餘額[['上市融資交易金額','上櫃融資交易金額']].sum(axis=1)
融資餘額市值 = (融資今日餘額*close*1000).sum(axis=1)
融資維持率 = (融資餘額市值/融資總餘額)
融資維持率

台股大盤融資指標圖組繪製

我們將用上述的資料套入Plotly製作動態圖組,一目瞭然市場動態,並學習使用plotly.layout去控制外觀與圖表互動工具。以下會對程式的細節提出重點講解。

目標結果

newplot 6
融資維持率

程式範例

#@title 台股大盤融資指標
start= '2020-01-01' #@param {type:"date"}
end = "2022-05-17" #@param {type:"date"}

import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np

df = 融資維持率.loc[(融資維持率.index>=start)&(融資維持率.index<=end)]
df2 = 融資券總餘額.loc[(融資券總餘額.index>=start)&(融資券總餘額.index<=end)]


fig = make_subplots(rows=3,
                    cols=1,
                    shared_xaxes=True,
                    vertical_spacing=0.05,
                    specs=[[{"secondary_y": True}],
                            [{"secondary_y": True}],
                            [{"secondary_y": True}],
                           
                           ],
                    subplot_titles=('融資維持率',
                                    '上市融資餘額',
                                    '上櫃融資餘額',

                                    )
                    )

date_index=df.index
benchmark_values=benchmark.reindex(df.index)

# 融資mt_rate
fig.add_trace(
    go.Scatter(x=date_index, y=benchmark_values, name="大盤加權報酬指數",line=dict(width=3)),
    secondary_y=False, row=1, col=1
)

fig.add_trace(
    go.Scatter(x=date_index, y=df.values, name="融資維持率"),
    secondary_y=True, row=1, col=1
)

fig.add_trace(
    go.Scatter(x=date_index, y=df.rolling(10).mean().values, name="融資維持率_ma10"),
    secondary_y=True, row=1, col=1
)


# 買賣超
fig.add_trace(
    go.Scatter(x=date_index, y=df2['上市融資交易金額'], fill='tozeroy',
                line=dict(width=0.5, color='#efd267'), name="上市融資餘額"),
    secondary_y=False, row=2, col=1
)

fig.add_trace(
    go.Bar(x=date_index, y=df2['上市融資買賣超'],
            marker_color=df2['上市融資買賣超'].apply(lambda s: 'red'  if s>0 else 'green' ), name="上市融資買賣超"),
    secondary_y=True, row=2, col=1
)


# otc買賣超
fig.add_trace(
    go.Scatter(x=date_index, y=df2['上櫃融資交易金額'], fill='tozeroy',
                line=dict(width=0.5, color='#efd267'), name="上櫃融資餘額"),
    secondary_y=False, row=3, col=1
)

fig.add_trace(
    go.Bar(x=date_index, y=df2['上櫃融資買賣超'],
            marker_color=df2['上櫃融資買賣超'].apply(lambda s: 'red'  if s>0 else 'green' ), name="上櫃融資買賣超"),
    secondary_y=True, row=3, col=1
)


# remove empty date(holiday)
dt_all = pd.date_range(start=date_index.values[0], end=date_index.values[-1])
# retrieve the dates that are in the original datset
dt_obs = [d.strftime("%Y-%m-%d") for d in pd.to_datetime(close.index)]
# define dates with missing values
dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d").tolist() if not d in dt_obs]
# hide dates with no values
fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])

# Add figure title


fig.update_layout(
    width=1500,
    height=800,
    title='台股大盤融資5',
    title_font_color="navy",
    title_font_size=20,
    hovermode='x unified',
    yaxis=dict(
        title='指數',
        showgrid=False
    ),
    yaxis2=dict(
        title='融資維持率',
    ),
    yaxis3=dict(
        title='price',
        showgrid=False
    ),
    yaxis4=dict(
        title='買賣超(億)',
    ),
    yaxis5=dict(
        title='price',
        showgrid=False
    ),
    yaxis6=dict(
        title='買賣超(億)',
    ),
        showlegend=True,
        xaxis=dict(
            rangeselector=dict(
                buttons=list([
                    dict(count=1,
                        label="1m",
                        step="month",
                        stepmode="backward"),
                    dict(count=6,
                        label="6m",
                        step="month",
                        stepmode="backward"),
                    dict(count=1,
                        label="YTD",
                        step="year",
                        stepmode="todate"),
                    dict(count=1,
                        label="1y",
                        step="year",
                        stepmode="backward"),
                    dict(count=3,
                        label="3y",
                        step="year",
                        stepmode="backward"),
                    dict(step="all")
                ])
            ),
            type="date"
        ),
        xaxis2=dict(
            type="date"
        ),
        xaxis3=dict(
            rangeslider=dict(
                visible=True
            ),
            type="date"
        ),
    )

fig.show()

多重子圖

plotly的make_subplots可控制多重圖組的畫布。
rows與cols參數控制畫布有多少張子圖,如此範例是三列一欄的子圖,繪圖物件的定位也依據此來設定。
shared_xaxes用來設定子圖是否要共用X軸,像此範例因有使用rangeslider做拉桿,希望拖動時間軸時,所有子圖能一起連動,所以設定為True。
vertical_spacing與horizontal_spacing參數為控制子圖間垂直與水平的間隙。
specs為設定圖組的格式,此範例因爲要設定雙Y軸縣市不同數據,有加入 {“secondary_y”: True}

融資維持率折線圖

畫布加入add_trace(xxx)的意思是加入子圖物件至大畫布裡,如以下程式是在第一列第一行 (也就是第一張子圖) 繪製融資維持率,並將數值對應到右側的Y軸,設定secondary_y=True。

fig.add_trace(
    go.Scatter(x=date_index, y=df.values, name="融資維持率"),
    secondary_y=True, row=1, col=1
)

餘額區域圖

區域圖又稱Filled Area Plot,使用go.Scatter(fill=’tozeroy’)即可將折線圖以下的區域設定填滿顏色。

買賣超長條圖

長條圖是用go.bar()來控制,這邊要注意長條圖顏色控制用融資買賣超的正負數來控制。

假日空值處理

plotly的小坑是時間序列若碰非連續,會有斷點。像台股資料週六、日未交易,圖表就會有被卡掉的現象。需用fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])來解決。

layout設定

設定畫布的大標題、長寬、子圖的X、Y軸細節,如showgrid只用每個子圖其中一個Y軸對應,不然雙Y軸對應會顯得雜亂。
rangeselector能產生圖標左上的日期選取按鈕工具列,點擊1m會將資料帶到近1月,點擊YTD會將資料帶到最近一年度之後的資料,如今天是2022-05-17,會將資料限縮在2022-01-01之後。
rangeslider則是子圖最下方的拉桿控制。

結語

plotly有許多互動圖表功能可使用,熟悉後就十分方便,能玩轉更種資料,將FinLab API延伸出更多應用。
融資籌碼指標除了大盤融資維持率,個股的維持率與斷頭指標的估算也能幫助我們判斷個股是否落底,靜待下回分曉囉

colab程式範例

Ben

Python 軟體工程師與量化策略研究員。 鑽研資料工程、網頁後端、資料視覺化、量化交易策略開發。 投資主力在台股市場,量化策略為主、質化分析為輔,追求人機攜做最佳化。逐步將觸角延伸到總經、美股、加密貨幣,朝更全方位的交易人邁進。