Skip to content
Published on

コア・サテライトETF自動リバランス

Authors
  • Name
    Twitter
コア・サテライトETF自動リバランス

コア・サテライト戦略とは

コア・サテライト(Core-Satellite)は、ポートフォリオを2つの役割に分ける資産配分戦略だ。**コア(Core)**は市場全体を追従する低コストのインデックスETFで構成し、安定的な収益を追求する。**サテライト(Satellite)**は特定セクター、テーマ、スタイルのETFで構成し、超過収益(アルファ)を狙う。

この戦略は100%インデックス投資と100%アクティブ投資の中間点だ。David Swensen(イェール大学基金運用者)が Unconventional Success で提案した個人投資家向け資産配分の核心でもある。

コア・サテライトの基本原則:

  • コア比率60-80%、サテライト比率20-40%
  • コアはほとんど手を加えない(年1-2回リバランス)
  • サテライトは市場状況に応じて入替可能(四半期単位で検討)
  • ポートフォリオ全体の経費率(TER)を0.3%以下に維持

コアとサテライトの役割分離

コア:市場ベータを確保する

コアの目標はシンプルだ。市場収益率を最も低いコストで獲得すること。「市場に勝とう」とはしない。

コアETF選定基準:

  1. 運用報酬0.1%以下(報酬は確実なマイナス収益)
  2. 純資産1,000億ウォン以上(流動性確保)
  3. トラッキングエラー最小(指数との乖離が少ない)
  4. 配当再投資構造(TR指数追従優先)

韓国で利用可能なコアETF候補(2026年基準):

ETF銘柄コード追従指数報酬純資産用途
TIGER 米国S&P500360750S&P 5000.07%6.5兆ウォン米国大型株
KODEX 米国S&P500TR379800S&P 500 TR0.05%3.2兆ウォン米国大型株(配当再投資)
KODEX 200069500KOSPI 2000.05%5.8兆ウォン韓国大型株
TIGER 米国ナスダック100133690NASDAQ-1000.07%4.1兆ウォン米国テック株
KODEX 米国債ウルトラ30年先物(H)304660US Treasury 30Y0.09%2,800億ウォン米国長期債
TIGER 米国債10年先物305080US Treasury 10Y0.09%1.2兆ウォン米国中期債
KODEX 総合債券(AA-以上)アクティブ443160国内優良債券0.05%3,500億ウォン国内債券

サテライト:テーマとアルファを追求する

サテライトは特定セクター、地域、スタイルに集中投資して市場対比の超過収益を狙う。コアと違い入替が可能であり、確信がなければ比率を下げるか現金で保持できる。

サテライトETFの種類:

種類特徴リスク度
セクター半導体、二次電池、バイオ特定産業に集中高い
テーマAI、ロボット、クリーンエネルギー成長トレンド追従高い
地域インド、日本、ベトナム特定国の成長中〜高
スタイル高配当、バリュー株、小型株ファクターベース投資
オルタナ金、コモディティ、リート低相関、分散効果

サテライト入替判断基準:

  • 投資論理(thesis)がまだ有効か?
  • 前四半期のベンチマーク対比パフォーマンスは?
  • より低い報酬の類似ETFが発売されたか?
  • ポートフォリオ内の相関関係が過度に高くなっていないか?

実践ポートフォリオ設計:3つのシナリオ

シナリオ1:安定成長型(保守的投資家)

# 目標:年6-8%収益、最大ドローダウン15%以内
# 対象:退職10-15年前、元本保全重視
portfolio:
  name: '安定成長型'
  core_weight: 0.80
  satellite_weight: 0.20

  core:
    - ticker: 'KODEX 米国S&P500TR'
      weight: 0.30
      role: '米国市場ベータ'
    - ticker: 'KODEX 200'
      weight: 0.15
      role: '韓国市場ベータ'
    - ticker: 'TIGER 米国債10年先物'
      weight: 0.20
      role: '金利低下時の防御'
    - ticker: 'KODEX 総合債券(AA-以上)アクティブ'
      weight: 0.15
      role: '安定的な利息収入'

  satellite:
    - ticker: 'TIGER 金銀先物(H)'
      weight: 0.10
      role: 'インフレヘッジ'
    - ticker: 'TIGER 米国配当ダウジョーンズ'
      weight: 0.10
      role: '配当収入'

  expected:
    annual_return: '6-8%'
    max_drawdown: '-15%'
    total_expense_ratio: '0.07%'

シナリオ2:成長追求型(30代会社員)

