跳轉到

finlab.backtest

finlab.backtest.sim

sim(position, resample=None, resample_offset=None, trade_at_price='close', position_limit=1, fee_ratio=1.425 / 1000, tax_ratio=3 / 1000, name='未命名', stop_loss=None, take_profit=None, trail_stop=None, touched_exit=False, retain_cost_when_rebalance=False, stop_trading_next_period=True, live_performance_start=None, mae_mfe_window=0, mae_mfe_window_step=1, market='AUTO', upload=True, fast_mode=False, notification_enable=False, line_access_token='')

Simulate the equity given the stock position history. 回測模擬股票部位所產生的淨值報酬率。

PARAMETER DESCRIPTION
position

買賣訊號紀錄。True 為持有, False 為空手。 若選擇做空position,只要將 sim(position) 改成負的 sim(-position.astype(float))即可做空。

TYPE: DataFrame or Series

resample

交易週期。將 position 的訊號以週期性的方式論動股票,預設為每天換股。其他常用數值為 W、 M 、 Q (每週、每月、每季換股一次),也可以使用 W-Fri 在週五的時候產生新的股票清單,並且於下週交易日下單。

  • D: Daily
  • W: Weekly
  • W-Wed: Every Wednesday
  • M: Monthly
  • MS: Start of every month
  • Q: Quarterly
  • QS: Start of every quarter

Note

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

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

另外 resample 也接受 pd.DataFrame 以及 pd.Series,並且將其 index 用來當成換股的時間點,例如以下的範例:

from finlab import backtest, data

rev = data.get('monthly_revenue:當月營收')
position = ...

# 月營收發布時才換股
backtest.sim(position, resample=rev)

TYPE: (str, None, DataFrame, Series, FinlabDataFrame) DEFAULT: None

resample_offset

交易週期的時間位移,例如。

  • '1D': 位移一天
  • '1H': 位移一小時

TYPE: str or None DEFAULT: None

trade_at_price

選擇回測之還原股價以收盤價或開盤價計算,預設為'close'。可選'close'、'open'、'open_close_avg'、'high_low_avg'或 'price_avg'。

TYPE: str or DataFrame DEFAULT: 'close'

position_limit

maximum amount of investing a stock. 單檔標的持股比例上限,控制倉位風險。預設為None。範例:0.2,代表單檔標的最多持有 20 % 部位。

TYPE: float DEFAULT: 1

fee_ratio

fee ratio of buying or selling a stock. 交易手續費率,預設為台灣無打折手續費 0.001425。可視個人使用的券商優惠調整費率。

TYPE: float DEFAULT: 1.425 / 1000

tax_ratio

tax ratio of selling a stock. 交易稅率,預設為台灣普通股一般交易交易稅率 0.003。若交易策略的標的皆為ETF,記得設成 0.001。

TYPE: float DEFAULT: 3 / 1000

name

name of the strategy. 策略名稱,預設為 未指名。策略名稱。相同名稱之策略上傳會覆寫。命名規則:全英文或開頭中文,不接受開頭英文接中文。

TYPE: str DEFAULT: '未命名'

stop_loss

停損基準,預設為None,不執行停損。範例:0.1,代表從再平衡開始,虧損 10% 時產生出場訊號。

TYPE: float DEFAULT: None

take_profit

停利基準,預設為None,不執行停利。範例:0.1,代表從再平衡開始, 10% 時產生出場訊號。

TYPE: float DEFAULT: None

trail_stop

移動停損停利基準,預設為None,不執行。範例:0.1,代表從最高點開始下跌,跌至 10% 時產生出場訊號。

TYPE: float DEFAULT: None

touched_exit

是否在回測時,使用觸價停損停利?預設為 False。

TYPE: bool DEFAULT: False

retain_cost_when_rebalance

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

TYPE: bool DEFAULT: False

stop_trading_next_period

當期已經停損停利,則下一期不買入,預設為 True。

TYPE: bool DEFAULT: True

live_performance_start

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

TYPE: str DEFAULT: None

mae_mfe_window

計算mae_mfe於進場後於不同持有天數下的數據變化,主要應用為edge_ratio (優勢比率)計算。預設為0,則Report.display_mae_mfe_analysis(...)中的edge_ratio不會顯現。

TYPE: int DEFAULT: 0

mae_mfe_window_step

與mae_mfe_window參數做搭配,為時間間隔設定,預設為1。若mae_mfe_window設20,mae_mfe_window_step設定為2,相當於python的range(0,20,2),以2日為間距計算mae_mfe。

TYPE: int DEFAULT: 1

market

可選擇'TW_STOCK', 'CRYPTO',分別為台股或加密貨幣, 或繼承 finlab.market_info.MarketInfo 開發回測市場類別。

TYPE: str or MarketInfo DEFAULT: 'AUTO'

upload

上傳策略,預設為True,上傳策略。 範例: False,不上傳,可用 finlab.backtest.sim(position, upload=False, ...).display() 快速檢視策略績效。

TYPE: bool DEFAULT: True

fast_mode

預設為False,若設定為True,則會使用快速模式,快速模式會忽略所有的停利停損設定,並且只有換股日進行報酬率模擬,因此會有一些誤差,當持有較多檔股票時,可以大幅加速回測速度。

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
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.backtest.line_notify

line_notify(report=None, line_access_token='', test=False, name='')

傳送回測結果之目前部位、近期換股訊息至Line聊天室。

PARAMETER DESCRIPTION
report

回測完的結果報告。

TYPE: Report DEFAULT: None

line_access_token

於Line Notify取得的access_token(權杖)。至Line Notify登入Line帳號後,點選個人頁面,點選「發行權杖」,選擇欲接收訊息的聊天室(可選擇1對1接收Line Notify通知、或是選擇其他群組聊天室),即可取得權杖。

TYPE: str DEFAULT: ''

test

是否進行傳送訊息測試。

TYPE: bool DEFAULT: False

name

策略名稱,預設為空字串。

TYPE: str DEFAULT: ''

Examples:

欲進行測試,則設定test參數為True。

from finlab import backtest

line_access_token = 'xxxxxxxxxxxx'
backtest.line_notify(line_access_token=line_access_token, test=True)

若成功收到通知,則權杖設定已完畢,可直接在sim回測模組中開啟使用,或單獨調用此函式發送回測換股訊息。 於sim中使用:

from finlab import backtest

line_access_token = 'xxxxxxxxxxxx'
position = ...
report = backtest.sim(position, notification_enable =True, line_access_token = line_access_token)

已回測完,單獨傳訊息用:

from finlab import backtest

line_access_token = 'xxxxxxxxxxxx'
report = backtest.sim(position)
backtest.line_notify(report, line_access_token=line_access_token)