finlab.dataframe
finlab.dataframe.FinlabDataFrame
Bases: pd.DataFrame
回測語法糖
除了使用熟悉的 Pandas 語法外,我們也提供很多語法糖,讓大家開發程式時,可以用簡易的語法完成複雜的功能,讓開發策略更簡潔!
我們將所有的語法糖包裹在 FinlabDataFrame
中,用起來跟 pd.DataFrame
一樣,但是多了很多功能!
只要使用 finlab.data.get()
所獲得的資料,皆為 FinlabDataFrame
格式,
接下來我們就來看看, FinlabDataFrame
有哪些好用的語法糖吧!
當資料日期沒有對齊(例如: 財報 vs 收盤價 vs 月報)時,在使用以下運算符號:+
, -
, *
, /
, >
, >=
, ==
, <
, <=
, &
, |
, ~
,不需要先將資料對齊,因為 FinlabDataFrame
會自動幫你處理,以下是示意圖。
以下是範例:cond1
與 cond2
分別為「每天」,和「每季」的資料,假如要取交集的時間,可以用以下語法:
from finlab import data
# 取得 FinlabDataFrame
close = data.get('price:收盤價')
roa = data.get('fundamental_features:ROA稅後息前')
# 運算兩個選股條件交集
cond1 = close > 37
cond2 = roa > 0
cond_1_2 = cond1 & cond2
cond1
跟 cond2
訊號的頻率雖然不相同,但是由於 cond1
跟 cond2
是 FinlabDataFrame
,所以可以直接取交集,而不用處理資料頻率對齊的問題。

總結來說,FinlabDataFrame 與一般 dataframe 唯二不同之處:
1. 多了一些 method,如df.is_largest()
, df.sustain()
...等。
2. 在做四則運算、不等式運算前,會將 df1、df2 的 index 取聯集,column 取交集。
average
取 n 筆移動平均
若股票在時間窗格內,有 N/2 筆 NaN,則會產生 NaN。
PARAMETER | DESCRIPTION |
---|---|
n |
設定移動窗格數。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
股價在均線之上
只需要簡單的語法,就可以將其中一部分的訊號繪製出來檢查:import matplotlib.pyplot as plt
close.loc['2021', '2330'].plot()
sma.loc['2021', '2330'].plot()
cond.loc['2021', '2330'].mul(20).add(500).plot()
plt.legend(['close', 'sma', 'cond'])

Source code in finlab/dataframe.py
deadline
財務索引轉換成公告截止日
將財務季報 (ex:2022Q1) 從文字格式轉為公告截止日的datetime格式, 通常使用情境為對不同週期的dataframe做reindex,常用於以公告截止日作為訊號產生日。
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
Source code in finlab/dataframe.py
fall
數值下降中
取是否比前第n筆低,若符合條件的值則為True,反之為False。
PARAMETER | DESCRIPTION |
---|---|
n |
設定比較前第n筆低。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
收盤價是否低於10日前股價
Source code in finlab/dataframe.py
groupby_category
資料按產業分群
類似 pd.DataFrame.groupby()
的處理效果。
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
半導體平均股價淨值比時間序列
from finlab import data
pe = data.get('price_earning_ratio:股價淨值比')
pe.groupby_category().mean()['半導體'].plot()

