跳轉到

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 在週五的時候產生新的股票清單,並且於下週交易日下單。 - D: Daily - W: Weekly - W-Wed: Every Wednesday - M: Monthly - MS: Start of every month - ME: End of every month - Q: Quarterly - QS: Start of every quarter - QE: End of every quarter

Note

'D'與'None'的差別? resample='D' 的意義為每天隨股價變化做再平衡,就算當天股票清單沒變,但股票漲跌後,部位大小會變化,而 resample='D' 會強制再平衡,平均分散風險。

但是當 resample=None 的話,假如清單不變,則不會強制再平衡,只有清單改變時,才做再平衡。適用情境在較常選到大波段標的的趨勢策略,較有機會將強勢股留下,而不會汰強留弱做再平衡。

None
resample_offset str or None

add time offset to resample the position. 交易週期的時間位移,例如。

  • '1D': 位移一天
  • '1H': 位移一小時
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

True: exit immediately whenever stop loss or take profit price is touched. False: exit tomorrow if the price touches stop loss or take profit. 是否在回測時,使用觸價停損停利?

False
retain_cost_when_rebalance bool

預設回測時,會將進場股票進場成本更新到到新的 rebalance 的當天價格,假如希望保留原本的進場價格當成停損停利的依據,可以設定為 True

False
live_performance_start bool

策略建構的日期,例如 2022-01-01 此日期之前,策略未撰寫,此日期之後則視為與實單有類似效果,實際不影響回測的結果,單純紀錄而已。

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

可選擇'TWSTOCK', 'CRYPTO',分別為台股或加密貨幣, 或繼承 finlab.market_info.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:

import pandas as pd
from finlab import backtest

position = pd.DataFrame({
    '2330': [0, 1, 1],
    '1101': [0.2, 0, 0],
    '2454': [0.4, 0, 0]
}, index=pd.to_datetime(['2021-12-31', '2022-03-31', '2022-06-30']))

report = backtest.sim(position)

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

可選擇'TWSTOCK', 'CRYPTO',分別為台股或加密貨幣, 或繼承 finlab.market_info.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' or 'return'

'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

finlab.analysis內的分析模組名稱,ex:'liquidityAnalysis'

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, data.get(name) will be automatically perform to fetch the values.

None
date_type str

can be either entry_date, entry_sig_date, exit_date, exit_sig_date.

'entry_sig_date'
target str

the target to optimize. Any column name in report.get_trades()

'return'

Examples:

report.run_analysis('InequalityAnalysis', name='price_earning_ratio:股價淨值比')

策略不等式因子分析

假如希望開發交易分析系統,可以繼承 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.