主要内容

使用金融工具箱™val投资策略

使用val框架执行val的投资组合策略。val的对比是一个有用的工具在历史或投资策略执行模拟的市场数据。这个例子发展五个不同的投资策略,然后比较他们的表现在运行了一段历史的股票数据。val框架中实现两个金融工具箱™类:backtestStrategybacktestEngine

加载数据

加载一年的调整为30只股票价格数据。val框架需要调整资产价格,这意味着价格调整的股息,分裂,或其他事件。价格必须存储在一个MATLAB®时间表与每一列持有资产价格的时间序列的可投资资产。

对于这个示例,使用一年的资产价格的数据组件道琼斯工业股票平均价格指数的股票。

%读表每日近2006吗股票价格调整。T = readtable (“dowPortfolio.xlsx”);%的可读性,只使用15 30收组件的股票。assetSymbols = [“AA”,“猫”,“说”,“通用汽车”,“hp”,“公司”,“力”,“嗯”,“莫”,“期望”,“微软”,“工业”,“PG”,“T”,“XOM”];%只修剪表来保存日期和选择股票。timeColumn =“日期”;T = T (:, (timeColumn assetSymbols]);%的转换为一个时间表。pricesTT = table2timetable (T)“RowTimes”,“日期”);%视图的结构价格时间表。头(pricesTT)
日期AA猫说通用hp JNJ MCD嗯莫merck microsoft pfizer PG T XOM ___________ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ 03 - 1月- 2006 28.72 55.86 24.18 17.82 28.35 59.08 32.72 75.93 52.27 30.73 26.19 22.16 56.38 22.7 56.64 04 -简- 2006 28.89 57.29 23.77 18.3 29.18 59.99 33.01 75.54 52.65 31.08 26.32 22.88 56.48 22.87 56.74 05 - 1月- 2006 29.12 57.29 24.19 19.34 28.97 59.74 33.05 74.85 52.52 31.13 26.34 22.9 56.3 22.92 56.45 06 - 1月- 2006 29.02 58.43 24.52 19.61 29.8 60.01 33.25 75.47 52.95 31.08 26.26 23.16 56.24 23.21 57.57 09 - 1月- 2006 29.37 59.49 24.78 21.12 30.17 60.38 33.88 75.84 53.11 31.58 26.21 23.16 56.67 23.3 57.54 10 - 1月- 2006 28.44 59.25 25.09 20.79 30.33 60.49 33.91 75.37 53.04 31.27 26.35 22.77 56.45 23.16 57.99 11 - 1月- 2006 28.05 59.28 25.33 20.61 30.88 59.91 34.5 75.22 53.31 31.39 26.63 23.06 56.65 23.34 58.38 12 - 1月- 2006 27.68 60.13 25.41 19.76 30.57 59.63 33.96 74.57 53.23 31.41 26.48 22.9 56.02 23.24 57.77
%查看资产价格数据集的大小。numSample = (pricesTT大小。变量,1);numAssets = (pricesTT大小。变量,2);表(numSample numAssets)
ans =1×2表numSample numAssets替251 15

定义策略

投资策略捕获用于资产配置决策的逻辑而val正在运行。定期在val运行时,每个策略是有机会来更新其投资组合分配基于落后于市场状况,它通过设置资产权重向量。资产权重代表可用资本投资到每个资产的比例,每个元素的权重向量对应相应的列的资产pricesTT时间表。如果权重向量的总和1,那么完全投资组合。

在这个例子中,有五个,val策略。val策略分配资产权重使用以下标准:

  • 等权

ω 电子战 = ( ω 1 , ω 2 , , ω N ) , ω = 1 N

  • 夏普比率最大化

ω = argmax ω { r ω ω ω | ω 0 , 1 N ω = 1 , 0 ω 0 1 } ,在那里 r 是一个向量的预期收益和 的协方差矩阵是资产的回报。

  • 逆方差

ω 四世 = ( ω 1 , ω 2 , , ω N ) , ω = ( σ 二世 - - - - - - 1 ) = 1 N σ 二世 - - - - - - 1 ,在那里 σ 二世 是资产收益协方差矩阵的对角元素。

  • 马科维茨投资组合优化(与固定收益最大化和风险最小化的风险规避系数)

