量化投資的強(qiáng)化學(xué)習(xí)神器!FinRL 入門(mén)指南

本文將基于FinRL教你實(shí)現(xiàn)一個(gè)超額收益7%的強(qiáng)化學(xué)習(xí)模型。關(guān)于強(qiáng)化學(xué)習(xí)的基礎(chǔ)知識(shí),可以閱讀我們以前發(fā)表的一篇基礎(chǔ)文章:
《什么是強(qiáng)化學(xué)習(xí)?預(yù)測(cè)股票的效果如何?》
使用強(qiáng)化學(xué)習(xí)預(yù)測(cè)股價(jià),類(lèi)似于心理學(xué)中的操作性條件反射原理,你需要在決策的時(shí)候采取合適的行動(dòng) (Action) 使獎(jiǎng)勵(lì)最大化。與監(jiān)督學(xué)習(xí)預(yù)測(cè)未來(lái)的數(shù)值不同,強(qiáng)化學(xué)習(xí)根據(jù)輸入的狀態(tài)(如當(dāng)日開(kāi)盤(pán)價(jià)、收盤(pán)價(jià)等),輸出系列動(dòng)作(例如:買(mǎi)進(jìn)、持有、賣(mài)出),并對(duì)好的動(dòng)作結(jié)果不斷進(jìn)行獎(jiǎng)勵(lì),對(duì)差的動(dòng)作結(jié)果不斷進(jìn)行懲罰,使得最后的收益最大化,實(shí)現(xiàn)自動(dòng)交易。
如果你從頭開(kāi)始編寫(xiě)一套強(qiáng)化學(xué)習(xí)的代碼,時(shí)間成本和試錯(cuò)成本會(huì)比較高。而本文的主角 FinRL 框架,能夠幫助你極大地減少學(xué)習(xí)成本、時(shí)間成本和試錯(cuò)成本。下面就介紹一下 FinRL 的使用方法。

1.準(zhǔn)備
開(kāi)始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒(méi)有,可以訪問(wèn)這篇文章:超詳細(xì)Python安裝指南 進(jìn)行安裝。
(可選1) 如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda:Python數(shù)據(jù)分析與挖掘好幫手—Anaconda,它內(nèi)置了Python和pip.
(可選2) 此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn):Python 編程的最好搭檔—VSCode 詳細(xì)指南。
請(qǐng)選擇以下任一種方式輸入命令安裝依賴:
1. Windows 環(huán)境 打開(kāi) Cmd (開(kāi)始-運(yùn)行-CMD)。
2. MacOS 環(huán)境 打開(kāi) Terminal (command+空格輸入Terminal)。
3. 如果你用的是 VSCode編輯器 或 Pycharm,可以直接使用界面下方的Terminal.
# 首先克隆項(xiàng)目
git clone https://github.com/AI4Finance-Foundation/FinRL.git
# 進(jìn)入剛克隆的項(xiàng)目,安裝依賴
cd FinRL
pip install請(qǐng)注意 Python 版本要大于等于 3.7。此外,如果你的當(dāng)前Python環(huán)境下安裝了 zipline,請(qǐng) pip uninstall 掉 zipline,因?yàn)閆ipline與FinRL不兼容。
可能出現(xiàn)的錯(cuò)誤:
如果你出現(xiàn)以下紅字提示:
error: command 'swig.exe' failed: No such file or directory請(qǐng)使用conda安裝swig:
conda install swig然后重新執(zhí)行 pip install . 即可。
2.模型訓(xùn)練
運(yùn)行官方示例的時(shí)候會(huì)使用到雅虎財(cái)經(jīng)的數(shù)據(jù),雅虎財(cái)經(jīng)在中國(guó)已經(jīng)關(guān)閉服務(wù),因此你會(huì)需要VPN才能下載雅虎財(cái)經(jīng)的數(shù)據(jù)。
cd FinRL
python Stock_NeurIPS2018.py運(yùn)行的時(shí)候大概率會(huì)遇到這個(gè)問(wèn)題(2022-07-03):
FileNotFoundError: Please set your own ALPACA_API_KEY and ALPACA_API_SECRET in config_private.py這是官網(wǎng)的一個(gè)不嚴(yán)謹(jǐn)實(shí)現(xiàn)導(dǎo)致的,你可以將 finrl/main.py 中25~30行的代碼移動(dòng)到第100行,如下所示:

此外,在運(yùn)行代碼的時(shí)候,你可能會(huì)遇到無(wú)法下載數(shù)據(jù)的問(wèn)題,這是因?yàn)檠呕⒇?cái)經(jīng)在中國(guó)已經(jīng)關(guān)閉服務(wù),你需要在 Stock_NeurIPS2018.py 的第172行代碼 fetch_data 函數(shù)中添加proxy參數(shù):
# 公眾號(hào):二七阿爾量化
# 此處我的代理是10809端口,你應(yīng)該按需修改
df = YahooDownloader(start_date = '2009-01-01',
end_date = '2021-10-31',
ticker_list = config_tickers.DOW_30_TICKER
).fetch_data(proxy={"http": "http://127.0.0.1:10809", "https": "https://127.0.0.1:10809"})此外,在 finrl/finrl_meta/preprocessor/preprocessors.py 的第191行,你也需要增加proxy參數(shù):
# 公眾號(hào):二七阿爾量化
# 此處我的代理是10809端口,你應(yīng)該按需修改
df_vix = YahooDownloader(
start_date=df.date.min(), end_date=df.date.max(), ticker_list=["^VIX"]
).fetch_data(proxy={"http": "http://127.0.0.1:10809", "https": "https://127.0.0.1:10809"})
正常運(yùn)行起來(lái)的模型訓(xùn)練如下圖所示:

