finlab.backtest
finlab.backtest.sim(position, resample=None, resample_offset=None, trade_at_price='close', position_limit=1, fee_ratio=1.425 / 1000, tax_ratio=3 / 1000, name=None, stop_loss=None, take_profit=None, touched_exit=False, retain_cost_when_rebalance=False, live_performance_start=None, mae_mfe_window=0, mae_mfe_window_step=1, market='AUTO', upload=True)
Simulate the equity given the stock position history. 回測模擬股票部位所產生的淨值報酬率。
Parameters:
Name | Type | Description | Default |
---|---|---|---|
position |
pd.DataFrame or pd.Series
|
Dataframe of the stock market position where index is date and columns are stock_id. Each row represents a stock portfolio, where the values are perentages. Negative values represent short position. If any sum of row is larger than 1, the normalization is perform, i.e., (1, 2) becomes (0.33, 0.66). 買賣訊號紀錄。True 為持有, False 為空手。 若選擇做空position,只要將 sim(position) 改成負的 sim(-position.astype(float))即可做空。 |
required |
resample |
str or None
|
rebalance position only on specified frequency. 交易週期。將 position 的訊號以週期性的方式論動股票,預設為每天換股。其他常用數值為 W、 M 、 Q (每週、每月、每季換股一次),也可以使用 W-Fri 在週五的時候產生新的股票清單,並且於下週交易日下單。
- Note 'D'與'None'的差別? resample='D' 的意義為每天隨股價變化做再平衡,就算當天股票清單沒變,但股票漲跌後,部位大小會變化,而 resample='D' 會強制再平衡,平均分散風險。 但是當 resample=None 的話,假如清單不變,則不會強制再平衡,只有清單改變時,才做再平衡。適用情境在較常選到大波段標的的趨勢策略,較有機會將強勢股留下,而不會汰強留弱做再平衡。 |
None
|
resample_offset |
str or None
|
add time offset to resample the position. 交易週期的時間位移,例如。
|
None
|
trade_at_price |
str or pd.DataFrame
|
rebalance on market 'close' or 'open'. 選擇回測之還原股價以收盤價或開盤價計算,預設為'close'。可選'close'或'open'。 |
'close'
|
position_limit |
float
|
maximum amount of investing a stock. 單檔標的持股比例上限,控制倉位風險。預設為None。範例:0.2,代表單檔標的最多持有 20 % 部位。 |
1
|
fee_ratio |
float
|
fee ratio of buying or selling a stock. 交易手續費率,預設為台灣無打折手續費 0.001425。可視個人使用的券商優惠調整費率。 |
1.425 / 1000
|
tax_ratio |
float
|
tax ratio of selling a stock. 交易稅率,預設為台灣普通股一般交易交易稅率 0.003。若交易策略的標的皆為ETF,記得設成 0.001。 |
3 / 1000
|
name |
str
|
name of the strategy. 策略名稱,預設為 未指名。策略名稱。相同名稱之策略上傳會覆寫。命名規則:全英文或開頭中文,不接受開頭英文接中文。 |
None
|
stop_loss |
float
|
exit when stock return smaller than a specific amount. i.e., 0.2 means -20% 停損基準,預設為None,不執行停損。範例:0.1,代表從再平衡開始,虧損 10% 時產生出場訊號。 |
None
|
take_profit |
float
|
exit when stock return larger than a specific amount. i.e., 0.3 means +30% 停利基準,預設為None,不執行停利。範例:0.1,代表從再平衡開始, 10% 時產生出場訊號。 |
None
|
touched_exit |
bool
|
|
False
|
retain_cost_when_rebalance |
bool
|
預設回測時,會將進場股票進場成本更新到到新的 rebalance 的當天價格,假如希望保留原本的進場價格當成停損停利的依據,可以設定為 |
False
|
live_performance_start |
bool
|
策略建構的日期,例如 |
None
|
mae_mfe_window |
int
|
計算mae_mfe於進場後於不同持有天數下的數據變化,主要應用為edge_ratio (優勢比率)計算。預設為0,則Report.display_mae_mfe_analysis(...)中的edge_ratio不會顯現。 |
0
|
mae_mfe_window_step |
int
|
與mae_mfe_window參數做搭配,為時間間隔設定,預設為1。若mae_mfe_window設20,mae_mfe_window_step設定為2,相當於python的range(0,20,2),以2日為間距計算mae_mfe。 |
1
|
market |
str or MarketInfo
|
可選擇 |
'AUTO'
|
upload |
bool
|
上傳策略至finlab網站,預設為True,上傳策略。範例: False,不上傳,可用 finlab.backtest.sim(position, upload=False, ...).display() 快速檢視策略績效。 |
True
|
Returns:
Type | Description |
---|---|
finlab.analysis.Report
|
回測數據報告 |
Examples:
Assume the history of portfolio is construct as follows: When market close on 2021-12-31, the portfolio {B: 0.2, C: 0.4} is calculated. When market close on 2022-03-31, the portfolio {A:1} is calculated.
Stock 2330 | Stock 1101 | Stock 2454 | |
---|---|---|---|
2021-12-31 | 0% | 20% | 40% |
2022-03-31 | 100% | 0% | 0% |
2022-06-30 | 100% | 0% | 0% |
With the portfolio, one could backtest the equity history as follows:
finlab.analysis.Report(creturn, position, fee_ratio, tax_ratio, trade_at, next_trading_date, market_info)
Bases: ReportPyx
策略回測基礎報告
Parameters:
Name | Type | Description | Default |
---|---|---|---|
creturn |
pd.Series
|
策略報酬率時間序列。 |
required |
position |
pd.DataFrame
|
策略報酬率時間序列。 |
required |
fee_ratio |
float
|
交易手續費率,預設為台灣無打折手續費 0.001425。可視個人使用的券商優惠調整費率。 |
required |
tax_ratio |
float
|
交易稅率,預設為台灣普通股一般交易交易稅率 0.003。若交易策略的標的皆為 ETF,記得設成 0.001。 |
required |
trade_at |
str
|
選擇回測之還原股價以收盤價或開盤價計算,預設為 close。可選 close 或 open。 |
required |
next_trading_date |
str
|
預期下期換股日。 |
required |
market_info |
str or MarketInfo
|
可選擇 |
required |
Attributes:
Name | Type | Description |
---|---|---|
benchmark |
pd.Series
|
對標報酬率曲線的時間序列,用於 Report.display() 顯示策略報酬率比較標準。 |
update_date |
str
|
用於 Report.display() 顯示策略對標的報酬率曲線。 |
asset_type |
str
|
資產類別, tw_stock 或 crypto。 |
last_trading_date |
str
|
最近產生交易訊號的日期。 |
display(return_fig=False)
顯示回測報酬率圖組
Parameters:
Name | Type | Description | Default |
---|---|---|---|
return_fig |
bool
|
是否回傳圖組 |
False
|
Returns:
Type | Description |
---|---|
plotly.graph_objects.Figure
|
圖組 |
Examples:
設定對標指數
from finlab import data
...
report = sim(position, resample='Q',mae_mfe_window=30,mae_mfe_window_step=2)
report.benchmark = data.get('benchmark_return:發行量加權股價報酬指數').squeeze()
report.display()