# 目標:年10-12%収益、最大ドローダウン25%許容
# 対象:投資期間15年以上、積極的成長追求
portfolio:
  name: '成長追求型'
  core_weight: 0.65
  satellite_weight: 0.35

  core:
    - ticker: 'TIGER 米国S&P500'
      weight: 0.35
      role: '米国市場ベータ'
    - ticker: 'TIGER 米国ナスダック100'
      weight: 0.15
      role: 'テック株の成長'
    - ticker: 'KODEX 200'
      weight: 0.10
      role: '韓国市場ベータ'
    - ticker: 'TIGER 米国債10年先物'
      weight: 0.05
      role: '最小債券配分'

  satellite:
    - ticker: 'TIGER 半導体'
      weight: 0.12
      role: '半導体サイクルアルファ'
    - ticker: 'KODEX 二次電池産業'
      weight: 0.08
      role: '二次電池の成長'
    - ticker: 'TIGER Fn半導体TOP10'
      weight: 0.08
      role: '韓国半導体集中'
    - ticker: 'TIGER インドNifty50'
      weight: 0.07
      role: 'インド市場の成長'

  expected:
    annual_return: '10-12%'
    max_drawdown: '-25%'
    total_expense_ratio: '0.15%'

シナリオ3:オールウェザー型(変動性最小化)

# 目標:あらゆる市場環境でプラス収益を追求
# 対象:変動性を極度に嫌う投資家
# 参考:Ray DalioのAll Weather戦略のバリエーション
portfolio:
  name: 'オールウェザー型'
  core_weight: 0.85
  satellite_weight: 0.15

  core:
    - ticker: 'TIGER 米国S&P500'
      weight: 0.25
      role: '景気拡大期の収益'
    - ticker: 'TIGER 米国債10年先物'
      weight: 0.25
      role: '景気後退防御'
    - ticker: 'KODEX 米国債ウルトラ30年先物(H)'
      weight: 0.15
      role: 'デフレーション防御'
    - ticker: 'KODEX 総合債券(AA-以上)アクティブ'
      weight: 0.10
      role: '安定的な利息'
    - ticker: 'TIGER 金銀先物(H)'
      weight: 0.10
      role: 'インフレヘッジ'

  satellite:
    - ticker: 'KODEX 200'
      weight: 0.10
      role: '韓国市場エクスポージャー'
    - ticker: 'TIGER 原油先物Enhanced(H)'
      weight: 0.05
      role: 'コモディティインフレ対応'

  expected:
    annual_return: '5-7%'
    max_drawdown: '-10%'
    total_expense_ratio: '0.09%'

自動リバランスの実装

コア vs サテライト分離リバランス

コアとサテライトはリバランスの周期と基準が異なる。一つのルールにまとめない。

"""
コア・サテライト分離リバランスエンジン
- コア:年2回+乖離5%超過時に緊急
- サテライト:四半期1回+乖離7%超過時に緊急
"""
from dataclasses import dataclass


@dataclass
class RebalanceRule:
    """資産タイプ別リバランスルール。"""
    section: str            # "core" or "satellite"
    scheduled_frequency: str  # "semi-annual" or "quarterly"
    drift_threshold: float    # 乖離閾値
    min_trade_krw: int        # 最小取引金額


RULES = {
    "core": RebalanceRule(
        section="core",
        scheduled_frequency="semi-annual",
        drift_threshold=0.05,
        min_trade_krw=200_000,
    ),
    "satellite": RebalanceRule(
        section="satellite",
        scheduled_frequency="quarterly",
        drift_threshold=0.07,
        min_trade_krw=100_000,
    ),
}


def check_section(
    section: str,
    holdings: dict,
    targets: list[dict],
    total_value: int,
) -> dict:
    """特定セクションのリバランス必要性を判断する。"""
    rule = RULES[section]
    drift_alerts = []

    for target in targets:
        code = target["code"]
        current_value = holdings.get(code, {}).get("value_krw", 0)
        current_weight = current_value / total_value if total_value > 0 else 0
        target_weight = target["weight"]
        drift = abs(current_weight - target_weight)

        if drift > rule.drift_threshold:
            drift_alerts.append({
                "ticker": target["ticker"],
                "code": code,
                "target": target_weight,
                "current": round(current_weight, 4),
                "drift": round(drift, 4),
                "action_needed": True,
            })

    return {
        "section": section,
        "rule": rule,
        "needs_rebalancing": len(drift_alerts) > 0,
        "alerts": drift_alerts,
    }


