포트폴리오의 리밸런스: 효과를 계산해 보았다(리밸런스편)
목차
2. 리밸런스편
여기에서는 실제로 리밸런스의 효과를 확인하기 위해서 세금·수수료의 약간 까다로운 곳도
싹둑 모델화해 계산해 보겠습니다.
2.1 우선 결과로부터
코드가 흩어져 버렸기 때문에 함수(getHistoricalMarketValue.m)는 모아 마지막에 소개합니다만,
targetWeight = [31, 23.4, 6.1, 27.7, 6.8, 5.0]/100;
commission = 0.0054; % 取引手数料(税込み) 0.54%
taxrate = 0.20; % 税金はざっくり 20%
rebalanceThreshold = 0; % 毎週
% pfQty 保有数
% pfMarketValue 評価額
[pfMarketValue, pfQty] = getHistoricalMarketValue(pricedata, divdata, ...
commission, taxrate, ...
rebalanceThreshold, targetWeight);
느낌으로 계산합니다. 우선 타겟의 종목 비율, 수수료율, 세율을 지정. rebalanceThreshold는 균형이 얼마나 깨졌을 때 재조정을 수행할지에 대한 임계값을 지정합니다. 0%의 경우는 매주(주간 데이터이므로) 리밸런스를 실시하고, 100%의 경우는 리밸런스는 실시되지 않습니다.
얻은 결과를 시각화합니다.
figure
subplot(2,1,1)
bar(pricedata.time,pfMarketValue,'stacked','DisplayName','tmp');
legend(pricedata.Properties.VariableNames)
title('評価額推移(リバランスあり)')
subplot(2,1,2)
ps = pfMarketValue./sum(pfMarketValue,2);
bar(pricedata.time,ps,'stacked','DisplayName','tmp');
title('各銘柄の保有割合の推移(リバランスあり)')
플롯 해 보면 깨끗하게 리밸런스 되어 있는 것을 알 수 있군요.
참고까지, 리밸런스하지 않았던 경우(+76%)도 플롯 해 둡니다.
rebalanceThreshold = 1; % リバランス無しに設定
[pfMarketValue, pfQty] = getHistoricalMarketValue(pricedata, divdata, ...
commission, taxrate, ...
rebalanceThreshold, targetWeight);
figure
subplot(2,1,1)
bar(pricedata.time,pfMarketValue,'stacked','DisplayName','tmp');
legend(pricedata.Properties.VariableNames)
title('評価額推移(リバランス無し)')
subplot(2,1,2)
ps = pfMarketValue./sum(pfMarketValue,2);
bar(pricedata.time,ps,'stacked','DisplayName','tmp');
title('各銘柄の保有割合の推移(リバランス無し)')
주가가 크게 떨어진 리먼 쇼크당 채권(AGG) 비율이 훨씬 높아졌습니다. 채권의 비율이 커져 버린 것으로, 그 후의 주가의 성장을 누릴 수 없었다··라고 느끼겠습니까.
리밸런스는 하면서, 수수료로 지나치게 지워지지 않도록, 크게 시세가 움직일 때만 리밸런스를 한다, 그런 경우를 상정해 15% 무너졌을 때만 리밸런스를 실시하는 케이스를 플롯한 것이 이하. 2회 리밸런스가 발생하고 있네요. 결과적으로 재조정하지 않을 때에 비해 24% (+76% -> +100%) 성능이 향상되었습니다.
주가는 계속 오르고 있었기 때문에 2번째의 리밸런스는 실시하지 않는 것이 퍼포먼스는 좋았을지도 모르겠네요.
아니, 원래 리밸런스는 「리밸런스에 의해서, 리스크를 너무 취하는 것을 막는」것이 목적이었습니다.
2.2 getHistoricalMarketValue.m
실제의 리밸런스를 실시하고 있는 코드는 이쪽. 수수료・세금의 취급이 귀찮습니다.
괴로워 혼란에 여러가지 눈을 찌르고 코드화하고 있습니다만, 치명적인 실수가 있으면 가르쳐 주세요. .
getHistoricalMarketValue.m
function [pfMarketValue,pfQty,fees,taxes] = getHistoricalMarketValue(pricedata, divdata, ...
commission, taxrate, ...
rebalanceTh, targetWeight)
pfQty = zeros(size(pricedata)); % 保有数
pfMarketValue = zeros(size(pricedata)); % 評価額
fees = zeros(height(pricedata)); % 手数料
taxes = zeros(height(pricedata)); % 税金
pfQty(1,:) = pricedata{1,:}.\targetWeight; % 初期保有数
pfMarketValue(1,:) = pricedata{1,:}.*pfQty(1,:); % 初期評価額
% 2週目から順に計算
for ii=2:height(pricedata)
pfQty_old = pfQty(ii-1,:);
% 先週と同じ株数での評価額
% 配当金も再投資しますが購入手数料と税金は引いておきます。
pfMarketValue(ii,:) = (pricedata{ii,:}+divdata{ii,:}*(1-commission)*(1-taxrate)).*pfQty_old;
% 配当金再投資後の株数
pfQty(ii,:) = pfMarketValue(ii,:)./pricedata{ii,:};
% 現時点での評価額
MarketValueNow = sum(pfMarketValue(ii,:),2);
% ポートフォリオバランス確認
actualWeight = pfMarketValue(ii,:)/MarketValueNow;
% ターゲットとの差分
difWeight = actualWeight - targetWeight;
% 1銘柄でも最低閾値を超えてバランスが崩れていればリバランス実行
if max(abs(difWeight)) > rebalanceTh
what2sell = difWeight > 0; % 想定割合を超えている銘柄認識
amount2sell = difWeight(what2sell)*MarketValueNow; % 各銘柄の売却額
% 売却益はあるかな?(簡易的に初期購入時の株価との差額を使用)
priceDif = pricedata{ii,what2sell} - pricedata{1,what2sell}; % 株価の差額(1株当たり)
capGain = priceDif.*(amount2sell./pricedata{ii,what2sell}); % 差額 x 売却株数 = 売却益
capGain = capGain - sum(amount2sell)*commission; % 手数料分減額
% 売却益 x 20% は税金(マイナスの場合還付あり想定)
taxLoss = sum(capGain)*taxrate;
% 手数料も引いて購入資金となる・・と。(売却・購入双方)
totalLoss = sum(amount2sell)*commission*2 + taxLoss;
% 税引き後の評価額
pfQty(ii,:) = pricedata{ii,:}.\targetWeight*sum(MarketValueNow - totalLoss);
pfMarketValue(ii,:) = pfQty(ii,:).*pricedata{ii,:};
taxes(ii) = taxLoss;
fees(ii) = sum(amount2sell)*commission*2;
end
end
end
Reference
이 문제에 관하여(포트폴리오의 리밸런스: 효과를 계산해 보았다(리밸런스편)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/eigs/items/e9496dac362331e61cc7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)