R Mkwtz = 马克斯 ω { r ω - - - - - - λ ω ω | ω 0 , 1 N ω = 1 , 0 ω 0 1 } ,在那里 λ 是风险规避系数。

  • 鲁棒优化与预期收益的不确定性

  • 强劲的投资组合优化策略,与确定性马科维茨公式,考虑资产的预期收益的不确定性及其方差和协方差。代替建模未知值(例如,预期收益),通常由过去的平均值计算,未知数指定为一组值,包含最可能的可能的实现, r = { r | r 年代 ( r 0 ) }

在这种情况下,预期收益而不是确定性矢量定义 r 0 但在该地区 年代 ( r 0 ) 在向量 r 0

要仔细考虑,有几种方法可以调整投资组合优化的问题。最常用的方法之一是制定问题找到最大和最小的问题:

R 健壮的 = 马克斯 ω 最小值 r 年代 ( r 0 ) { r ω - - - - - - λ ω ω | ω 0 , 1 N ω = 1 , 0 ω 0 1 }

在这个例子中,该地区的不确定性 年代 ( r 0 ) 被指定为一个椭球体:

年代 ( r 0 ) = { r | ( r - - - - - - r 0 ) Σ r - - - - - - 1 ( r - - - - - - r 0 ) κ 2 }

在这里, κ ——不确定性厌恶系数,定义了不确定性区域,有多宽 Σ r 预期收益矩阵的估计错误 r

添加的椭球马科维茨模型不确定性,鲁棒优化问题是新配方为:

R 健壮的 = 马克斯 ω { r ω - - - - - - λ ω ω - - - - - - kz | ω 0 , z 0 , ω Σ r ω - - - - - - z 2 0 , 1 N ω = 1 , 0 ω 0 1 }

实现战略平衡的功能

每个策略的核心逻辑是建立在一个平衡的功能。平衡功能是一个MATLAB®用户定义函数,指定策略如何分配资本在投资组合中。平衡功能是一个输入参数backtestStrategy。平衡功能必须实现以下固定签名:

函数new_weights = allocationFunctionName(current_weights,pricesTimetable)

这个固定的签名时,val框架使用的API重新平衡投资组合。val运行,val引擎调用每个策略的调整功能,通过在这些输入:

  • current_weights再平衡之前——当前的投资组合权重

  • pricesTimetable——MATLAB®时间表包含滚动窗口对象的资产价格。

backtestStrategy平衡函数使用这些信息来计算所需的新的投资组合权重,val引擎返回的函数的输出new_weights。看到本地函数部分平衡函数的五个策略。

计算初始权重策略

使用战略平衡函数来计算每个策略的初始权重。设置初始权重很重要,因为否则策略开始,val 100%的现金,获得无风险利率,直到第一次调整日期。

这个示例使用数据集的前40天(约2个月)来初始化策略。然后运行在val剩余的数据(约10个月)。

warmupPeriod = 40;

初始权值计算通过调用backtestStrategy平衡功能是一样的,val引擎将调用它。电流,通过一个向量权重(0,100%的现金),以及一个窗口的价格数据策略将使用设置所需的重量(热身数据分区)。使用平衡函数来计算初始权重以这种方式不是必需的。初始权值向量的初始投资组合权重,可以设置为任何适当的值。平衡功能在这个例子中近似国家策略将他们已经val的开始。

目前没有重量百分比(100%现金头寸)。numAssets current_weights = 0 (1);%热身分区数据集的时间表。warmupTT = pricesTT (1: warmupPeriod,:);%计算每种策略的初始投资组合权重。equalWeight_initial = equalWeightFcn (current_weights warmupTT);maxSharpeRatio_initial = maxSharpeRatioFcn (current_weights warmupTT);inverseVariance_initial = inverseVarianceFcn (current_weights warmupTT);markowitz_initial = markowitzFcn (current_weights warmupTT);robustOptim_initial = robustOptimFcn (current_weights warmupTT);

可视化的初始重量分配策略。

strategyNames = {“并重”,“马克斯·夏普比率”,“逆方差”,“马科维茨优化”,鲁棒优化的};assetSymbols = pricesTT.Properties.VariableNames;initialWeights = [equalWeight_initial (:), maxSharpeRatio_initial (:), inverseVariance_initial (:), markowitz_initial (:), robustOptim_initial (:));热图(strategyNames assetSymbols initialWeights,“标题”,“初始资产配置”,“Colormap”,parula);

图包含一个类型的对象的热图。类型的热图的图表标题初始资产配置。

创建val策略