def run_core_satellite_rebalance(portfolio_config: dict, holdings: dict):
    """コアとサテライトを分離して各リバランスを実行する。"""
    total_value = sum(h["value_krw"] for h in holdings.values())

    print(f"総資産: ₩{total_value:,}\n")

    for section in ["core", "satellite"]:
        targets = portfolio_config[section]
        result = check_section(section, holdings, targets, total_value)

        section_label = "コア" if section == "core" else "サテライト"
        print(f"=== {section_label} チェック ===")
        print(f"リバランス周期: {result['rule'].scheduled_frequency}")
        print(f"乖離閾値: ±{result['rule'].drift_threshold * 100}%")

        if result["needs_rebalancing"]:
            print(f"状態: リバランス必要")
            for alert in result["alerts"]:
                print(
                    f"  - {alert['ticker']}: "
                    f"目標 {alert['target']*100:.1f}% / "
                    f"現在 {alert['current']*100:.1f}% / "
                    f"乖離 {alert['drift']*100:.1f}%p"
                )
        else:
            print("状態: 正常範囲内")
        print()


# 使用例
config = {
    "core": [
        {"ticker": "TIGER 米国S&P500", "code": "360750", "weight": 0.35},
        {"ticker": "KODEX 200", "code": "069500", "weight": 0.15},
        {"ticker": "TIGER 米国債10年先物", "code": "305080", "weight": 0.15},
    ],
    "satellite": [
        {"ticker": "TIGER 半導体", "code": "091230", "weight": 0.12},
        {"ticker": "KODEX 二次電池産業", "code": "305720", "weight": 0.08},
        {"ticker": "TIGER インドNifty50", "code": "453810", "weight": 0.07},
    ],
}

holdings = {
    "360750": {"value_krw": 4_500_000},
    "069500": {"value_krw": 1_500_000},
    "305080": {"value_krw": 1_200_000},
    "091230": {"value_krw": 1_800_000},
    "305720": {"value_krw": 600_000},
    "453810": {"value_krw": 400_000},
}

run_core_satellite_rebalance(config, holdings)

サテライト入替ロジック

サテライトは四半期ごとにパフォーマンスをレビューし、投資論理が弱まった銘柄を入れ替える。

"""サテライトETFパフォーマンスレビューと入替判断。"""

def evaluate_satellite(
    ticker: str,
    quarter_return: float,
    benchmark_return: float,
    thesis_valid: bool,
    cheaper_alternative: str | None = None,
) -> dict:
    """サテライトETFの入替必要性を判断する。"""
    excess_return = quarter_return - benchmark_return

    recommendation = "HOLD"
    reasons = []

    # 投資論理が無効化された場合
    if not thesis_valid:
        recommendation = "REPLACE"
        reasons.append("投資論理(thesis)がもはや有効ではない")

    # 3四半期連続でベンチマーク対比不振の場合
    if excess_return < -0.05:
        recommendation = "REVIEW"
        reasons.append(
            f"ベンチマーク対比 {excess_return*100:.1f}%p 不振"
        )

    # より安価な代替が存在する場合
    if cheaper_alternative:
        reasons.append(f"報酬がより低い代替あり: {cheaper_alternative}")

    return {
        "ticker": ticker,
        "quarter_return": f"{quarter_return*100:.1f}%",
        "excess_return": f"{excess_return*100:.1f}%p",
        "recommendation": recommendation,
        "reasons": reasons,
    }


# 四半期レビュー例
reviews = [
    evaluate_satellite(
        ticker="TIGER 半導体",
        quarter_return=0.12,
        benchmark_return=0.08,
        thesis_valid=True,
    ),
    evaluate_satellite(
        ticker="KODEX 二次電池産業",
        quarter_return=-0.03,
        benchmark_return=0.08,
        thesis_valid=True,
    ),
    evaluate_satellite(
        ticker="TIGER インドNifty50",
        quarter_return=0.06,
        benchmark_return=0.08,
        thesis_valid=True,
        cheaper_alternative="KODEX インドNifty50(合成)",
    ),
]

print("=== サテライト四半期レビュー ===")
for r in reviews:
    print(f"\n{r['ticker']}")
    print(f"  四半期収益率: {r['quarter_return']}")
    print(f"  超過収益: {r['excess_return']}")
    print(f"  判定: {r['recommendation']}")
    if r["reasons"]:
        for reason in r["reasons"]:
            print(f"  - {reason}")

相関関係管理:分散効果の維持

