庫藏股實施家數|崩盤後的長線抄底訊號|左側交易|

可以彎腰撿鑽石了沒?你怕不怕是接到刀子?

近期事件

新冠肺炎強襲台灣,讓最近波動很大的台股再度面臨破底考驗,市場恐慌的逃命情緒和搶買全聯物資的人潮不相上下,台股在2021年5月上旬急速回檔近10%,下跌過程除了創了盤中最大跌點,也讓年初許多“少年股神”哀鴻遍野。

只要你是倉位較滿的投資人,很難躲過這波沙盤,系統性風險一樣會讓績優成長股崩盤,差別可能在大盤下跌30%,你的投資組合下跌25%。

空頭趨勢總是來的兇猛,想抄底又怕天天都便宜,買到沒錢陷入崩潰,不是每個人都像巴爺爺一樣能本多忠勝,承受左側交易的心理壓力,有沒有指標可以顯現底部將近?讓你抄底抄的有策略,相對能安心有個底?

金管會救市三步

1.鼓勵企業實施庫藏股

2.限空令 or 找法人喝咖啡

3.國安感冒糖漿(國家金融安定基金)

今天主要來套討第一步“鼓勵企業實施庫藏股”,這招對政府最省事,因為不用自己出一毛錢就可能有效果。企業內部人往往對自家公司價值最了解,有些又有質押股票面臨市值下修的壓力。一般來說,庫藏股這類回燒公司資金的事,經營者多會考量價格是否合理(進入低檔)?少部分高檔買庫藏股的企業,要多想想是何居心?

程式驗證

爬蟲

這招有沒有效,寫程式來驗證最快。首先我們要先到公開觀測資訊站取得資料,使用request.post提交查詢表單內容來抓上市櫃庫藏股資料,程式如下:

import pandas as pd
import numpy as np
from datetime import datetime,timedelta
import requests


def combine_index(df, n1, n2):
    """將dataframe df中的股票代號與股票名稱合併

    Keyword arguments:

    Args:
        df (pandas.DataFrame): 此dataframe含有column n1, n2
        n1 (str): 股票代號
        n2 (str): 股票名稱

    Returns:
        df (pandas.DataFrame): 此dataframe的index為「股票代號+股票名稱」
    """

    return df.set_index(df[n1].str.replace(' ', '') + \
                        ' ' + df[n2].str.replace(' ', '')).drop([n1, n2], axis=1)