下面是我簡(jiǎn)化版的到SAC模型訓(xùn)練為止的全部代碼:
3.模型測(cè)試
在這一部分,我們將使用測(cè)試集進(jìn)行模擬交易,檢驗(yàn)?zāi)P偷男Ч?/p>
在env_kwargs中,我們?cè)O(shè)置了初始資金為1000000美元,測(cè)試也會(huì)以這個(gè)初始資金為起點(diǎn)。
# 測(cè)試
e_trade_gym = StockTradingEnv(df=trade, turbulence_threshold=70, risk_indicator_col='vix', **env_kwargs)
df_account_value, df_actions = DRLAgent.DRL_prediction(
model=trained_sac,
environment=e_trade_gym
)
print(f"df_account_value.tail(): {df_account_value.tail()}")如下:

此外,df_actions內(nèi)保存了每天的持倉(cāng)記錄:
print(f"df_actions.head(): {df_actions.head()}")
調(diào)用 backtest_stats 函數(shù),能獲得完整的回測(cè)結(jié)果:
print("==============Get Backtest Results===========")
now = datetime.datetime.now().strftime('%Y%m%d-%Hh%M')
perf_stats_all = backtest_stats(account_value=df_account_value)
perf_stats_all = pd.DataFrame(perf_stats_all)
perf_stats_all.to_csv("./"+config.RESULTS_DIR+"/perf_stats_all_"+now+'.csv')結(jié)果如下所示:

可以見(jiàn)到,模型的年化收益為30%,累計(jì)凈值收益為43%.
但是這段時(shí)間為美股的牛市,我們還需要以道瓊斯指數(shù)為基準(zhǔn)計(jì)算超額收益,才能更直觀地展示模型的效果:
print("==============Get Baseline Stats===========")
baseline_df = get_baseline(
ticker="^DJI",
start = df_account_value.loc[0,'date'],
end = df_account_value.loc[len(df_account_value)-1,'date'])
stats = backtest_stats(baseline_df, value_col_name = 'close')
可見(jiàn)模型還是具有超額收益的,我們將其繪制為圖表更清晰地表達(dá):
backtest_result = backtest_plot(df_account_value,
baseline_ticker = '^DJI',
baseline_start = df_account_value.loc[0,'date'],
baseline_end = df_account_value.loc[len(df_account_value)-1,'date'])
with open("backtest_result.html", "w") as file:
file.write(backtest_result)
作者給我們內(nèi)置了許多漂亮的回測(cè)圖表,非常好用。但我們只需要看最關(guān)鍵的cumulative returns. 從圖中可以看到這個(gè)模型(綠色的線條)一開(kāi)始的表現(xiàn)并不如指數(shù),但是到了后面,它的表現(xiàn)漸漸優(yōu)于指數(shù)。
當(dāng)然,這是官方給的示例數(shù)據(jù),大家可以用自己的因子補(bǔ)充數(shù)據(jù),將模型完善地更好。本文的示例中使用的是SAC模型,你也可以嘗試其他的強(qiáng)化學(xué)習(xí)模型。
總之,F(xiàn)inrl 只能提供你一雙”巨人的肩膀“,你應(yīng)該根據(jù)自己的實(shí)際業(yè)務(wù)場(chǎng)景和數(shù)據(jù)類(lèi)型使用不同的優(yōu)化方法。
4.其他
FinRL不只能支持美股,它還支持A股的部分?jǐn)?shù)據(jù)源,如聚寬、米筐和Tushare:

以downloader為例,用法很簡(jiǎn)單,庫(kù)中提供了 Tushare 的 downloader, 你只需要把:
from finrl.finrl_meta.preprocessor.yahoodownloader import YahooDownloader
替換為:
from finrl.finrl_meta.preprocessor.tusharedownloader import TushareDownloader并進(jìn)行相應(yīng)的代碼修改即可,當(dāng)然,除此之外還有許多細(xì)節(jié)問(wèn)題需要處理,由于文章篇幅的問(wèn)題,我們留到下篇文章再給大家介紹。
我們的文章到此就結(jié)束啦,如果你喜歡今天的量化投資內(nèi)容,請(qǐng)持續(xù)關(guān)注二七阿爾量化。
有任何問(wèn)題,可以在公眾號(hào)后臺(tái)回復(fù):加群,回答相應(yīng)紅字驗(yàn)證信息,進(jìn)入互助群詢問(wèn)。
希望你能在下面點(diǎn)個(gè)贊和在看支持我繼續(xù)創(chuàng)作,謝謝!
歡迎關(guān)注公眾號(hào):二七阿爾量化
