參考資料
FinRL_PortfolioAllocation_NeurIPS_2020.ipynb
FinRL_PortfolioAllocation_NeurIPS_2020.py
FinRL for Quantitative Finance: Tutorial for Portfolio Allocation
-
投資組合配置(Portfolio Allocation) 是 FinRL 入門教程之一,旨在介紹如何使用深度強化學習(DRL)模型來優化投資組合的動態資金配置。該教程通過與傳統方法的比較,展示了 DRL 在投資組合管理中的潛力。
本文將基於道瓊斯工業平均指數(DOW 30)的成分股,使用日線級別的數據進行分析。我們將比較 DRL 方法與傳統的均值-方差優化(MVO)和道瓊斯工業平均指數(DJI)的表現。
在此教學中使用了每日動態再平衡的 MVO 策略作為比較基準,以更公平地評估 DRL 模型的動態資產配置能力。
這篇教學使用
每日動態再平衡的 MVO 策略
主要是為了對齊DRL 動態的 Portfolio Allocation
的行為。
從結果來看每日動態再平衡的 MVO 策略
效果很普通,跟前篇教學使用 MVO 在計算資產分配比例後就持有直至到期日的策略比較起來,獲利差了很多。
StockPortfolioEnv
需要計算一年前的協方差列表(cov_list
),因此 2008 年的資料不被使用。之後會測試一下如果不使用重疊的資料績效會掉多少
以下是資料下載與處理的主要程式碼:
from finrl import config
from finrl import config_tickers
from finrl.meta.data_processors.processor_yahoofinance import YahooFinanceProcessor
from finrl.meta.env_portfolio_allocation.env_portfolio import StockPortfolioEnv
from finrl.meta.preprocessor.preprocessors import FeatureEngineer, data_split
import os
import pandas as pd
# 設定環境
TIME_INTERVAL = '1D'
START_DATE = '2008-01-01'
END_DATE = '2021-10-31'
RAW_DATA_PATH = f'./datasets/DOW30_{TIME_INTERVAL}_{START_DATE}_to_{END_DATE}.csv'
TRAIN_START_DATE = '2009-01-01'
TRAIN_END_DATE = '2020-07-01'
TRADE_START_DATE = '2020-01-01'
## Part 3. Download Data
print(config_tickers.DOW_30_TICKER)
if not os.path.exists(RAW_DATA_PATH):
dp = YahooFinanceProcessor()
df = dp.download_data(start_date=START_DATE,
end_date=END_DATE,
ticker_list=config_tickers.DOW_30_TICKER,
time_interval=TIME_INTERVAL)
df.to_csv(RAW_DATA_PATH)
else:
df = pd.read_csv(RAW_DATA_PATH)
if 'date' not in df.columns and 'timestamp' in df.columns:
df = df.rename(columns={'timestamp': 'date'})
先前的 DRL 自動交易策略範例中使用的是 StockTradingEnv
,此處則改用 StockPortfolioEnv
的 GYM 環境來訓練 DRL。以下將比較這兩者的區別及使用原因。
StockPortfolioEnv
vs StockTradingEnv
簡要比較cov_list
)及技術指標。選擇 StockPortfolioEnv
:當目標是多資產的權重分配與風險管理,適合長期投資調整資金配置與機構需求。
選擇 StockTradingEnv
:當目標是優化具體交易行為,適合短期策略開發與個人交易員。
StockPortfolioEnv
需要透過 "tech_indicator_list"
設定使用時輸入的數據中會有哪些額外的特徵
env_kwargs = {
"hmax": 100,
"initial_amount": 1000000,
"transaction_cost_pct": 0.001,
"state_space": state_space,
"stock_dim": stock_dimension,
"tech_indicator_list": config.INDICATORS,
"action_space": stock_dimension,
"reward_scaling": 1e-4
}
# 初始化環境
e_train_gym = StockPortfolioEnv(df=train, **env_kwargs)
這邊前處理以下兩者必不可少
tech_indicator
:透過 FeatureEngineer
在 df
數據中加入初始化時指定的一些額外特徵cov_list
:StockPortfolioEnv
核心算法需要資產之間的協方差矩陣數據評估各資產的風險,此項數據必不可少fe = FeatureEngineer(use_technical_indicator=True,
use_turbulence=False,
user_defined_feature = False)
df = fe.preprocess_data(df)
# 計算協方差矩陣
df = calculate_cov_list(df)
cov_list
?在使用 FinRL 進行自動資金分配(Portfolio Allocation)時,StockPortfolioEnv
環境中使用協方差矩陣(Covariance Matrix) 用於衡量多個資產之間回報的相關性。cov_list
是一系列協方差矩陣的集合,通常基於一段回溯期間(如 252 個交易日,即一年)的資產回報數據計算而來。
在 StockPortfolioEnv
中的應用
self.state = np.append(
np.array(self.covs),
[self.data[tech].values.tolist() for tech in self.tech_indicator_list],
axis=0,
)
cov_list
被整合到環境的狀態空間中,為強化學習模型提供有關資產間相關性的資訊。這有助於模型在進行資金分配時,考量資產之間的風險和回報關係。cov_list
提供的風險資訊可以用於設計更複雜的獎勵函數,如夏普比率(Sharpe Ratio),即回報與風險的比率,從而促進更穩健的資金分配策略。# 訓練模型
trained_models = train_drl(e_train_gym, models_info)