使用val的策略框架,必须构建backtestStrategy对象,一个用于每一个策略。的backtestStrategy函数作为输入策略名称为每个策略和平衡功能。此外,backtestStrategy可以采用多种名称-值对参数来指定各种选项。创建val策略的更多信息,请参阅backtestStrategy

设置调整频率和lookback窗口大小设置的时间步骤(即行数pricesTT时间表)。由于数据是每日价格数据,指定调整频率和滚动lookback窗口在天。

%平衡大约每1个月(252/12 = 21)。rebalFreq = 21;%将滚动lookback窗口设置为至少40天,最多126人%天(约6个月)。lookback = 40 [126];%使用一个固定的交易成本(买卖成本都是0.5%的金额%交易)。transactionsFixed = 0.005;使用一个函数%定制交易成本。看到% variableTransactionCosts函数下面的一个例子。transactionsVariable = @variableTransactionCosts;%的前两个策略使用固定交易成本。的等权%的策略不需要lookback后数据的窗口,作为它的%分配是固定的。strat1 = backtestStrategy (“并重”@equalWeightFcn,“RebalanceFrequency”rebalFreq,“LookbackWindow”0,“TransactionCosts”transactionsFixed,“InitialWeights”,equalWeight_initial);strat2 = backtestStrategy (“马克斯·夏普比率”@maxSharpeRatioFcn,“RebalanceFrequency”rebalFreq,“LookbackWindow”lookback,“TransactionCosts”transactionsFixed,“InitialWeights”,maxSharpeRatio_initial);%使用变量为剩下的交易成本的策略。strat3 = backtestStrategy (“逆方差”@inverseVarianceFcn,“RebalanceFrequency”rebalFreq,“LookbackWindow”lookback,“TransactionCosts”@variableTransactionCosts,“InitialWeights”,inverseVariance_initial);strat4 = backtestStrategy (“马科维茨优化”@markowitzFcn,“RebalanceFrequency”rebalFreq,“LookbackWindow”lookback,“TransactionCosts”transactionsFixed,“InitialWeights”,markowitz_initial);strat5 = backtestStrategy (鲁棒优化的@robustOptimFcn,“RebalanceFrequency”rebalFreq,“LookbackWindow”lookback,“TransactionCosts”transactionsFixed,“InitialWeights”,robustOptim_initial);%的总策略对象到一个数组中。策略= [strat1 strat2、strat3 strat4, strat5);

val的策略

使用以下工作流,val的策略backtestEngine

定义,val引擎

backtestEngine函数作为输入的数组backtestStrategy对象。此外,当使用backtestEngine,您可以设置一些选项,例如无风险利率和最初的投资组合价值。指定年度而言,无风险利率时backtestEngine使用基础属性设置计数约定的那一天。在创建val引擎的更多信息,见backtestEngine

%无风险利率是1%annualRiskFreeRate = 0.01;%,val引擎创建对象val = backtestEngine(策略,“RiskFreeRate”annualRiskFreeRate)
val = backtestEngine属性:策略:[1 x5 backtestStrategy] RiskFreeRate: 0.0100 CashBorrowRate: 0 RatesConvention:“年”的基础上:0 InitialPortfolioValue: 10000 DateAdjustment:“之前”NumAssets:[]的回报:[]职位:[]营业额:[]BuyCost: [] SellCost:[]费用:[]

运行,val

使用runBacktest使用测试数据运行,val分区。使用runBacktest名称-值对的观点“开始”为了避免有预见性的偏见(即“看到未来”)。开始,val末尾的“热身”。运行,val填充空的字段backtestEngine对象与每天的val的结果。

pricesTT val = runBacktest (val,“开始”warmupPeriod)
val = backtestEngine属性:策略:[1 x5 backtestStrategy] RiskFreeRate: 0.0100 CashBorrowRate: 0 RatesConvention:“年”的基础上:0 InitialPortfolioValue: 10000 DateAdjustment:“之前”NumAssets: 15的回报:[211 x5时间表)职位:[1 x1 struct]营业额:[211 x5时间表]BuyCost: [211 x5时间表]SellCost: [211 x5时间表)费用:[1 x1 struct]

检查,val结果

使用总结函数来生成一个表的策略,val的性能结果。

