CovBlock-Sim

Simulation Methodology

Calculation rules and data processing methods used by CoveredCall Block-Sim

1. Data Collection & Storage

All data is collected from Yahoo Finance.

Collected Fields (Daily)

FieldSourceDescription
priceCloseClosing price of the day
daily_returnDerived value(today close - previous close) / previous close
dividendTicker.dividendsDividend per share on payout date (0 if none)
vix^VIX CloseCBOE Volatility Index
estimated_premiumDerived valueVIX-based option premium approximation

Premium Approximation Formula

Historical option data is approximated using VIX:

premium = VIX / 100 × cover_ratio × premium_factor × 0.7
// premium_factor: 0.3 with ELN, 1.0 without ELN

Collection period: From January 1, 2000 to present. For periods before an ETF was listed, synthetic data is used (see Section 3).

2. Block Structure

A block encapsulates market conditions for a specific period. Users can assemble blocks in any order to create custom investment scenarios.

Annual Block

  • • One block per year from 2016 to present
  • 10 blocks per ETF
  • • Synthetic data is used for years without real ETF history
  • • Period: Jan 1 to Dec 31

Special Block

  • • Represents a specific market event window
  • • Dot-com bubble (2000.03 to 2002.10)
  • • Global Financial Crisis (2008.09 to 2009.03)
  • • COVID crash/rebound, high-rate shock

Per-block Metrics

MetricFormula
price_return(last close - first close) / first close × 100
dividend_returntotal dividends in period / first close × 100
total_returnprice_return + dividend_return
total_return_dripresult with dividend reinvestment (see Section 5)
mddmaximum drawdown (see Section 6)
index_price_returnprice return of the underlying index

3. Synthetic Data Generation (Estimated)

Newly listed ETFs such as JEPI (launched in 2020) and JEPQ (launched in 2022) do not have 10 years of live history. For missing periods, we estimate returns using daily returns of the underlying index (SPY/QQQ/IWM) and VIX.

Estimation Logic

1) Price Movement (Upside Capped)
index daily return > 0 (up):
  ETF return = index return × upside_participation

index daily return < 0 (down):
  ETF return = index return × (1 - downside_cushion)

// upside_participation:
//   ATM 100% covered (QYLD/XYLD): 0.55 (55%)
//   ELN-based (JEPI/JEPQ):         0.90 (90%)
//   OTM partial covered (QQQI):    0.75 (75%)

// downside_cushion: cover_ratio × 0.02
2) Dividend Estimate (Monthly, VIX-linked)
monthly dividend = current_price × (base_annual_yield / 12) × (VIX / 20)

// base_annual_yield:
//   ATM 100% covered: 12%/year
//   ELN-based:         8%/year
//   others:           10%/year

// VIX < 20: dividends decrease
// VIX > 20: dividends increase (higher vol -> higher premium)
Estimated blocks are tagged with #estimated. They may differ from actual historical ETF performance. Use them as reference only.

4. Block Simulation Engine

The selected blocks are connected in the user-defined order to simulate a custom investment path.

Simulation Flow

initial portfolio = $100 (normalized)

for each block (in user-selected order):
  1. Set the first trading day price as the base
  2. For each trading day:
     a. Calculate daily price change
     b. Apply change to all holdings:
        shares *= (today_price / yesterday_price)
     c. If dividend exists:
        - DRIP OFF: add to cash (not exposed to market move)
        - DRIP ON:  reinvest into shares immediately
     d. portfolio value = shares + cash
  3. Move to next block (shares/cash state is carried over)

What Block Order Changes vs Does Not Change

OK Changes with Order

  • • Shape of the return curve
  • • MDD (maximum drawdown)
  • • Sharpe / Sortino ratios
  • • Total dividends (DRIP OFF)
  • • Total Return (DRIP OFF)

NO Mostly Order-invariant (with constraints)

  • • Total Return (DRIP ON, for same block set)
  • • Pure price return (Price Return)
  • -> when dividends are reinvested immediately and no cash bucket exists
    daily returns are multiplied, so
    (1+r₁)×(1+r₂) = (1+r₂)×(1+r₁)

5. Dividend Reinvestment (DRIP)

DRIP OFF

Dividends are accumulated as cash.

on dividend payout:
  cash += shares × (dividend / price)

portfolio value:
  value = shares + cash

// cash is not exposed to market moves
// therefore total dividends depend on
// when payouts occur

DRIP ON

Dividends are immediately reinvested into shares.

on dividend payout:
  bonus = shares × (dividend / price)
  shares += bonus  // reinvest

portfolio value:
  value = shares  // no cash

// all assets stay in shares
// by commutative multiplication
// results are order-invariant

6. Risk Metrics

MDD (Maximum Drawdown)

Largest drop from peak to trough. Represents worst loss during the period.

for each day:
  cumulative_max = max(cumulative_max, today_value)
  drawdown = (today_value - cumulative_max) / cumulative_max
  MDD = min(MDD, drawdown)

// ex: peak $150 to $120 -> MDD = -20%

Sharpe Ratio (Risk-adjusted return)

Excess return per unit of risk. Higher is better.

annualized return = mean daily return × 252
annualized volatility = daily std dev × sqrt(252)
risk-free rate = U.S. base rate of the year

Sharpe = (annualized return - risk-free rate) / annualized volatility

// > 1.0: good | > 2.0: excellent | < 0: below risk-free

Sortino Ratio (Downside risk-adjusted return)

Sharpe-like metric using downside deviation only. Upside volatility is not penalized.

downside deviation = std dev of negative daily returns × sqrt(252)

Sortino = (annualized return - risk-free rate) / downside deviation

// often more suitable for covered call ETFs
// because upside moves are structurally capped

Calmar Ratio (Return vs max drawdown)

Annualized return divided by absolute MDD. Measures return against worst downside.

Calmar = annualized return(%) / |MDD(%)|

// ex: annualized return 15%, MDD -10% -> Calmar = 1.5
// > 1.0: decent downside-adjusted return | < 0.5: weak

Yearly Risk-free Rate (U.S. Base Rate)

2016
0.50%
2017
1.25%
2018
2.50%
2019
1.75%
2020
0.25%
2021
0.25%
2022
4.50%
2023
5.50%
2024
5.25%
2025
4.50%

7. Auto Tagging Rules

Block tags are generated automatically from collected data to provide quick market context.

TagCondition
#bear-marketprice return < -15%
#bull-marketprice return > +20%
#sideways-5% <= price return <= +5%
#high-volatilityaverage VIX > 25
#low-volatilityaverage VIX < 15
#estimatedsynthetic data based (no live ETF history)

8. Limitations & Notes

Synthetic data is estimated

It can differ from true historical ETF performance. Special structures such as ELN (JEPI/JEPQ) or 0DTE behavior (QQQI) cannot be fully captured by a simplified index-based model.

Option premiums are approximations

Option microstructure (implied volatility skew, term structure, etc.) is not fully represented by a simple VIX-based model.

Transaction costs are excluded

Real investing includes commissions, slippage, and taxes (e.g., dividend tax), but those costs are not included in this simulator.

NAV vs market price

An ETF market price may deviate from NAV. This simulator uses Yahoo Finance close prices.

Past performance != future returns

Results based on historical data do not guarantee future investment returns. Use as reference only.

CoveredCall Block-Sim v1.0 · 2026.02

Data Source: Yahoo Finance

Covered Call Methodology & Backtest Logic | CovBlock-Sim