display_mae_mfe_analysis(violinmode='group', mfe_scatter_x='mae', **kwargs)
顯示波動分析圖組
Parameters:
Name | Type | Description | Default |
---|---|---|---|
violinmode |
str
|
violin 型態統計圖樣式,模式分為 group 與 overlay。 預設為 group,group 模式為將交易勝敗分群統計',overlay 採取全數統計。 |
'group'
|
mfe_scatter_x |
str
|
子圖 2-1、2-2 MFE 散點圖的X軸比較項目設定,可選 |
'mae'
|
**kwargs |
dict
|
其餘圖表外觀(layout)參數。 |
{}
|
Returns:
Type | Description |
---|---|
plotly.graph_objects.Figure
|
波動分析圖組 |
Examples:
group :
overlay :
get_mae_mfe()
取得 mae_mfe 時序資料
Returns:
Type | Description |
---|---|
pd.DataFrame
|
波動時序資料 |
get_stats(resample='1d', riskfree_rate=0.02)
取得策略統計數據 取得數據如夏普率、索提諾比率、最大回檔、近期報酬率統計...
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resample |
str
|
報酬率檢測週期,其他常用數值為 W、 M 、Q(每週、每月、每季換股)。 |
'1d'
|
riskfree_rate |
float
|
無風險利率。 |
0.02
|
Returns:
Type | Description |
---|---|
dict
|
策略指標數據。 |
get_trades()
取得回測逐筆交易紀錄
重點欄位說明
- entry_sig_date:進場訊號產生日。
- exit_sig_date:出場訊號產生日。
- entry_date:進場日。
- exit_date:出場日。
- position:持有佔比。
- period:持有天數。
- return:報酬率。
- [email protected]_date:進場價。
- [email protected]_date:出場價。
- mae:持有期間最大不利報酬率幅度。
- gmfe:持有期間最大有利報酬率幅度。
- bmfe:mae發生前的最大有利報酬率幅度。
- mdd:持有期間最大回撤。
- pdays:處於獲利時的天數。
Returns:
Type | Description |
---|---|
pd.DataFrame
|
交易紀錄 |
position_info()
取得近期持有部位與預期換股資訊
Returns:
Type | Description |
---|---|
dict
|
部位資訊 |
run_analysis(analysis, display=True, **kwargs)
執行策略分析外掛模組
Parameters:
Name | Type | Description | Default |
---|---|---|---|
analysis |
str or object
|
|
required |
display |
bool
|
是否顯示模組分析圖表。 |
True
|
**kwargs |
mapping
|
分析模組參數調整。 |
{}
|
Returns:
Type | Description |
---|---|
pd.DataFrame or plotly.graph_objects.Figure
|
分析結果 |
upload(name=None)
上傳回測報告資料到量化平台網站
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str
|
策略名稱。 |
None
|
finlab.analysis.liquidityAnalysis.LiquidityAnalysis(required_volume=200000, required_turnover=1000000, detail=True)
Bases: Analysis
分析台股策略流動性風險項目的機率
Note
參考VIP限定文章更了解流動性檢測內容細節。
Parameters:
Name | Type | Description | Default |
---|---|---|---|
required_volume |
int
|
要求進出場時的單日成交股數至少要多少? |
200000
|
required_turnover |
int
|
要求進出場時的單日成交金額至少要多少元?避免成交股數夠,但因低價股因素,造成胃納量仍無法符合資金需求。 |
1000000
|
Examples:
# better syntax
report.run_analysis('LiquidityAnalysis', required_volume=100000)
# original syntax
from finlab.analysis.liquidityAnalysis import LiquidityAnalysis
report.run_analysis(LiquidityAnalysis(required_volume=100000))
finlab.analysis.inequalityAnalysis.InequalityAnalysis(name, df=None, date_type='entry_sig_date', target='return')
Bases: Analysis
Analyze return of trades with condition inequality
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str
|
name of the condition |
required |
df |
pd.DataFrame or None
|
value used in condition. If df is None, |
None
|
date_type |
str
|
can be either |
'entry_sig_date'
|
target |
str
|
the target to optimize. Any column name in report.get_trades() |
'return'
|
Examples:
假如希望開發交易分析系統,可以繼承 finlab.analysis.Analysis
來實做分析。
finlab.analysis.Analysis
Bases: ABC
analyze(report)
Analyze trading report.
One could assume self.caluclate_trade_info will be executed before self.analyze,
so the report.get_trades()
will contain the required trade info.
calculate_trade_info(report)
Additional trade info can be calculated easily.
User could override this function if additional trade info is required for later anlaysis.
Examples:
from finlab.analysis import Analysis
class SomeAnalysis(Analysis):
def calculate_trade_info(self, report):
return [
['股價淨值比', data.get('price_earning_ratio:股價淨值比'), 'entry_sig_date']
]
report.run_analysis(SomeAnalysis())
trades = report.get_trades()
assert '股價淨值比@entry_sig_date' in trades.columns
print(trades)
display()
Display result
When implement this function, returning Plotly figure instance is recommended.
is_market_info_supported(market_info)
Check if market info is supported
Returns:
Type | Description |
---|---|
bool
|
True, support. False not support. |