summaryByStrategies =总结(val)
summaryByStrategies =9×5表___________ Equal_Weighted Max_Sharpe_Ratio Inverse_Variance Markowitz_Optimization Robust_Optimization * * * ___________ ______________________ ___________________ TotalReturn SharpeRatio 0.12559 0.092456 0.12179 0.18745 0.14991 0.15906 0.17404 0.15655 0.10339 - 0.11442 0.0063474 0.0070186 0.0055626 0.0072466 0.0058447 AverageTurnover波动MaxTurnover 0.031251 0.239 0.09114 0.00087623 0.0065762 0.0028666 0.0058268 0.0025172 0.00083462 0.00068672 0.0007152 0.00078682 0.00070651 0.21873 - 0.073746 AverageReturn MaxDrawdown AverageBuyCost 0.047298 0.3449 0.15228 0.072392 0.084768 0.054344 0.085544 0.064904 0.047298 0.3449 0.22842 0.3155 0.1328 0.3155 - 0.1328 AverageSellCost

详细的val的结果,包括每日回报,资产头寸,营业额,费用都存储在属性的backtestEngine对象。

使用equityCurve绘制股票曲线的五种不同的投资策略。

equityCurve (val)

图包含一个坐标轴对象。坐标轴对象与标题股本曲线,包含时间,ylabel投资组合价值包含5线类型的对象。这些对象代表相同权重,马克斯•夏普比率逆方差,马科维茨优化,鲁棒优化。

更换某些指标的汇总表,使情节可能是有用的。

%的转置图指标汇总表。summaryByMetrics = rows2vars (summaryByStrategies);summaryByMetrics.Properties。VariableNames {1} =“策略”
summaryByMetrics =5×10表战略TotalReturn SharpeRatio波动AverageTurnover MaxTurnover AverageReturn MaxDrawdown AverageBuyCost AverageSellCost __________________________ ___________ ___________ __________售予___________售予_________________……* * * {‘Equal_Weighted} 0.18745 0.12559 0.0063474 0.00087623 0.031251 0.00083462 0.072392 0.047298 0.047298 {‘Max_Sharpe_Ratio} 0.14991 0.092456 0.0070186 0.0065762 0.239 0.00068672 0.084768 0.3449 0.3449 {‘Inverse_Variance} 0.15906 0.12179 0.0055626 0.0028666 0.09114 0.0007152 0.054344 0.15228 0.22842 {‘Markowitz_Optimization} 0.17404 0.10339 0.0072466 0.0058268 0.21873 0.00078682 0.085544 0.3155 0.3155 {‘Robust_Optimization} 0.15655 0.11442 0.0058447 0.0025172 0.073746 0.00070651 0.064904 0.1328 0.1328
%比较策略营业额。名称= [backtester.Strategies.Name];nameLabels = strrep(名称,“_”,' ');标题栏(summaryByMetrics.AverageTurnover) (的平均营业额的)ylabel (“每日营业额(%)”甘氨胆酸)组(,“xticklabel”nameLabels)

图包含一个坐标轴对象。坐标轴对象标题平均营业额,ylabel每日营业额(%)包含一个对象类型的酒吧。

你可以想象策略分配的变化随着时间的使用面积图的日常资产头寸。上的信息assetAreaPlot功能,请参见本地函数部分。

strategyName =“Max_Sharpe_Ratio”;strategyName assetAreaPlot (val)

图包含一个坐标轴对象。坐标轴对象与标题马克斯•夏普比率的位置包含日期、ylabel资产位置包含16个区域类型的对象。这些对象代表现金,AA,猫说,通用汽车、hp, johnson & johnson, MCD,嗯,密苏里州,期望microsoft,工业的PG, T, XOM。

本地函数

战略再平衡功能以及变量交易成本函数。