全球 2020 量化寬鬆加上晶片短缺,使得半導體股價淨值比衝高。
Source code in finlab/dataframe.py
hold_until
hold_until(exit, nstocks_limit=None, stop_loss=-np.inf, take_profit=np.inf, trade_at='close', rank=None, market='AUTO')
訊號進出場
這大概是所有策略撰寫中,最重要的語法糖,上述語法中 entries
為進場訊號,而 exits
是出場訊號。所以 entries.hold_until(exits)
,就是進場訊號為 True
時,買入並持有該檔股票,直到出場訊號為 True
則賣出。
此函式有很多細部設定,可以讓你最多選擇 N 檔股票做輪動。另外,當超過 N 檔進場訊號發生,也可以按照客制化的排序,選擇優先選入的股票。最後,可以設定價格波動當輪動訊號,來增加出場的時機點。
PARAMETER | DESCRIPTION |
---|---|
exit |
出場訊號。
TYPE:
|
nstocks_limit |
輪動檔數上限,預設為None。
TYPE:
|
stop_loss |
價格波動輪動訊號,預設為None,不生成輪動訊號。範例:0.1,代表成本價下跌 10% 時產生出場訊號。
TYPE:
|
take_profit |
價格波動輪動訊號,預設為None,不生成輪動訊號。範例:0.1,代表成本價上漲 10% 時產生出場訊號。
TYPE:
|
trade_at |
價格波動輪動訊號參考價,預設為'close'。可選
TYPE:
|
rank |
當天進場訊號數量超過 nstocks_limit 時,以 rank 數值越大的股票優先進場。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
價格 > 20 日均線入場, 價格 < 60 日均線出場,最多持有10檔,超過 10 個進場訊號,則以股價淨值比小的股票優先選入。
from finlab import data
from finlab.backtest import sim
close = data.get('price:收盤價')
pb = data.get('price_earning_ratio:股價淨值比')
sma20 = close.average(20)
sma60 = close.average(60)
entries = close > sma20
exits = close < sma60
#pb前10小的標的做輪動
position = entries.hold_until(exits, nstocks_limit=10, rank=-pb)
sim(position)
Source code in finlab/dataframe.py
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
|
index_str_to_date
財務月季報索引格式轉換
將以下資料的索引轉換成datetime格式:
月營收 (ex:2022-M1) 從文字格式轉為公告截止日。
財務季報 (ex:2022-Q1) 從文字格式轉為財報電子檔資料上傳日。
通常使用情境為對不同週期的dataframe做reindex,常用於以公告截止日作為訊號產生日。
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
data.get('monthly_revenue:當月營收').index_str_to_date()
data.get('financial_statement:現金及約當現金').index_str_to_date()
Source code in finlab/dataframe.py
industry_rank
計算產業 ranking 排名,0 代表產業內最低,1 代表產業內最高
PARAMETER | DESCRIPTION |
---|---|
categories |
欲考慮的產業,ex: ['貿易百貨', '雲端運算'],預設為全產業,請參考
TYPE:
|
Examples:
本意比產業排名分數
from finlab import data
pe = data.get('price_earning_ratio:本益比')
pe_rank = pe.industry_rank()
print(pe_rank)
Source code in finlab/dataframe.py
is_entry
進場點
取進場訊號點,若符合條件的值則為True,反之為False。
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
策略為每日收盤價前10高,取進場點。
Source code in finlab/dataframe.py
is_exit
出場點
取出場訊號點,若符合條件的值則為 True,反之為 False。
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
策略為每日收盤價前10高,取出場點。
Source code in finlab/dataframe.py
is_largest
取每列前 n 筆大的數值
若符合 True
,反之為 False
。用來篩選每天數值最大的股票。
PARAMETER | DESCRIPTION |
---|---|
n |
設定每列前 n 筆大的數值。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
每季 ROA 前 10 名的股票
from finlab import data
roa = data.get('fundamental_features:ROA稅後息前')
good_stocks = roa.is_largest(10)
Source code in finlab/dataframe.py
is_smallest
取每列前 n 筆小的數值
若符合 True
,反之為 False
。用來篩選每天數值最小的股票。
PARAMETER | DESCRIPTION |
---|---|
n |
設定每列前 n 筆小的數值。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
股價淨值比最小的 10 檔股票
from finlab import data
pb = data.get('price_earning_ratio:股價淨值比')
cheap_stocks = pb.is_smallest(10)
Source code in finlab/dataframe.py
quantile_row
股票當天數值分位數
取得每列c定分位數的值。
PARAMETER | DESCRIPTION |
---|---|
c |
設定每列 n 定分位數的值。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
取每日股價前90%分位數
Source code in finlab/dataframe.py
rise
數值上升中
取是否比前第n筆高,若符合條件的值則為True,反之為False。
PARAMETER | DESCRIPTION |
---|---|
n |
設定比較前第n筆高。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
收盤價是否高於10日前股價
Source code in finlab/dataframe.py
sustain
持續 N 天滿足條件
取移動 nwindow 筆加總大於等於nsatisfy,若符合條件的值則為True,反之為False。
PARAMETER | DESCRIPTION |
---|---|
nwindow |
設定移動窗格。
TYPE:
|
nsatisfy |
設定移動窗格計算後最低滿足數值。
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
pd.DataFrame
|
data |
Examples:
收盤價是否連兩日上漲