def crawl_treasury_stock(days=200):
    now =datetime.now().strftime('%Y%m%d')
    end = (datetime.now() - timedelta(days)).strftime('%Y%m%d')
    date_now = str(int(now[:4]) - 1911) + now[4:]
    date_end = str(int(end[:4]) - 1911) + end[4:]

    data = []
    for market_name in ["sii", "otc"]:
        url = 'https://mops.twse.com.tw/mops/web/t35sc09'
        form_data = {
            "encodeURIComponent": "1",
            "step": "1",
            "firstin": "1",
            "off": "1",
            "TYPEK": market_name,
            "d1": date_end,
            "d2": date_now,
            "RD": "1",
        }

        res = requests.post(url, form_data)
        page_count = len(pd.read_html(res.text))
        page_start = 11
        page_end = page_count - 2
        df = pd.concat([pd.read_html(res.text)[n] for n in range(page_start, page_end)])
        data.append(df)

    df_all = pd.concat(data)
    df_all = df_all.astype(str)
    df_all.columns = ['序號', 'stock_id', '公司名稱', 'date', '買回目的', '買回股份總金額上限',
                      '預定買回股數', '買回價格區間-最低', '買回價格區間-最高', '預定買回期間-起', '預定買回期間-迄', '是否執行完畢',
                      '買回達一定標準資料', '本次已買回股數', '本次執行完畢已註銷或轉讓股數',
                      '本次已買回股數佔預定買回股數比例(%)', '本次已買回總金額',
                      '本次平均每股買回價格', '本次買回股數佔公司已發行股份總數比例(%)', '本次未執行完畢之原因']

    df_all = df_all.drop(columns=['序號', '買回達一定標準資料'])

    def date_process(columns_name):
        df_all[columns_name] = df_all[columns_name].apply(lambda s: s.replace('/', '-')).apply(
            lambda s: datetime.strptime(str(int(s[:s.index('-')]) + 1911) + s[s.index('-'):], '%Y-%m-%d'))

    for i in ['date', '預定買回期間-起', '預定買回期間-迄']:
        date_process(i)
    float_list = ['買回股份總金額上限', '預定買回股數', '買回價格區間-最低', '買回價格區間-最高',
                  '本次已買回股數', '本次執行完畢已註銷或轉讓股數', '本次已買回股數佔預定買回股數比例(%)',
                  '本次已買回總金額', '本次平均每股買回價格', '本次買回股數佔公司已發行股份總數比例(%)']
    df_all[float_list] = df_all[float_list].apply(lambda s: pd.to_numeric(s, errors='coerce')).fillna(0)
    df_all['買回目的'] = ['轉讓股份予員工' if i == "1" else '股權轉換' if i == "2" else '維護公司信用及股東權益' for i in df_all['買回目的']]
    df_all = combine_index(df_all, "stock_id", "公司名稱")
    df_all.index.name = 'stock_id'
    df_all = df_all.reset_index()
    df_all = df_all.set_index(['stock_id', 'date'])
    sort_multi=df_all.index.sortlevel(1,sort_remaining=True)
    treasury_stock=df_all.loc[sort_multi[0]]
    return treasury_stock

清理資料及繪圖

plan_vol=data.get('treasury_stock:預定買回股數')
plan_vol=plan_vol.unstack().dropna()
plan_vol=plan_vol.reset_index()
plan_vol.columns=['stock_id','date','plan_vol']

# 次月1日得知上月統計家數,取標準差抓庫藏股家數特多的極值月份為訊號
plan_vol['date']=plan_vol['date']+ pd.DateOffset(months=1)
plan_vol['year_month']=plan_vol['date'].apply(lambda s:datetime(s.year,s.month,1))
count_num=plan_vol.groupby(['year_month']).count().iloc[:,0].to_frame()
count_num['signal'] = ['crimson' if x > int(count_num.mean()+1.5*np.std(count_num).values) else 'darkcyan' for x in count_num.iloc[:,0]]
count_num=count_num.reset_index()
count_num=count_num.rename(columns={'stock_id':'count'})

將上市櫃的庫藏股實施情況統計一下,發現前月庫藏股實施家數超過1.5個標準差時,會浮現長線(月週期)買點,但之後會不會馬上走長多就不一定了,2008年金融海嘯時,跌到半山腰,就很多企業實施庫藏股,卻仍檔不住強大賣壓,連續數月多家公司實施庫藏股後才止跌回升,長期來看仍是相對低點。

而在其他幾波,像是去年歐美疫情最慘烈的3月,該訊號再度浮現,只出現一次就止跌,拉出另一波強勢多頭。

那最近該指標有無閃出訊號?看來是沒有。

最近政府接連出招,目前這波只有國安基金說會密切注意市場的消息,還在口水護盤的情況。未來若進一步出現大跌,該指標會不會出現紅棒訊號呢?讓我們繼續觀察,可以使用置底的程式來看相關圖標訊號。

結論:

長期投資攤平的策略可觀察庫藏股實施家數的月統計狀況做第一波買進切入,在實施家數大增時,標的若有公司派護盤,籌碼面會相對抗跌,可以另外拉出當月宣佈開始執行庫藏股的公司。

國安基金的進場時機常接在該訊號之後,因此若對選股不太有把握,指數型基金與權值股會是抓大盤反彈行情的最佳選擇

Colab程式碼連結

喜歡我們的文章的話,那更別錯過我們精心製作的優質系列課程喔!

上一篇
下一篇

Genie

Python elf, love magic of python. Explore the financial world.