主要内容

val投资策略

此示例显示如何使用MATLAB®实现的反向框架执行投资组合策略的次次来执行。反向来是一个有用的工具,可以比较投资策略如何在历史或模拟市场数据上进行。此示例开发了五种不同的投资策略,然后在历史股票数据的一年内运行后比较了他们的性能。反向框架在两个Matlab®类中实现:反向rightsgy.backtestEngine

加载数据

载入30只股票的一年调整价格数据。回溯测试框架需要调整资产价格,即根据股息、分割或其他事件调整价格。价格必须存储在MATLAB®中时间表每列持有可投资资产的时间序列资产价格。

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

%阅读2006年DJIA股票的每日调整后的接近价格表。T = readtable (“dowPortfolio.xlsx”);%为了可读性,只使用30个DJI组件股票中的15个。assetSymbols = [“aa”“猫”“说”“GM”“HPQ”“jnj”“力”“嗯”“莫”“MRK”“msft”“pfe”“PG”“T”“XOM”];%修剪表,只保存日期和选定的股票。timecolumn =.“日期”;T = T(:,[timeColumn assetSymbols]);%将表格转换为时间表。pricesTT = table2timetable(T,“RowTimes”“日期”);%查看价格时间表的结构。头(pricesTT)
ans =8×15时间表日期AA CAT DIS GM HPQ JNJ MCD MMM MO MRK MSFT PFE PG牛逼XOM ___________ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ 03-JAN-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.3822.7 56.64 04-JAN-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-JAN-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  -  2006年29.02 58.43 24.5219.61 29.8 60.01 33.25 75.47 52.95 31.08 26.26 23.16 56.24 23.21 57.57 09-JAN-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-JAN-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.4523.16 57.99 11-JAN-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-JAN-2006 27.68 60.13 25.41 19.76 30.57 59.63 33.96 74.57 53.23 31.41 26.48 56.02 22.9 23.24 57.77
%查看资产价格数据集的大小。numsample = size(pricestt.variables,1);numasset =大小(pricestt.variables,2);表(NumSample,NumAsset)
ans =1×2表NumSample Numasset _________ _________ 251 15

定义策略

投资策略捕获用于在恢复时捕获资产分配决策的逻辑。作为逆行运行,每次策略都会定期基于尾随市场条件更新其投资组合分配的机会,它通过设置资产权重的向量来实现。资产权重代表投资于每个资产的可用资本百分比,其中重量矢量中的每个元素对应于资产中的相应列pricesTT时间表。如果权重向量的和是1,那么投资组合就全部投资了。

在这个例子中,有五个回溯测试策略。使用以下crieria的回溯测试策略分配资产的权重:

  • 等权

ω. EW. = ω. 1 ω. 2 ω. N ω. 一世 = 1 N

  • 的夏普比率最大化

ω. SR. = argmax. ω. { R. ' ω. ω. ' 问: ω. | ω. 0. σ. 1 N ω. 一世 = 1 0. ≤. ω. ≤. 0. 1 } ,在那里 R. 是预期回报和的向量吗 问: 为资产收益的协方差矩阵。

  • 逆转方案

ω. 4 = ω. 1 ω. 2 ω. N ω. 一世 = σ. 2 - 1 σ. 一世 = 1 N σ. 2 - 1 ,在那里 σ. 2 是资产回报协方差矩阵的对角元素。

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

R. Mkwtz = 马克斯 ω. { R. ' ω. - λ. ω. ' 问: ω. | ω. 0. σ. 1 N ω. 一世 = 1 0. ≤. ω. ≤. 0. 1 } ,在那里 λ. 为风险厌恶系数。

  • 在预期回报中具有不确定性的强大优化

  • 与确定性的Markowitz制定相比,强大的投资组合优化策略考虑了资产及其差异和协方差的不确定性预期回报。而不是将未知值(例如,预期返回)为一个点,通常由从过去计算的平均值表示的一个点,未知名被指定为包含最可能实现的一组值, R. = { R. | R. S. R. 0. }

在这种情况下,预期的返回不是由确定性向量定义的 R. 0. 但由该地区 S. R. 0. 在向量 R. 0.

考虑到这一点,有几种方法可以重新制定投资组合优化问题。最常用的方法之一是将问题作为找到最大和最小值的问题:

R. 健壮的 = 马克斯 ω. R. S. R. 0. { R. ' ω. - λ. ω. ' 问: ω. | ω. 0. σ. 1 N ω. 一世 = 1 0. ≤. ω. ≤. 0. 1 }

在这个例子中,不确定性区域 S. R. 0. 指定为椭球体:

