主要内容

val投资策略

这个例子展示了如何使用MATLAB®中实现的回溯测试框架来执行投资组合策略的回溯测试。回溯测试是比较投资策略在历史或模拟市场数据中的表现的有用工具。这个例子开发了五种不同的投资策略,然后在运行了一年的历史股票数据后比较它们的表现。回溯测试框架在两个MATLAB®类中实现:backtestStrategy倒退生儿

加载数据

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

对于本例,使用道琼斯工业平均指数成份股的一年资产价格数据。

%阅读2006年道琼斯工业平均指数股票的每日调整收盘价表。t = readtable(“dowPortfolio.xlsx”);%为了可读性,只使用30个DJI组件股票中的15个。assetsymbols = [“AA”“猫”“说”“通用汽车”“hp”“公司”“力”“嗯”“莫”“期望”“微软”“工业”“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 = (pricesTT大小。变量,1);numAssets = (pricesTT大小。变量,2);表(numSample numAssets)
ans =.1×2表numSample numAssets _________ _________ 251 15

定义策略

投资策略抓住了在进行回溯测试时做出资产配置决策的逻辑。随着回溯测试的进行,每种策略都会定期获得机会,根据落后的市场状况更新其投资组合配置,方法是设置一个资产权重向量。资产权重表示投资于每个资产的可用资本的百分比,权重向量中的每个元素对应于资产中相应的列pricesTT时间表。如果权重向量的总和是1然后,投资组合已全面投入。

在此示例中,有五种反向策略。后退策略使用以下Crieria分配资产权重:

  • 同等加权

ω. 电子战 ω. 1 ω. 2 ω. N ω. 1 N

  • 锐利比率的最大化

ω. 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 , 在哪里 λ. 为风险厌恶系数。

  • 预期收益不确定的稳健优化

  • 稳健投资组合优化策略与确定性的马柯维茨公式不同,它考虑了资产的不确定性预期收益及其方差和协方差。与将未知值(例如,预期回报)建模为一个点(通常由过去计算的平均值表示)不同,未知量被指定为一组包含最有可能实现的值, 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

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

R 健壮的 马克斯 ω. { r ω. - λ. ω. ω. - kz | ω. 0 z 0 ω. σ. r ω. - z 2 0 1 N ω. 1 0 ω. 0 1

实施战略重新平衡职能

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

函数new_weights = allocationFunctionNamecurrent_weights,价格是奖项

这个固定的签名是backtest框架在重新平衡投资组合时使用的API。当backtest运行时,backtest引擎调用每个策略的rebalance函数,传入这些输入:

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

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

backtestStrategyRebalance函数使用这些信息来计算所需的新投资组合权重,这些权重将在函数输出中返回到后台测试引擎new_weights.看到本地函数五项策略中的每一个的重新平衡函数的部分。

计算初始策略权重

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

此示例使用数据集的前40天(大约2个月)来初始化策略。然后,返回最终通过剩余数据(大约10个月)运行。

warmupPeriod = 40;

初始权值是通过调用backtestStrategyRebalance函数的方式与后台测试引擎调用它的方式相同。为此,传入一个当前权重向量(全部为零,即100%现金),以及一个价格数据窗口,策略将使用该窗口设置所需的权重(热身数据分区)。不需要使用rebalance函数以这种方式计算初始权重。初始权重是初始投资组合权重的向量,可以设置为任意合适的值。这个例子中的rebalance函数近似于策略在回测开始时已经运行的状态。

%没有当前权重(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策略

要使用回溯测试框架中的策略,您必须构建backtestStrategy对象,每个策略对应一个对象。的backtestStrategy函数将每个策略的策略名称和再平衡函数作为输入。此外,backtestStrategy可以采用各种名称 - 值对参数来指定各种选项。有关创建反向策略的更多信息,请参阅backtestStrategy

设置再平衡频率和回调窗口大小是根据时间步长(即pricesTT时间表)。由于数据是每日价格数据,请指定以天为单位的再平衡频率和回滚窗口。

大约每1个月重新平衡(252/12 = 21)。rebalfreq = 21;%设置回滚窗口为至少40天,最多126天%天(约6个月)。Lookback = [40 126];%使用固定交易成本(买卖成本均为金额的0.5%)%交易)。transactionsFixed = 0.005;%使用函数自定义交易成本。看到% variableTransactionCosts函数的例子如下。transactionsVariable = @variableTransactionCosts;前两种策略使用固定交易成本。的等权%策略不需要跟踪数据的回溯窗口,因为它的%分配是固定的。strat1 = backtestStrategy(“并重”@equalWeightFcn,...“RebalanceFrequency”rebalFreq,...“LookbackWindow”0,...“TransactionCosts”,交易,...“InitialWeights”, equalWeight_initial);strat2 = backtestStrategy (“马克斯·夏普比率”,@maxsharperatiofcn,...“RebalanceFrequency”rebalFreq,...“LookbackWindow”lookback,...“TransactionCosts”,交易,...“InitialWeights”, maxSharpeRatio_initial);%使用可变交易成本为剩余策略。strat3 =反向临时(“逆方差”@inverseVarianceFcn,...“RebalanceFrequency”rebalFreq,...“LookbackWindow”lookback,...“TransactionCosts”@variableTransactionCosts,...“InitialWeights”, inverseVariance_initial);strat4 = backtestStrategy (“马科维茨优化”@markowitzFcn,...“RebalanceFrequency”rebalFreq,...“LookbackWindow”lookback,...“TransactionCosts”,交易,...“InitialWeights”,markowitz_initial);strat5 =反向临时(鲁棒优化的@robustOptimFcn,...“RebalanceFrequency”rebalFreq,...“LookbackWindow”lookback,...“TransactionCosts”,交易,...“InitialWeights”, robustOptim_initial);%将策略对象聚合为一个数组。策略= [strat1, strat2, strat3, strat4, strat5];

val的策略

使用下面的工作流对策略进行回溯测试倒退生儿

定义回离引擎

倒退生儿函数接受的数组作为输入backtestStrategy对象。此外,使用时倒退生儿,您可以设置多种选项,例如无风险速率和初始产品组合值。在年度条款中规定无风险率时,倒退生儿用途基础财产设定当天计数约定。有关创建反垄断引擎的更多信息,请参阅倒退生儿

年化无风险率为1%annualRiskFreeRate = 0.01;%创建后台测试引擎对象val = backtestEngine(策略,“RiskFreeRate”annualRiskFreeRate)
backtester = backtestEngine with properties: Strategies: [1x5 backtestStrategy] RiskFreeRate: 0.0100 CashBorrowRate: 0 rate convention: "Annualized" Basis: 0 InitialPortfolioValue: 10000 NumAssets: [] Returns: [] Positions: [] Turnover: [] BuyCost: [] SellCost: []

运行,val

使用runBacktest使用测试数据分区运行回测。使用runBacktest名称-值对的观点“开始”避免前瞻性偏见(即“预见未来”)。在“热身”阶段结束时开始回溯测试。的空字段,运行回测倒退生儿对象的逐日回溯测试结果。

反向临时= Runbacktest(反击,Pricestt,“开始”warmupPeriod)
反向临时=逆景期收购:[211x5时间表] SELLCOST:[211x5时间表]

检查,val结果

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

summaryByStrategies =总结(val)
summaryByStrategies =9×5表Equal_Weighted Max_Sharpe_Ratio Inverse_Variance Markowitz_Optimization Robust_Optimization ______________ ________________ ________________ ______________________ ___________________ TotalReturn 0.18745 0.14991 0.15906 0.17404 0.15655 SharpeRatio -1.4474 -1.3301 -1.6731 -1.2744 -1.5938波动0.0063474 0.0070186 0.0055626 0.0072466 0.0058447 AverageTurnover 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.000786820.00070651最大损失0.072392 0.084768 0.054344 0.085544 0.064904 0.047298 AverageBuyCost 0.3449 0.15228 0.3155 0.1328 AverageSellCost 0.047298 0.3449 0.22842 0.3155 0.1328

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

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

equityCurve (val)

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

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

转置汇总表以绘制度量。summaryByMetrics = rows2vars (summaryByStrategies);summaryByMetrics.Properties。VariableNames {1} =“策略”
summaryByMetrics =5×10表策略TotalReturn SharpeRatio波幅AverageTurnover MaxTurnover AverageReturn最大损失AverageBuyCost AverageSellCost __________________________ ___________ ___________ __________ _______________ ___________ _____________ ___________ ______________ _______________ { 'Equal_Weighted'} 0.18745 -1.4474 0.0063474 0.00087623 0.031251 0.00083462 0.072392 0.047298 0.047298 { 'Max_Sharpe_Ratio'} 0.14991 -1.3301 0.0070186 0.0065762 0.239 0.00068672 0.084768 0.3449 0.3449{ 'Inverse_Variance'} 0.15906 -1.6731 0.0055626 0.0028666 0.09114 0.0007152 0.054344 0.15228 0.22842 { 'Markowitz_Optimization'} 0.17404 -1.2744 0.0072466 0.0058268 0.21873 0.00078682 0.085544 0.3155 0.3155 { 'Robust_Optimization'} 0.15655 -1.5938 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”;strategyName assetAreaPlot (val)

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

本地函数

接下来是战略再平衡函数以及可变交易成本函数。

函数new_weights =平等福克(Current_weights,pricestt)%等加权投资组合配置nAssets = size(pricesTT, 2);new_weights = =那些(1,尼索特);New_weights = New_weights / sum(New_weights);结束
函数new_weights = maxSharpeRatioFcn(current_weights, pricesTT)%均值-方差组合配置nAssets = size(pricesTT, 2);assetReturns = tick2ret (pricesTT);最多25%进入单一资产(包括现金)p = portfolio(“NumAssets”,尼索特,...下界的,0,“UpperBound”, 0.1,...“LowerBudget”,1,“UpperBudget”,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;稳健厌恶系数λ= 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.Budget = Sum(Xrobust)== 1;定义鲁棒约束probust.constraints.robust = xrobust'* sigmax * xrobust  -  zrobust * zrobust <= 0;probust.objective = -rportfolio'* xrobust + k * zrobust + lambda * xrobust'* q * xrobust;x0.x =零(拐角,1);x0.z = 0;选择= Optimoptions('粉丝''展示''离开');(solRobust, ~, ~) =解决(x0, pRobust“选项”、选择);new_weights = solrobust.x;结束
函数new_weights = markowitzFcn(current_weights, pricesTT)稳健的投资组合配置nAssets = size(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.budget = sum(xMrkwtz) == 1;定义马科维茨目标pMrkwtz.Objective = -rPortfolio '* xMrkwtz +拉姆达* xMrkwtz' * Q * xMrkwtz;x0.x =零(拐角,1);选择= Optimoptions(“quadprog”'展示''离开');[solmrkwtz,〜,〜] =解决(pmrkwtz,x0,“选项”、选择);new_weights = solMrkwtz.x;结束
函数[买入,卖出]= varabletransactioncosts (deltaPositions)%可变事务成本函数%此函数是如何计算可变事务成本的示例。%根据市场价值的变化计算成比例的交易成本每个资产在重新平衡后%。费用按下列费率计算:%购买:% $0-$10,000: 0.5%% $10,000+: 0.35%%销售:% $0-$1,000: 0.75%%$ 1,000 +:0.5%买= 0(1,元素个数(deltaPositions));销售= 0(1,元素个数(deltaPositions));%购买idx = 0 < = 0;买进(idx) = 0.005 * deltaPositions(idx);%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个基点卖=总和(卖);结束
函数strategyName assetAreaPlot (val)%绘制资产分配面积图。T = backtester.Positions(strategyName)。时间。位置= backtester.Positions(strategyName).Variables。H =区域(T,位置);标题(sprintf的(“% s的立场”strrep (strategyName“_”' ')));Xlabel(“日期”);ylabel (“资产头寸”);datetick (“x”“mm / dd”“keepticks”);Xlim ([t(1) t(end)]) oldylim = ylim;ylim ([0 oldylim (2)]);厘米= parula(元素个数(h));I = 1:numel(h) set(h(I),“FaceColor”厘米(我:));结束传奇(backtester.Positions (strategyName) .Properties.VariableNames)。结束

另请参阅

|||

相关的话题