<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>pandas &#8211; FinLab</title>
	<atom:link href="https://www.finlab.tw/tag/pandas/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.finlab.tw</link>
	<description>深入淺出的量化投資，讓你在在茫茫股海中，找到專屬於自己的投資方法</description>
	<lastBuildDate>Thu, 22 Dec 2022 07:29:01 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.9</generator>

<image>
	<url>https://www.finlab.tw/wp-content/uploads/2020/07/favicon.png</url>
	<title>pandas &#8211; FinLab</title>
	<link>https://www.finlab.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">179699571</site>	<item>
		<title>產業資料庫的基礎應用</title>
		<link>https://www.finlab.tw/industry_themes_database_basic_application/</link>
					<comments>https://www.finlab.tw/industry_themes_database_basic_application/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Tue, 20 Dec 2022 06:35:19 +0000</pubDate>
				<category><![CDATA[FinLab 量化平台]]></category>
		<category><![CDATA[Python新手教學]]></category>
		<category><![CDATA[基本面分析]]></category>
		<category><![CDATA[生產力]]></category>
		<category><![CDATA[pandas]]></category>
		<category><![CDATA[台股]]></category>
		<category><![CDATA[產業分析]]></category>
		<category><![CDATA[資料處理]]></category>
		<guid isPermaLink="false">https://www.finlab.tw/?p=4971</guid>

					<description><![CDATA[這篇教學文章將說明FinLab的「產業題材資料庫」的簡單應用，並教你如何用 Python 與 Pandas 基礎語法去「客製化」自己的產業分類，讓產業資料庫更豐富]]></description>
										<content:encoded><![CDATA[
<p class="has-medium-font-size">產業資料庫重要嗎？如果你想讓選股技巧更上一層樓，勢必會進階到產業分析。<br>投資標的的優劣評價，除了自己跟自己比，例如近期財報是否較過去改善，另一個判斷企業競爭力的評價方式，就是跟同業比，好壞都是比較而來的，選對比較基準才讓評價有意義。<br>除了同業個股比較，產業資料庫的另一個主要應用在找出族群趨勢，如果一個產業的企業的營收或股價趨勢都向上，那代表該產業蒸蒸日上，有產業景氣良好的基本面護體，更能增加投資判斷把握度與可解釋性，排除單一個股炒作的個別性，更進階的應用甚至可延伸到概念股落後補漲效應。<br>這一切的應用的基礎都建構在「產業資料庫」的分類，這篇教學文章將說明FinLab的「<a href="https://ai.finlab.tw/database#security_industry_themes" target="_blank" rel="noopener">產業題材資料庫</a>」的簡單應用，並教你如何用 Python 與 Pandas 基礎語法去「客製化」自己的產業分類，讓產業資料庫更豐富。</p>



<h2>產業資料</h2>



<p class="has-medium-font-size">FinLab 的細產業主題資料來源主要取自「<a href="https://ic.tpex.org.tw/" target="_blank" rel="noreferrer noopener">產業價值鍊資訊平台</a>」，少部分為自定義分類。從&nbsp;<a href="https://ai.finlab.tw/database#security_industry_themes" target="_blank" rel="noreferrer noopener">FinLab資料庫</a>&nbsp;只要一行程式碼就能下載全部的細產業資訊，讓你輕鬆以此基礎做後續應用。要注意的是此份資料僅限&nbsp;<a href="https://ai.finlab.tw/pricing" target="_blank" rel="noreferrer noopener">VIP</a>&nbsp;使用。<br><a href="https://ic.tpex.org.tw/" target="_blank" rel="noreferrer noopener">產業價值鍊資訊平台</a>&nbsp;會將主產業再分拆上下游的細產業，讓你更精細的去比較，否則證交所一般分類光半導體就近百檔，比較效果相對籠統。</p>



<figure class="wp-block-image"><img src="https://www.finlab.tw/wp-content/uploads/2022/11/%E6%88%AA%E5%9C%96-2022-11-02-%E4%B8%8A%E5%8D%887.30.52-1024x404.png" alt="截圖 2022 11 02 上午7.30.52" class="wp-image-4756" title="產業面選股策略｜同業本益比比較法 1"/><figcaption>資料庫欄位</figcaption></figure>



<p class="has-medium-font-size">每家公司所屬產業的資訊放在 catergory 內，category 欄位的型態是文字格式，所有產業分類會放入 List 後再包成文字型態，從該資料得知公司分別有哪些產業的標籤。<br>例如1101台泥的產業序列裡有主產業的水泥，也有細產業「水泥:水泥成品」、「水泥:水泥熟料」(格式為「主產業:細產業 or 主產業」)。</p>



<figure class="wp-block-image"><img src="https://www.finlab.tw/wp-content/uploads/2022/11/%E6%88%AA%E5%9C%96-2022-11-02-%E4%B8%8A%E5%8D%887.35.04-1024x810.png" alt="截圖 2022 11 02 上午7.35.04" class="wp-image-4757" title="產業面選股策略｜同業本益比比較法 2"/></figure>



<h2>簡單查詢應用</h2>



<p class="has-medium-font-size">如果我們想查詢哪些公司屬於水泥產業？我們可以運用pandas內的 <a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.str.contains.html" target="_blank" rel="noopener">Series.str.contains</a>，讓我們快速分類出產業名單，如下範例，只要「category」欄位內含「水泥」兩字，就會被納入範圍。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">from finlab import data
from finlab.backtest import sim

# 取出產業題材
themes = data.get('security_industry_themes')

# 選出產業包含「水泥」的公司
ind1 = themes[themes['category'].str.contains('水泥')]
</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="513" src="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55-1024x513.png" alt="截圖 2022 12 20 下午12.36.55" class="wp-image-4972" srcset="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55-1024x513.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55-300x150.png 300w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55-768x384.png 768w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55-1536x769.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.36.55.png 1894w" sizes="(max-width: 1024px) 100vw, 1024px" title="產業資料庫的基礎應用 1"></figure>



<p class="has-medium-font-size">contains 語法支援 or 的運用，如果我們今天想選出產業包含「水泥」或「建材營造」的公司，可以使用以下語句，使用&#8217;|&#8217;的符號做邏輯運算串連：</p>



<p class="has-medium-font-size"> <code>ind2 = themes[themes['category'].str.contains('水泥|建材營造')]</code> </p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="532" src="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-1024x532.png" alt="截圖 2022 12 20 下午12.37.48" class="wp-image-4973" srcset="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-1024x532.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-300x156.png 300w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-768x399.png 768w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-1536x799.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午12.37.48-2048x1065.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" title="產業資料庫的基礎應用 2"></figure>



<h2>簡單回測範例</h2>



<p class="has-medium-font-size">「想挑出水泥產業中，本益比低於水泥產業本益比中位數之個股當投資組合」</p>



<p class="has-medium-font-size">實作很簡單，用前述contains篩選的stock_id，套入本益比資料做欄位圈選，就能限定資料範圍，再運用 <code>median(axis=1)</code>，計算每日產業本益比中位數，axis=1的用途在取每一期(橫列)的中位數。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">from finlab import data
from finlab.backtest import sim

# 取出產業題材
themes = data.get('security_industry_themes')

# 選出產業包含「水泥」公司
ind = themes[themes['category'].str.contains('水泥')]
pe = data.get('price_earning_ratio:本益比')
ind_pe = pe[list(ind['stock_id'])]

# 計算每日產業本益比中位數,axis=1的用途在取每一期(橫列)的中位數
ind_pe_med = ind_pe.median(axis=1)

# 選出本益比小於同業本益比中位數且本益比小於25的公司
position = (ind_pe &lt; ind_pe_med) &amp; (ind_pe &lt; 25)

# 回測
report = sim(position, upload=False)
report.display()</code></pre>



<figure class="wp-block-image"><img loading="lazy" width="800" height="600" src="https://www.finlab.tw/wp-content/uploads/2022/11/newplot-2.png" alt="newplot 2" class="wp-image-4758" title="產業面選股策略｜同業本益比比較法 3" srcset="https://www.finlab.tw/wp-content/uploads/2022/11/newplot-2.png 800w, https://www.finlab.tw/wp-content/uploads/2022/11/newplot-2-300x225.png 300w, https://www.finlab.tw/wp-content/uploads/2022/11/newplot-2-768x576.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>



<h2>自定義產業分類</h2>



<p class="has-medium-font-size">有時我們發現產業價值鏈資訊平台的分類仍不能滿足需求，像是他缺少概念股的標籤資料，學會Python 的好處在我們可以任意擴展資料，去自定義新增的分類。<br>使用開發好的 create_new_industry_themes 的函式去創建新的產業分類，其中 additional_themes 變數控制新增標籤，格式為<code>[([目標群],[標籤群]),...]</code>。<br><br>例如以下範例對&#8217;6684&#8242;, &#8216;6756&#8217;, &#8216;3014&#8217; 新增 &#8216;元宇宙:祖克柏概念股&#8217; 的標籤，對&#8217;1342&#8242;, &#8216;1584&#8217;新增&#8217;航太週邊:空中巴士概念股&#8217;的標籤，對&#8217;2342&#8242;, &#8216;3317&#8217;, &#8216;4923&#8217;, &#8216;5299&#8217;, &#8216;6287&#8217; 增加兩個標籤&#8217;半導體:基礎元件&#8217;, &#8216;通訊產業:通訊元件&#8217;。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def add_sub_group(dataframe, stock_list: list, theme_list: list):
    try:
        dataframe.loc[stock_list]['category'] = dataframe.loc[stock_list]['category'].apply(
            lambda s: s.extend(theme_list))
    except KeyError:
        print('stock_list not in index.')
    return dataframe


def process_sub_group_list(sub_group_list):
    sub_group_list.extend(list(set({i[:i.index(':')] for i in sub_group_list if ':' in i})))
    return sorted(list(set(sub_group_list)))


def create_new_industry_themes(additional_themes):

    df = data.get('security_industry_themes')
    df = df.set_index(['stock_id', 'name'])
    df['category'] = df['category'].apply(lambda s: eval(s))

    if additional_themes:
        for stock_list, theme_list in additional_themes:
            df = add_sub_group(df, stock_list, theme_list)

    df['category'] = df['category'].apply(lambda s: process_sub_group_list(s))
    df = df.astype(str)
    df = df.reset_index()
    return df


additional_themes = [
    (['6684', '6756', '3014'], ['元宇宙:祖克柏概念股']),
    (['1342', '1584'], ['航太週邊:空中巴士概念股']),
    (['2342', '3317', '4923', '5299', '6287'], ['半導體:基礎元件', '通訊產業:通訊元件']),
]


new_themes = create_new_industry_themes(additional_themes)
# 檢查6684 是否成功新增標籤
new_themes[new_themes['stock_id']=='6684']['category'].values</code></pre>



<p class="has-medium-font-size"><br><br></p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="699" src="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42-1024x699.png" alt="截圖 2022 12 20 下午2.02.42" class="wp-image-4974" srcset="https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42-1024x699.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42-300x205.png 300w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42-768x524.png 768w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42-1536x1049.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/12/截圖-2022-12-20-下午2.02.42.png 1797w" sizes="(max-width: 1024px) 100vw, 1024px" title="產業資料庫的基礎應用 3"></figure>



<p class="has-medium-font-size">執行完含式後，會發現 new_themes 已有新增資料～之後就可以用自定義後的 new_themes  做產業分析囉！</p>



<h2>小結</h2>



<p class="has-medium-font-size"><a href="https://colab.research.google.com/drive/15PQ_W_6xUZ1lHlDWaNZtZgsUPZPMiove?usp=sharing" target="_blank" rel="noopener">colab程式範例</a><br><br>學會基礎的產業資料的資料處理技巧後，就可以進行許多分析與策略開發，像是「<a href="https://www.finlab.tw/industry_pe_strategy/">產業面選股策略｜同業本益比比較法</a>」就是延伸的應用喔！<br>如果有自己的產業分類標籤可以加入，那就會進化成個人獨有的資料，可能創造出不易被模仿的策略或產業觀察指標。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/industry_themes_database_basic_application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4971</post-id>	</item>
		<item>
		<title>國安基金與庫藏股應用教學｜政府軍急了嗎？</title>
		<link>https://www.finlab.tw/treasury_stock_national_security_fund/</link>
					<comments>https://www.finlab.tw/treasury_stock_national_security_fund/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Mon, 17 Oct 2022 05:37:42 +0000</pubDate>
				<category><![CDATA[籌碼面]]></category>
		<category><![CDATA[FinLab 量化平台]]></category>
		<category><![CDATA[Python新手教學]]></category>
		<category><![CDATA[VIP文章]]></category>
		<category><![CDATA[pandas]]></category>
		<category><![CDATA[Plotly]]></category>
		<category><![CDATA[國安基金]]></category>
		<category><![CDATA[庫藏股]]></category>
		<guid isPermaLink="false">https://www.finlab.tw/?p=4684</guid>

					<description><![CDATA[2022 可說是亂世風雲，中國防疫政策、俄烏戰爭、通膨、美國大幅升息、企業庫存暴增...等等利空連發重挫市場，許多市場指數到 2022年10月都回檔30%，台股也在護國神山走山下，從 18000 點下殺到 13000 點以下，明顯跌入熊市。
令人不安的是救市神主牌國安基金在 2022/7/12 已進場護盤，卻仍止不住跌勢，被質疑是否過早進場送頭？如果連最後一張王牌都無法扛住，那確實麻煩大了。
本篇文章將用 Finlab 模組 與 Pandas 實作 國安基金與庫藏股 的簡易趨勢分析，讓你更加熟悉 Pandas 各種財經時序資料處理的手法。最後輸出的結果，我們會看到國安基金這次是否和以往不一樣？]]></description>
										<content:encoded><![CDATA[
<p class="has-medium-font-size">2022 可說是亂世風雲，中國防疫政策、俄烏戰爭、通膨、美國大幅升息、企業庫存暴增&#8230;等等利空連發重挫市場，許多市場指數到 2022年10月都回檔30%，台股也在護國神山走山下，從 18000 點下殺到 13000 點以下，明顯跌入熊市。<br>令人不安的是救市神主牌國安基金在 2022/7/12 已進場護盤，卻仍止不住跌勢，被質疑是否過早進場送頭？如果連最後一張王牌都無法扛住，那確實麻煩大了。<br>本篇文章將用 Finlab 模組 與 Pandas 實作 <strong>國安基金與庫藏股</strong> 的簡易趨勢分析，讓你更加熟悉 Pandas 各種財經時序資料處理的手法。最後輸出的結果，我們會看到國安基金這次是否和以往不一樣？</p>



<h2>庫藏股資料處理</h2>



<p class="has-medium-font-size">透過FinLab資料庫，我們可取得庫藏股資訊，在之前的「<a href="https://www.finlab.tw/treasury-stock-signal/">庫藏股實施家數｜崩盤後的長線抄底訊號｜左側交易</a>」文章中有相關實作，不過上篇是用「董事會決議庫藏股的日期」當訊號，這次換示範另一種寫法，使用「庫藏股實施期間」來當訊號，更能精準反應當下有在護盤的公司大概的總家數。</p>



<h3>程式範例</h3>



<pre class="wp-block-code"><code lang="python" class="language-python">import pandas as pd
from finlab import data

預定買回期間_起 = data.get('treasury_stock:預定買回期間-起').unstack()
預定買回期間_迄 = data.get('treasury_stock:預定買回期間-迄').unstack()
# date 為董事會決議庫藏股日期
treasury_stock = pd.DataFrame({'預定買回期間_起':預定買回期間_起, '預定買回期間_迄':預定買回期間_迄}).dropna(how='all')
treasury_stock.index.names = ['stock_id', 'date']

# 產生實施期間序列
treasury_stock['period'] = [pd.date_range(s,e).to_list() for s,e in zip(treasury_stock['預定買回期間_起'],treasury_stock['預定買回期間_迄'])] 

# 使用 explode 展開資料
treasury_stock_period = treasury_stock.explode('period')
treasury_stock_period = treasury_stock_period[['period']]

# 計算每日預計實施庫藏股的公司家數
treasury_count = treasury_stock_period.groupby(['period'])['period'].count()
benchmark = data.get('benchmark_return:發行量加權股價報酬指數')

# 日期索引對應加權大盤報酬指數
treasury_count = treasury_count.reindex(benchmark.index).fillna(0)
treasury_count.plot()</code></pre>



<h3>程式說明</h3>



<ul class="has-medium-font-size"><li>組裝資料<br>將「預定買回期間起迄」兩份資料使用 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.unstack.html" target="_blank" rel="noopener">unstack</a> 方法 將格式從 pivot 轉換成 Series，再組裝成 DataFrame。</li><li>產生庫藏股實施日日期序列<br>將開始與結束日期傳入 <a href="https://pandas.pydata.org/docs/reference/api/pandas.date_range.html" target="_blank" rel="noopener">date_range</a> 方法，得到日期序列。</li><li>統計每日預計實施庫藏股的公司家數<br>在使用 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html" target="_blank" rel="noopener">groupby </a>與 count 統計每日總家數前，要先使用 <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html" target="_blank" rel="noopener">explode</a> 方法展開上一個步驟得到的日期資料。</li><li>日期索引重置<br>為了等一下畫圖顯示趨勢，將庫藏股家數趨勢的日期對應加權大盤報酬指數，讓兩條序列長度一致，方便呈現。</li><li>簡易繪圖檢視<br>最後使用dataframe內建的 plot 方法，呈現剛剛整理的數據<br><img loading="lazy" width="375" height="252" class="wp-image-4685" style="width: 150px;" src="https://www.finlab.tw/wp-content/uploads/2022/10/庫存股簡易趨勢.png" alt="庫存股簡易趨勢" srcset="https://www.finlab.tw/wp-content/uploads/2022/10/庫存股簡易趨勢.png 375w, https://www.finlab.tw/wp-content/uploads/2022/10/庫存股簡易趨勢-300x202.png 300w" sizes="(max-width: 375px) 100vw, 375px" title="國安基金與庫藏股應用教學｜政府軍急了嗎？ 4"><br></li></ul>



<h2>取得國安基金資料</h2>



<p class="has-medium-font-size">現在 FinLab 的資料庫可以取得國安基金的進出場基本資訊了，詳見<a href="https://ai.finlab.tw/database/#national_security_fund" target="_blank" rel="noopener">資料庫</a>說明。<br>簡單一行就能取出囉 <code>data.get('national_security_fund')</code><br>目前國安基金共啟動8次。</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="520" src="https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27-1024x520.png" alt="截圖 2022 10 17 上午11.44.27" class="wp-image-4686" srcset="https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27-1024x520.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27-300x152.png 300w, https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27-768x390.png 768w, https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27-1536x780.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/10/截圖-2022-10-17-上午11.44.27.png 1585w" sizes="(max-width: 1024px) 100vw, 1024px" title="國安基金與庫藏股應用教學｜政府軍急了嗎？ 5"></figure>



<h2>趨勢繪圖</h2>



<p class="has-medium-font-size">將國安基金實施期間與庫藏股趨勢疊合，比較兩者訊號時間點。</p>



<h3>程式範例</h3>



<pre class="wp-block-code"><code lang="python" class="language-python">import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Add traces
fig.add_trace(
    go.Bar(x=treasury_count.index, y=treasury_count.values, marker_color='navy',name="庫藏股實施家數"),
    secondary_y=False,
)

fig.update_traces(marker_color = 'rgba(0,0,250, 0.5)',
                  marker_line_width = 0,
                  selector=dict(type="bar"))

# 大盤指數
fig.add_trace(
    go.Scatter(x=benchmark.index, y=benchmark['發行量加權股價報酬指數'],line = dict(color = '#2C191B'), name="發行量加權股價報酬指數"),
    secondary_y=True,
)

# 國安基金實施期間
for i,row in national_security_fund.iterrows():
    fig.add_vrect(x0=row['啟動時間'], x1=row['退場時間'], 
                  annotation_text=row['時空背景'], annotation_position="top left",
                  fillcolor="green", opacity=0.25, line_width=0)
    
# Add figure title
fig.update_layout(
        title={
            'text': "庫藏股與國安基金護盤趨勢",
            'x': 0.49,
            'y': 0.9,
            'xanchor': 'center',
            'yanchor': 'top'},
        legend=dict(
            orientation="h",
            yanchor="bottom",
            y=1.02,
            xanchor="right",
            x=0.3
        )
)

# Set x-axis title
fig.update_xaxes(title_text="date",
                 rangeselector=dict(
                     buttons=list([
                         dict(count=1,
                              label="1y",
                              step="year",
                              stepmode="backward"),
                         dict(count=3,
                              label="3y",
                              step="year",
                              stepmode="backward"),
                         dict(count=5,
                              label="5y",
                              step="year",
                              stepmode="backward"),
                         dict(count=10,
                              label="10y",
                              step="year",
                              stepmode="backward"),
                         dict(step="all")
                     ])
                 ),
                 rangeslider=dict(
                     visible=True
                 ),
                 type="date")



# Set y-axes titles
fig.update_yaxes(title_text="&lt;b>count&lt;/b>", secondary_y=False)
fig.update_yaxes(title_text="&lt;b>benchmark&lt;/b>", secondary_y=True,showgrid=False)
fig.show()</code></pre>



<h2>救市趨勢分析</h2>



<h3>政府救市三步</h3>



<p class="has-medium-font-size">通常政府救市的步驟如下</p>



<p class="has-medium-font-size">1.鼓勵企業實施庫藏股</p>



<p class="has-medium-font-size">2.限空令 or 找法人喝咖啡</p>



<p class="has-medium-font-size">3.國安感冒糖漿(國家金融安定基金)</p>



<p class="has-medium-font-size">庫藏股對政府最省事，因為不用自己出一毛錢就可能有效果，當然別人先動手最好。<br>企業內部人往往對自家公司價值最了解，有些又有質押股票面臨市值下修的壓力。一般來說，庫藏股這類回燒公司資金的事，經營者多會考量價格是否合理(進入低檔)才買入。<br></p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="418" src="https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18-1024x418.png" alt="newplot 18" class="wp-image-4688" srcset="https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18-1024x418.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18-300x122.png 300w, https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18-768x313.png 768w, https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18-1536x627.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/10/newplot-18.png 1960w" sizes="(max-width: 1024px) 100vw, 1024px" title="國安基金與庫藏股應用教學｜政府軍急了嗎？ 6"></figure>



<p class="has-medium-font-size"><br><strong>從圖表發現，前幾次國安基金進場前，庫藏股家數(藍柱)都會先明顯變多，內部人護盤也撐不住了，國家隊才會進場。</strong><br>但這次很不一樣，雖然政府在7月初已經 <a href="https://www.gvm.com.tw/article/94817" target="_blank" rel="noopener">鼓勵企業實施庫藏股</a>，卻沒啥公司響應，於是殺盤持續。即使現在跌多，庫藏股仍靜悄悄，是不是股價不到公司派目標價 (前幾年噴太多)？還是公司派看到未來景氣風險，要保留資金過冬？ <br>還沒等到公司派進場，政府軍這次等不及了，先啟動國安基金，發現還是抵擋不住殺盤，才再祭出「<a href="https://www.storm.mg/lifestyle/4560341" target="_blank" rel="noopener">限空令</a>」，SOP似乎和以前不一樣，就怕大招放完後仍抵擋不住，這次沒庫藏股先擋第一線，要自己多扛一點。</p>



<p class="has-medium-font-size">如果政府招式出盡後，還是繼續殺呢？那很可能國安基金這個六連勝的底部訊號也會失效，讓我們繼續看下去 ~ </p>



<p class="has-medium-font-size">下一篇來教大家怎麼將庫藏股和國安基金進出場化作大盤風險濾網加入策略。</p>



<h2>程式範例檔</h2>



<p class="has-medium-font-size"><a href="https://drive.google.com/file/d/1MIVKDhqjnWvjufa7I_VEbTSarX2ips0P/view?usp=sharing" target="_blank" rel="noopener">colab連結</a><br><br>註冊 FinLab 量化平台 VIP 才能取得全時段數據喔。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/treasury_stock_national_security_fund/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4684</post-id>	</item>
		<item>
		<title>如何用指標計分來選股? &#124; Python 資料分級處理</title>
		<link>https://www.finlab.tw/basic_score_strategy/</link>
					<comments>https://www.finlab.tw/basic_score_strategy/#respond</comments>
		
		<dc:creator><![CDATA[Ben]]></dc:creator>
		<pubDate>Tue, 27 Sep 2022 05:09:39 +0000</pubDate>
				<category><![CDATA[Python新手教學]]></category>
		<category><![CDATA[FinLab 量化平台]]></category>
		<category><![CDATA[VIP文章]]></category>
		<category><![CDATA[基本面分析]]></category>
		<category><![CDATA[pandas]]></category>
		<category><![CDATA[策略開發豆知識]]></category>
		<guid isPermaLink="false">https://www.finlab.tw/?p=4593</guid>

					<description><![CDATA[前陣子韓老師線上直播時，有同學許願想幫標的打分數，利用分數來篩選。 今天FinLab的神燈精靈就來幫你實現願望 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="has-medium-font-size">前陣子韓老師<a href="https://fb.watch/fOmbkSHRnn/" target="_blank" rel="noopener">線上直播</a>時，有同學許願想幫標的打分數，利用分數來篩選。</p>



<p></p>



<figure class="wp-container-2 wp-block-gallery-1 wp-block-gallery has-nested-images columns-default is-cropped">
<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="320" data-id="4594" src="https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-1024x320.png" alt="截圖 2022 09 27 下午12.21.45" class="wp-image-4594" srcset="https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-1024x320.png 1024w, https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-300x94.png 300w, https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-768x240.png 768w, https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-1536x480.png 1536w, https://www.finlab.tw/wp-content/uploads/2022/09/截圖-2022-09-27-下午12.21.45-2048x640.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" title="如何用指標計分來選股? | Python 資料分級處理 7"></figure>
</figure>



<p></p>



<p class="has-medium-font-size">今天FinLab的神燈精靈就來幫你實現願望，示範如何用 pandas 撰寫指標計分，並實際應用到策略開發。</p>



<h2>方法一、Pandas qcut</h2>



<p class="has-medium-font-size"><a href="https://pandas.pydata.org/docs/reference/api/pandas.qcut.html" target="_blank" rel="noopener">qcut </a>是 Pandas模組中基於分位數的離散化函數。剛好適用這位同學的需求。簡單打個範例來看看qcut的效果。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">import pandas as pd
# range(20)數列按10分位數切分級
pd.qcut(x=range(20), q=10, labels=False)
# output
# array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9])</code></pre>



<p class="has-medium-font-size">從以下範例中，可以得知x參數為要處理的1維序列資料 ; q為分級的設定 ; label如果為 False，則返回整數分級。<br>輸出結果將 1-20 的序列分成 10 等份，注意分級從 0 開始。</p>



<p class="has-medium-font-size">認識了qcut以後，我們要將該函數應用到FinLab的資料格式，就可以得到財務指標分級資料。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">with data.universe(market='TSE_OTC'):
    df = data.get('fundamental_features:ROE稅後')
    rank_df = df.T
    for date in rank_df.columns:
        # 方便認知，將0~9變1~10
        rank_df[date] = pd.qcut(rank_df[date].rank(method='first'), 10, labels=False)+1
    rank_df = rank_df.T</code></pre>



<h2></h2>



<h2>方法二、程式簡化</h2>



<p class="has-medium-font-size">但 qcut 函數有個缺點是他不適用 DataFrame 資料型態，只能用在序列，所以我們要一行行操作再組裝，程式碼變的瑣碎。<br>其實我們能用 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rank.html" target="_blank" rel="noopener">rank</a> 函數直接去做簡化，運用函數的axis參數做整列分級運數，pct參數將數值轉成百分位數以方便之後使用 <a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.mul.html" target="_blank" rel="noopener">mul</a> 方法將數據乘上欲分級距，得數值後再將數據全+1，讓最小分級從1開始，而不是0開始，最後使用「無條件捨去法 (np.floor)」取得級距值。<br>最後由於排第一名的會跑到多出來的 rank (因為只有他是滿分 1 分)，所以要加上<a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.clip.html" target="_blank" rel="noopener">clip</a>去限縮分數上限，ex:若用10等分級距，第一名會是11分，用clip讓數據限縮到10分內。<br>程式範例如下：</p>



<pre class="wp-block-code"><code lang="python" class="language-python">with data.universe(market='TSE_OTC'):
    rank_df = (data.get('fundamental_features:ROE稅後')
        .rank(axis=1, pct=True, ascending=True)
        .mul(10)
        .add(1)
        .apply(np.floor).clip(0,10))</code></pre>



<p class="has-medium-font-size">程式是不是變乾淨很多呢？</p>



<h3>函數封裝</h3>



<pre class="wp-block-code"><code lang="python" class="language-python">def qcut_feature(data_name='fundamental_features:ROE稅後', q_range=10, ascending=True):
    import numpy as np

    rank_df = (data.get(data_name)
               .rank(axis=1, pct=True, ascending=ascending)
               .mul(q_range)
               .add(1)
               .apply(np.floor).clip(0,q_range))
    return rank_df
</code></pre>



<p class="has-medium-font-size"><br><br>參數說明如下：</p>



<ul class="has-medium-font-size"><li>data_name：設定要處理的FinLab資料庫中的財務指標。</li><li>q_range：變數設定分割的級距。</li><li>ascending：的用途在有些指標我們希望數值越高則分數越高，如ROE ; 有些指標我們希望數值越低則分數越高，如負債比率，所以用 ascending 來控制指標升降屬性，ascending=False時，會反轉序列排序，產生數值越低則分數越高的作用。</li></ul>



<p class="has-medium-font-size">來執行程式並來檢視一下數據吧！可以發現護國神山的 ROE 長年都在前段班。</p>



<pre class="wp-block-code"><code lang="python" class="language-python">roe_score = qcut_feature(data_name='fundamental_features:ROE稅後')
roe_score['2330'].plot()</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" width="384" height="262" src="https://www.finlab.tw/wp-content/uploads/2022/09/下載.png" alt="下載" class="wp-image-4595" srcset="https://www.finlab.tw/wp-content/uploads/2022/09/下載.png 384w, https://www.finlab.tw/wp-content/uploads/2022/09/下載-300x205.png 300w" sizes="(max-width: 384px) 100vw, 384px" title="如何用指標計分來選股? | Python 資料分級處理 8"></figure>



<h2>策略開發</h2>



<pre class="wp-block-code"><code lang="python" class="language-python">from finlab import data
from finlab.backtest import sim


def qcut_feature(data_name='fundamental_features:ROE稅後', q_range=10, ascending=True):
    import numpy as np

    rank_df = (data.get(data_name)
               .rank(axis=1, pct=True, ascending=ascending)
               .mul(q_range
               .add(1)
               .apply(np.floor).clip(0,q_range))
    return rank_df


with data.universe(market='TSE_OTC'):
    # 預想越高越好
    roe_score = qcut_feature(data_name='fundamental_features:ROE稅後')
    營業毛利率_score = qcut_feature('fundamental_features:營業毛利率')
    稅前淨利年增率_score = qcut_feature('fundamental_features:稅前淨利成長率')
    應收帳款週轉率_score = qcut_feature('fundamental_features:應收帳款週轉率')

    # 預想越低越好
    負債比率_score = qcut_feature('fundamental_features:負債比率',ascending=False)

    all_score = roe_score + 營業毛利率_score + 稅前淨利年增率_score + 應收帳款週轉率_score + 負債比率_score 

    # 設定總分要求
    position = all_score &gt;= 40
    report = sim(position,resample='M',position_limit=0.1,name="財務指標計分回測範例",upload=True)</code></pre>



<p class="has-medium-font-size">利用前述的qcut_feature函數，範例用5個財報指標來計分，並將分數加總。<br>策略條件要求總分要高於40分，也就是平均一個分數要達8分以上，算是不低的要求。<br>如果只用此指標做月週期回測，結果如下，報酬率比大盤優一點點，每月檔數穩定會選到100檔上下。</p>



<figure class="wp-block-image size-full"><img loading="lazy" width="800" height="600" src="https://www.finlab.tw/wp-content/uploads/2022/09/newplot-15.png" alt="newplot 15" class="wp-image-4596" srcset="https://www.finlab.tw/wp-content/uploads/2022/09/newplot-15.png 800w, https://www.finlab.tw/wp-content/uploads/2022/09/newplot-15-300x225.png 300w, https://www.finlab.tw/wp-content/uploads/2022/09/newplot-15-768x576.png 768w" sizes="(max-width: 800px) 100vw, 800px" title="如何用指標計分來選股? | Python 資料分級處理 9"></figure>



<h3>優化</h3>



<p class="has-medium-font-size">標的數量偏多，實際上我們資金有限，買不了那麼多，這時我們可以想想，同樣的財務指標總分下，越低價的股票是不是越有上漲的空間呢？</p>



<pre class="wp-block-code"><code lang="python" class="language-python">from finlab import data
from finlab.backtest import sim


def qcut_feature(data_name='fundamental_features:ROE稅後', q_range=10, ascending=True):
    import numpy as np

    rank_df = (data.get(data_name)
               .rank(axis=1, pct=True, ascending=ascending)
               .mul(q_range)
               .add(1)
               .apply(np.floor).clip(0,q_range))
    return rank_df


with data.universe(market='TSE_OTC'):
    # 預想越高越好
    roe_score = qcut_feature(data_name='fundamental_features:ROE稅後')
    營業毛利率_score = qcut_feature('fundamental_features:營業毛利率')
    稅前淨利年增率_score = qcut_feature('fundamental_features:稅前淨利成長率')
    應收帳款週轉率_score = qcut_feature('fundamental_features:應收帳款週轉率')

    # 預想越低越好
    負債比率_score = qcut_feature('fundamental_features:負債比率',ascending=False)

    all_score = roe_score + 營業毛利率_score + 稅前淨利年增率_score + 應收帳款週轉率_score + 負債比率_score 

    # 設定總分要求
    position = all_score &gt;= 40

    # 選前10低價股
    close = data.get('price:收盤價')
    position = (position*close).astype(float)
    position = position[position&gt;0].is_smallest(10)
    report = sim(position,resample='M',position_limit=0.1,name="財務指標計分回測範例",upload=True)</code></pre>



<p class="has-medium-font-size"><br>所以我們上面程式後段再從原先清單選出每期股價前 10 低的條件，則報酬率明顯拉出差距，也更貼近小資族的使用情境。</p>



<figure class="wp-block-image size-full"><img loading="lazy" width="800" height="600" src="https://www.finlab.tw/wp-content/uploads/2022/09/newplot-17.png" alt="newplot 17" class="wp-image-4597" srcset="https://www.finlab.tw/wp-content/uploads/2022/09/newplot-17.png 800w, https://www.finlab.tw/wp-content/uploads/2022/09/newplot-17-300x225.png 300w, https://www.finlab.tw/wp-content/uploads/2022/09/newplot-17-768x576.png 768w" sizes="(max-width: 800px) 100vw, 800px" title="如何用指標計分來選股? | Python 資料分級處理 10"></figure>



<h2>結論</h2>



<p class="has-medium-font-size">qcut 是不是很好用呢？又認識一個pandas的新工具！<br>附上<a href="https://colab.research.google.com/drive/1zCyk-GeWtuswnMVvUTMN6n-rTFfIH2ph?usp=sharing" target="_blank" rel="noopener">colab範例檔</a>讓大家練習～來試試打造自己的指標計分策略吧！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.finlab.tw/basic_score_strategy/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4593</post-id>	</item>
	</channel>
</rss>