コア・サテライト戦略の落とし穴の一つは、サテライト同士の相関関係が高くなることだ。半導体ETFとナスダック100 ETFを同時に保有すると、実質的にテック株に過度に集中することになる。

相関関係モニタリング

"""ポートフォリオ内のETF相関関係を計算する。"""
import numpy as np


def check_correlation(returns_matrix: dict, threshold: float = 0.8) -> list:
    """高い相関関係を持つETFペアを見つける。

    Args:
        returns_matrix: {銘柄コード: [日次収益率リスト]}
        threshold: 警告基準の相関係数

    Returns:
        相関係数がthresholdを超えるETFペアのリスト
    """
    tickers = list(returns_matrix.keys())
    data = np.array([returns_matrix[t] for t in tickers])
    corr = np.corrcoef(data)

    high_corr_pairs = []
    for i in range(len(tickers)):
        for j in range(i + 1, len(tickers)):
            if abs(corr[i][j]) > threshold:
                high_corr_pairs.append({
                    "pair": (tickers[i], tickers[j]),
                    "correlation": round(corr[i][j], 3),
                    "warning": "分散効果の弱体化 - 一方の比率縮小を検討",
                })

    return high_corr_pairs


# 例:60日間の日次収益率(シミュレーション)
np.random.seed(42)
market = np.random.normal(0.0005, 0.01, 60)

sample_returns = {
    "S&P500": market + np.random.normal(0, 0.002, 60),
    "NASDAQ100": market * 1.3 + np.random.normal(0, 0.003, 60),
    "半導体": market * 1.5 + np.random.normal(0, 0.005, 60),
    "米国債10年": -market * 0.3 + np.random.normal(0, 0.003, 60),
    "金": np.random.normal(0.0002, 0.008, 60),
}

alerts = check_correlation(sample_returns, threshold=0.7)

print("=== 相関関係警告 ===")
for alert in alerts:
    print(f"  {alert['pair'][0]} <-> {alert['pair'][1]}: "
          f"相関係数 {alert['correlation']}")
    print(f"  -> {alert['warning']}")

コア・サテライト運営年間カレンダー

コアサテライトその他
1月定期リバランス四半期レビュー+年間戦略点検年間収益率精算、税金確認
2-3月乖離モニタリング-配当基準日確認
4月-四半期レビューISA/IRP拠出状況点検
5-6月乖離モニタリング-中間点検
7月定期リバランス四半期レビュー下半期戦略調整
8-9月乖離モニタリング--
10月-四半期レビュー+翌年戦略策定ISA/IRP年末拠出計画
11-12月乖離モニタリング-税金最適化売買(海外ETF)

クイズ

Q1. コア・サテライト戦略におけるコアの役割は? 正解:市場全体の収益率(ベータ)を低コストで確保すること。市場に勝とうとせず、インデックスETFで安定的な収益を追求する。

Q2. コアとサテライトのリバランス周期が異なる理由は? 正解:コアは長期保有が原則のため、年1-2回の定期リバランスで十分だ。サテライトは市場状況に応じて入替可能なので四半期単位でレビューする。それぞれの性格に合った管理周期を適用することで、不要な売買を減らすことができる。

Q3. サテライトETF入替を判断する最も重要な基準は? 正解:投資論理(thesis)がまだ有効かどうかだ。短期パフォーマンス不振だけで入替すると感情的売買になり、投資論理が無効化されても保有し続ければ損失が拡大する。

Q4. ポートフォリオ内のETF相関関係が高いとなぜ問題か? 正解:相関関係の高い資産を複数保有すると分散効果が消滅する。例えばS&P500+NASDAQ100+半導体ETFを同時に保有すると、テック株下落時に3銘柄が同時に下落し、ポートフォリオ全体が大きな打撃を受ける。

Q5. オールウェザー型ポートフォリオが株式、債券、金を同時に保有する理由は? 正解:景気拡大期(株式上昇)、景気後退期(債券上昇)、インフレ期(金上昇)、デフレ期(長期債上昇)など、あらゆる環境で一部の資産が収益を上げるよう設計されている。Ray DalioのAll Weather戦略の核心原理だ。

Q6. コアETF選定時に報酬(TER)を最も重視する理由は? 正解:コアETFは長期間(10年以上)保有するため、報酬が複利で蓄積される。報酬0.05%と0.5%の差は、20年後に約9%の収益率差を生む。コアは市場収益率を追従するため、報酬が低いほど実質収益が高くなる。

参考資料