S. R. 0. = { R. | R. - R. 0. ' Σ R. - 1 R. - R. 0. ≤. κ.. 2 }

这里, κ.. 是不确定性厌恶系数,它定义了不确定性区域的宽度 Σ R. 是估计误差的预期收益矩阵 R.

在Markowitz模型中加入椭球不确定性,鲁棒优化问题重新表述为:

R. 健壮的 = 马克斯 ω. { R. ' ω. - λ. ω. ' 问: ω. - kz | ω. 0. Z. 0. ω. ' Σ R. ω. - Z. 2 ≤. 0. σ. 1 N ω. 一世 = 1 0. ≤. ω. ≤. 0. 1 }

实现策略再平衡功能

每个策略的核心逻辑在一个rebalance函数中实现。再平衡函数是一个用户定义的MATLAB®函数,它指定了策略如何在投资组合中配置资本。的输入参数是rebalance函数反向rightsgy.。重新平衡函数必须实施以下固定签名:

函数new_weights = AllocationFunctionName.current_weights,pricesTimetable

此固定签名是后退框架在重新平衡投资组合时使用的API。作为逆行运行,逆向引擎呼叫每个策略的重新平衡函数,通过这些输入:

  • Current_weights.-重新平衡前的当前投资组合权重

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

反向rightsgy.重新平衡函数使用此信息来计算所需的新产品组合权重,该重量将返回到函数输出中的回溯引擎new_weights。看看本地功能这五种策略中的每一种的rebalance函数节。

计算初始策略权重

使用策略rebalance函数计算每个策略的初始权值。设定初始权重是很重要的,因为否则策略将以100%现金开始回测,获得无风险利率,直到第一次再平衡日期。

本例使用的数据集的第40日(约2个月)来初始化的策略。后台测试,然后在剩余的数据(约10个月)运行。

warmupPeriod = 40;

通过呼叫来计算初始权重反向rightsgy.重新平衡函数的方式与后退引擎称之为相同的方式。为此,通过当前权重的向量(所有零,即100%现金)以及策略将用于设置所需权重的价格数据窗口(预热数据分区)。使用重新平衡函数以这种方式计算初始权重。初始权重是初始产品组合权重的矢量,可以设置为任何适当的值。在这个例子中的重新平衡函数近似于策略将在第二次开始在第二次开始时运行。

%没有当前权重(100%现金头寸)。current_weights =零(1,numasset);数据设置时间表的%热身分区。warmupTT = pricesTT (1: warmupPeriod,:);%计算每个策略的初始产品组合权重。complyweight_initial =平等福克(Current_weights,Mirtuptt);maxsharperatio_initial = maxsharperatiofcn(current_weights,mightuptt);Inversevariance_initial = InversevarianceFCN(Current_weights,Materultt);markowitz_initial = markowitzfcn(current_weights,mightuptt);robustoptim_initial = robustoptimfcn(current_weights,mightuptt);

从策略中可视化初始权重分配。

StrategyNames = {“并重”'max sharpe比率'“逆方差”'Markowitz优化'鲁棒优化的};assetSymbols = pricesTT.Properties.VariableNames;initialWeights = [equalWeight_initial(:), maxSharpeRatio_initial(:), inverseVariance_initial(:), markowitz_initial(:), robustOptim_initial(:)];热图(strategyNames assetSymbols initialWeights,'标题'“初始资产配置”“Colormap”,parula);

图包含型热图的对象。型热图的图表有标题初始资产分配。

创建反向策略

要使用反向框架中的策略,必须构建反向rightsgy.对象,每个策略一个。这反向rightsgy.函数将每个策略的策略名称和再平衡函数作为输入。此外,反向rightsgy.可以接受各种名称-值对参数来指定各种选项。有关创建backtest策略的更多信息,请参见反向rightsgy.

设置重新平衡频率和Lookback窗口大小根据时间步骤(即,行的行)设置pricesTT时间表)。由于数据是每日价格数据,因此在几天内指定重新平衡频率和滚动Lookback窗口。

%重新平衡大约每1个月(252 / 12 = 21)。rebalFreq = 21;%将滚动的窗口设置为至少40天,最多126%天(约6个月)。寻求= [40 126];%使用固定的交易成本(买卖成本均为0.5%%交易)。transactionsFixed = 0.005;%使用函数自定义事务成本。看看% variableTransactionCosts函数的例子如下。transactionsVariable = @variableTransactionCosts;前两种策略使用固定交易成本。的等权%策略不需要跟踪数据的回溯窗口,因为它的%分配是固定的。strat1 = backtestStrategy(“并重”,@equalweightfcn,......'重新平衡'rebalFreq,......'lookbackwindow',0,......'交易成本'transactionsFixed,......'初始重量',平等的_;;;;strat2 =反向临时('max sharpe比率'@maxSharpeRatioFcn,......'重新平衡'rebalFreq,......'lookbackwindow', 回望,......'交易成本'transactionsFixed,......'初始重量', maxSharpeRatio_initial);%其余策略使用可变交易成本。strat3 = backtestStrategy (“逆方差”,@inversevariancefcn,......'重新平衡'rebalFreq,......'lookbackwindow', 回望,......'交易成本',@variabletransactioncosts,......'初始重量',Inversevariance_initial);strat4 =反向临时('Markowitz优化',@markowitzfcn,......'重新平衡'rebalFreq,......'lookbackwindow', 回望,......'交易成本'transactionsFixed,......'初始重量',markowitz_initial);strat5 = backtestStrategy(鲁棒优化的,@robustoptimfcn,......'重新平衡'rebalFreq,......'lookbackwindow', 回望,......'交易成本'transactionsFixed,......'初始重量', robustOptim_initial);%将策略对象聚合为一个数组。策略= [strat1, strat2, strat3, strat4, strat5];

反向策略

使用以下工作流程将策略返回使用backtestEngine

定义,val引擎

backtestEngine函数作为输入的数组反向rightsgy.对象。此外,当使用backtestEngine,你可以设定几个选项,例如无风险利率和初始投资组合价值。当无风险利率以年化方式指定时,则backtestEngine用途基础属性设置日计数约定。有关创建反向测试引擎的更多信息,请参见backtestEngine

年化无风险率为1%annualRiskFreeRate = 0.01;%创建反向引擎对象反向临时=逆景气(策略,“RiskFreeRate”annualRiskFreeRate)
反向临时=逆景期:[]

运行,val

使用runbacktest.使用测试数据分区运行回测。使用runbacktest.名称 - 值对参数'开始'避免向前偏见(即“看到未来”)。在“热身”时期结束时开始反向。运行reachtest填充空字段backtestEngine对象的逐日回溯测试结果。

backtester = runBacktest(backtester,pricesTT,'开始'warmupPeriod)
backtester = backtestEngine与属性:策略:[1x5 backtestStrategy] RiskFreeRate: 0.0100 CashBorrowRate: 0 rate惯例:“年化”基础:0 InitialPortfolioValue: 10000 NumAssets: 15 Returns: [211x5时间表]position: [1x1 struct] Turnover: [211x5时间表]BuyCost: [211x5时间表]SellCost: [211x5时间表]

检查反向效果

使用总结函数为回测生成策略性能结果表。

summarybystrategies =摘要(反击)
summarybystrategies =.9×5表Equal_Weighted Max_Sharpe_Ratio Inverse_Variance Markowitz_Optimization Robust_Optimization  ______________ ________________ ________________ ______________________ ___________________ TotalReturn SharpeRatio 0.18745 0.14991 0.15906 0.17404 0.15655 0.12559 0.092456 0.12179 0.0063474 0.0070186 - 0.0055626 0.0072466 - 0.0058447 0.10339 - 0.11442波动平均成交量0.00087623 0.0065762 0.0028666 0.0058268 0.0025172 MaxTurnover 0.031251 0.239 0.09114 0.21873 0.073746 AverageReturn 0.00083462 0.00068672 0.0007152 0.00078682 0.00070651 maxdown 0.072282 0.084768 0.054344 0.085544 0.064904 AverageBuyCost 0.047298 0.3449 0.15228 0.3155 0.1328 AverageSellCost 0.0427298 0.3449 0.22842 0.3155 0.1328

详细的回测结果,包括日收益、资产头寸和周转率,存储在资产的属性中backtestEngine对象。

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

股权(反向聊天)

图中包含一个坐标轴。标题为权益曲线的轴包含5个类型为line的对象。这些对象代表等加权,最大夏普比,逆方差,马科维茨优化,稳健优化。

移调汇总表,使某些指标的地块可能是有用的。

%转换摘要表以绘制度量标准。summaryByMetrics = rows2vars (summaryByStrategies);summaryByMetrics.Properties。VariableNames {1} ='战略'
核心禁止=5×10表策略TotalReturn SharpeRatio波幅AverageTurnover MaxTurnover AverageReturn最大损失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)

图中包含一个坐标轴。标题为“平均周转”的轴包含一个bar类型的对象。

您可以使用日常资产位置的区域图表随着时间的推移可视化战略分配的变化。有关的信息assetAreaPlot功能,请参见本地功能部分。

StrategyName =“Max_Sharpe_Ratio”;Assetareaplot(反击,StrategyName)

图中包含一个坐标轴。标题为“最大夏普比率位置”的轴包含16个类型区域对象。这些对象代表Cash, AA, CAT, DIS, GM, HPQ, JNJ, MCD, MMM, MO, MRK, MSFT, PFE, PG, T, XOM。

本地功能

策略重新平衡功能以及可变交易成本函数遵循。

函数new_weights = equalWeightFcn(current_weights, pricesTT)%等加权投资组合配置nAssets = size(pricesTT, 2);nAssets new_weights = 1 (1);New_weights = New_weights / sum(New_weights);结尾
函数new_weights = maxsharperatiofcn(current_weights,pricestt)%均值-方差组合配置nAssets = size(pricesTT, 2);assetReturns = tick2ret (pricesTT);%最大25%到单个资产(包括现金)p =组合('numasset'nAssets,......下界的0,'上行',0.1,......'LowerBudget',1,'Unimbudget',1);P = estimateAssetMoments(P,assetReturns {:,:});new_weights = estimateMaxSharpeRatio(P);结尾
函数new_weights = Inversevariancefcn(Current_weights,pricestt)%逆方差投资组合配置assetReturns = tick2ret (pricesTT);assetCov = x (assetReturns {:,:});new_weights = 1 ./ diag(assetCov);New_weights = New_weights / sum(New_weights);结尾
函数new_weights = robustOptimFcn(current_weights, pricesTT)稳健的投资组合配置nAssets = size(pricesTT, 2);assetReturns = tick2ret (pricesTT);Q = x (table2array (assetReturns));SIGMAx =诊断接头(诊断接头(Q));%稳健厌恶系数k = 1.1;%稳健厌恶系数lambda = 0.05;rportfolio =卑鄙(表2Array(Assetreturn))';%创建优化问题probust = OptimProblem('描述''强大的投资组合');%定义变量%xRobust  -  X分配矢量xRobust = optimvar (“x”nAssets 1“类型”'连续'下界的,0.0,'上行', 0.1);zRobust = optimvar (“z”下界的, 0);定义预算限制pRobust.Constraints.budget = sum(x鲁棒)== 1;%定义了稳健的约束probust . constraints .鲁棒= x鲁棒'*SIGMAx* x鲁棒- z鲁棒* z鲁棒<=0;pRobust。目标= -rPortfolio'* x鲁棒+ k* z鲁棒+ lambda* x鲁棒'*Q* x鲁棒;x0.x =零(nAssets,1);x0。Z.=0.;选择= optimoptions (“fmincon”“显示”“关闭”);(solRobust, ~, ~) =解决(x0, pRobust“选项”、选择);new_weights = solRobust.x;结尾
函数new_weights = markowitzfcn(current_weights,pricestt)稳健的投资组合配置nAssets = size(pricesTT, 2);assetReturns = tick2ret (pricesTT);Q = x (table2array (assetReturns));%风险厌恶系数lambda = 0.05;rportfolio =卑鄙(表2Array(Assetreturn))';%创建优化问题pMrkwtz = optimproblem ('描述''Markowitz意味着方差组合');%定义变量%xRobust  -  X分配矢量xmrkwtz = Optimvar(“x”nAssets 1“类型”'连续'下界的,0.0,'上行', 0.1);定义预算限制pmrkwtz.constraints.budget = sum(xmrkwtz)== 1;定义马科维茨目标pMrkwtz.Objective = -rPortfolio '* xMrkwtz +拉姆达* xMrkwtz' * Q * xMrkwtz;x0.x =零(nAssets,1);选择= optimoptions (“quadprog”“显示”“关闭”);(solMrkwtz, ~, ~) =解决(x0, pMrkwtz“选项”、选择);new_weights = solMrkwtz.x;结尾
函数[买,卖] = variabletransactioncosts(deltapositions)可变交易成本函数这个函数是如何计算可变交易成本的一个例子。%根据市场价值的变化计算成比例的交易成本重新平衡后的每笔资产。成本以下列费率计算:%buys:%$ 0- $ 10,000:0.5%%$ 10,000 +:0.35%%卖:%$ 0- $ 1,000:0.75%% $ 1000 +: 0.5%购买=零(1,numel(deltapositions));卖=零(1,Numel(Deltapositions));%购买idx = 0 % 50基点idx = 1e4 <= deltaPositions;买进(idx) = 0.0035 *买入(idx);35个%的基础ponits买=总和(买);%销售idx = -1e3 < 0;卖出(idx) = 0.0075 *减仓(idx);% 75个基点idx = deltaPositions <= -1e3;卖出(idx) = 0.005;% 50基点销售=总和(销售);结尾
函数Assetareaplot(反击,StrategyName)%绘制资产分配作为区域图。T = backtester.Positions(strategyName)。时间。位置= backtester.Positions(strategyName).Variables。H =区域(T,位置);标题(Sprintf('%s职位',strrep(StrategyName,'_''')));包含('日期');ylabel('资产职位');dateTick(“x”'mm / dd''保持');XLIM([T(1)T(end)])offylim = ylim;ylim([0 offylim(2)]);cm = parula(numel(h));为了I = 1:numel(h) set(h(I),“FaceColor”,cm(i,:));结尾传奇(反击。(StrategyName).properties.variablenames)结尾

也可以看看

|||

相关的话题