函数new_weights = equalWeightFcn (current_weights pricesTT)%加权组合配置nAssets =大小(pricesTT, 2);nAssets new_weights = 1 (1);new_weights = new_weights /笔(new_weights);结束
函数new_weights = maxSharpeRatioFcn (current_weights pricesTT)%均值-方差投资组合配置nAssets =大小(pricesTT, 2);assetReturns = tick2ret (pricesTT);% 25% Max成一个单一的资产(包括现金)p =组合(“NumAssets”nAssets,下界的0,“UpperBound”,0.1,“LowerBudget”,1“UpperBudget”1);(p, p = estimateAssetMoments assetReturns {:,:});new_weights = estimateMaxSharpeRatio (p);结束
函数new_weights = inverseVarianceFcn (current_weights pricesTT)%反变量组合配置assetReturns = tick2ret (pricesTT);assetCov = x (assetReturns {:,:});new_weights = 1。/诊断接头(assetCov);new_weights = new_weights /笔(new_weights);结束
函数new_weights = robustOptimFcn (current_weights pricesTT)%的投资组合分配nAssets =大小(pricesTT, 2);assetReturns = tick2ret (pricesTT);Q = x (table2array (assetReturns));SIGMAx =诊断接头(诊断接头(Q));%的厌恶系数k = 1.1;%的厌恶系数λ= 0.05;rPortfolio =意味着(table2array (assetReturns)) ';%创建优化问题pRobust = optimproblem (“描述”,“强劲的投资组合”);%定义变量% xRobust - x分配向量xRobust = optimvar (“x”nAssets 1“类型”,“连续”,下界的,0.0,“UpperBound”,0.1);zRobust = optimvar (“z”,下界的,0);%定义预算限制pRobust.Constraints。预算= sum (xRobust) = = 1;%定义的约束pRobust.Constraints。健壮的=xRobust'*SIGMAx*xRobust - zRobust*zRobust <=0; pRobust.Objective = -rPortfolio'*xRobust + k*zRobust + lambda*xRobust'*Q*xRobust; x0.x = zeros(nAssets,1); x0.z = 0; opt = optimoptions(“fmincon”,“显示”,“关闭”);(solRobust, ~, ~) =解决(x0, pRobust“选项”、选择);new_weights = solRobust.x;结束
函数new_weights = markowitzFcn (current_weights pricesTT)%的投资组合分配nAssets =大小(pricesTT, 2);assetReturns = tick2ret (pricesTT);Q = x (table2array (assetReturns));%风险规避系数λ= 0.05;rPortfolio =意味着(table2array (assetReturns)) ';%创建优化问题pMrkwtz = optimproblem (“描述”,马科维茨均值-方差投资组合的);%定义变量% xRobust - x分配向量xMrkwtz = optimvar (“x”nAssets 1“类型”,“连续”,下界的,0.0,“UpperBound”,0.1);%定义预算限制pMrkwtz.Constraints。预算= sum (xMrkwtz) = = 1;%定义马科维茨的目标pMrkwtz。目标= -rPortfolio ' * xMrkwtz +λ* xMrkwtz”* Q * xMrkwtz;x0。x = 0 (nAssets, 1);选择= optimoptions (“quadprog”,“显示”,“关闭”);(solMrkwtz, ~, ~) =解决(x0, pMrkwtz“选项”、选择);new_weights = solMrkwtz.x;结束
函数(购买、销售)= variableTransactionCosts (deltaPositions)%变量交易成本函数%%这个函数就是一个例子如何计算变量的交易成本。%%计算了交易成本基于市场价值的变化%每个资产平衡。在以下利率成本计算:%%购买:% 0 - 10000美元:0.5%% $ 10000 +:0.35%%销售:% 0 - 1000美元:0.75%% $ 1000 +:0.5%买= 0(1,元素个数(deltaPositions));销售= 0(1,元素个数(deltaPositions));%购买idx = 0 < deltaPositions & deltaPositions < 1 e4;买(idx) = 0.005 * deltaPositions (idx);% 50个基点idx = 1 e4 < = deltaPositions;买(idx) = 0.0035 * deltaPositions (idx);% 35 ponits基础买=总和(购买);%销售idx = 1 e3 < deltaPositions & deltaPositions < 0;出售(idx) = 0.0075 * -deltaPositions (idx);% 75个基点idx = deltaPositions < = 1 e3;出售(idx) = 0.005 * -deltaPositions (idx);% 50个基点销售=总和(销售);结束
函数strategyName assetAreaPlot (val)%画出资产配置区域的阴谋。t = backtester.Positions。(strategyName) .Time;位置= backtester.Positions。(strategyName) .Variables;h =区域(t,职位);标题(sprintf (“% s的立场”strrep (strategyName“_”,' ')));包含(“日期”);ylabel (“资产头寸”);datetick (“x”,“mm / dd”,“keepticks”);xlim ([t (1) t(结束)])oldylim = ylim;ylim ([0 oldylim (2)]);厘米= parula(元素个数(h));i = 1:元素个数(h)组(h(我),“FaceColor”厘米(我:));结束传奇(backtester.Positions (strategyName) .Properties.VariableNames)。结束

另请参阅

|||

相关的话题