Staking Rewards Tracker
Track staking rewards across multiple proof-of-stake blockchain protocols including staking APR changes over time, reward compounding frequency effects, and validator node performance metrics to optimize staking capital allocation and report aggregate passive income generation.
Staking Rewards Tracker — Crypto-Native
What This Notebook Does
A staking rewards tracker records and analyses cumulative staking income over time, accounting for:
- Daily/epoch reward amounts
- ETH/token price at time of receipt (USD value)
- Auto-compounding effects
- Tax cost basis (income recognized at receipt price)
This notebook:
- Simulates or fetches daily staking reward events
- Tracks cumulative ETH balance and USD value over time
- Computes effective APR realized (vs theoretical)
- Calculates tax cost basis for staking income
- Models compounding vs non-compounding scenarios
- Exports a complete rewards ledger
!pip install numpy pandas matplotlib seaborn --quietimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
plt.rcParams['figure.figsize'] = (14, 5)
plt.rcParams['axes.spines.top'] = False
plt.rcParams['axes.spines.right'] = False
print('Imports ready.')Imports ready.
Configuration
This section sets up the fundamental parameters that govern the staking rewards simulation. Key variables such as the INITIAL_ETH staked, the ANNUAL_APR_PCT (Annual Percentage Rate), the SIMULATION_DAYS, and the START_DATE are defined here. These configurations are critical as they establish the context and constraints for all subsequent calculations and analyses within the notebook.
INITIAL_ETH = 32.0 # one validator
ANNUAL_APR_PCT = 4.2 # approximate Ethereum consensus APR
SIMULATION_DAYS = 730 # 2 years
START_DATE = '2023-01-01'
print('Config ready.')Config ready.
Reward Simulation
This section implements the core logic for simulating daily staking rewards. It includes a function that models the daily accumulation of ETH, considering factors such as fluctuating ETH prices, slight variations in daily APR, and the powerful effect of compounding. The output is a detailed DataFrame (df) that serves as a daily ledger of rewards, providing the foundational data for all further analysis and visualization. This simulation is crucial for understanding how staking rewards accrue over time under various market conditions.
def simulate_staking_rewards(initial_eth: float, annual_apr: float,
n_days: int, start_date: str,
seed: int = 42) -> pd.DataFrame:
"""
Simulate daily staking rewards for an Ethereum validator.
Parameters
----------
initial_eth : float Starting ETH staked.
annual_apr : float Annual APR in percent.
n_days : int Number of days to simulate.
start_date : str Simulation start date.
seed : int Random seed for price simulation.
Returns
-------
pd.DataFrame Daily rewards ledger.
"""
rng = np.random.default_rng(seed)
idx = pd.date_range(start_date, periods=n_days, freq='D')
# ETH price: starts at 1500, trends up with noise
eth_price = 1_500 + np.cumsum(rng.normal(3, 40, n_days))
eth_price = np.maximum(eth_price, 800.0)
# Daily APR varies slightly (MEV, base rewards, etc.)
daily_base = annual_apr / 100 / 365
daily_apr = np.maximum(daily_base + rng.normal(0, daily_base * 0.1, n_days), 0)
# Compound: stake earns stake
eth_balance = [initial_eth]
eth_rewards_day = []
for d in daily_apr:
reward = eth_balance[-1] * d
eth_rewards_day.append(reward)
eth_balance.append(eth_balance[-1] + reward)
eth_balance = eth_balance[1:]
df = pd.DataFrame({
'eth_price': eth_price,
'eth_balance': eth_balance,
'daily_reward_eth': eth_rewards_day,
'daily_apr': daily_apr * 365 * 100, # annualised %
}, index=idx)
df['daily_reward_usd'] = df['daily_reward_eth'] * df['eth_price']
df['cumulative_reward_eth'] = df['daily_reward_eth'].cumsum()
df['cumulative_reward_usd'] = df['daily_reward_usd'].cumsum()
df['portfolio_usd'] = df['eth_balance'] * df['eth_price']
df['cost_basis_usd'] = df['daily_reward_usd'].cumsum() # income at receipt price
return df
df = simulate_staking_rewards(INITIAL_ETH, ANNUAL_APR_PCT, SIMULATION_DAYS, START_DATE)
total_eth_rewards = df['cumulative_reward_eth'].iloc[-1]
total_usd_income = df['cumulative_reward_usd'].iloc[-1]
effective_apr = (df['eth_balance'].iloc[-1] / INITIAL_ETH - 1) / (SIMULATION_DAYS / 365) * 100
print(f'Initial stake : {INITIAL_ETH:.1f} ETH')
print(f'Final balance : {df["eth_balance"].iloc[-1]:.4f} ETH')
print(f'ETH earned : {total_eth_rewards:.4f} ETH')
print(f'USD income : ${total_usd_income:,.0f}')
print(f'Effective APR : {effective_apr:.2f}%')Initial stake : 32.0 ETH Final balance : 34.8086 ETH ETH earned : 2.8086 ETH USD income : $6,352 Effective APR : 4.39%
Compound vs No-Compound Comparison
This section delves into the impact of compounding on staking rewards by comparing two scenarios: one where rewards are automatically reinvested (compounding) and another where they are not (non-compounding). By calculating the compound_benefit, this comparison quantifies the additional ETH earned due to compounding. This analysis is important for understanding the long-term growth potential of staking and making informed decisions about reward management strategies.
# Non-compounding: rewards withdrawn daily, only initial stake earns
daily_rate = ANNUAL_APR_PCT / 100 / 365
df['no_compound_daily_reward_eth'] = INITIAL_ETH * daily_rate
df['no_compound_cumulative_eth'] = df['no_compound_daily_reward_eth'].cumsum()
compound_gain = df['cumulative_reward_eth'].iloc[-1]
no_compound_gain = df['no_compound_cumulative_eth'].iloc[-1]
compound_benefit = compound_gain - no_compound_gain
print(f'Compounding extra benefit: {compound_benefit:.4f} ETH ({compound_benefit/no_compound_gain*100:.2f}% more)')Compounding extra benefit: 0.1206 ETH (4.49% more)
Visualization
This section is dedicated to visualizing the simulated staking rewards data. It generates several plots to illustrate key metrics, including:
- Cumulative ETH Rewards: Showing the growth of staked ETH with and without compounding.
- Daily USD Rewards: Highlighting the daily income generated in USD.
- Portfolio Value vs. Tax Cost Basis: Tracking the overall USD value of the staked assets against the accumulated tax cost basis of earned rewards.
These visualizations are essential for gaining intuitive insights into the distribution, trends, and financial implications of the staking strategy over the simulation period.
fig, axes = plt.subplots(3, 1, figsize=(14, 12), sharex=True)
fig.suptitle('Staking Rewards Tracker — 32 ETH Validator', fontsize=14, fontweight='bold')
ax1 = axes[0]
ax1.plot(df.index, df['cumulative_reward_eth'], color='#1976d2', lw=2, label='With compounding')
ax1.plot(df.index, df['no_compound_cumulative_eth'], color='#bdbdbd', lw=1.5, ls='--', label='Without compounding')
ax1.set_ylabel('Cumulative ETH Earned')
ax1.legend(); ax1.set_title('Cumulative ETH Rewards')
ax2 = axes[1]
ax2.bar(df.index, df['daily_reward_usd'], color='#43a047', width=1, alpha=0.7)
ax2.plot(df.index, df['daily_reward_usd'].rolling(30).mean(), color='#1b5e20', lw=1.5, label='30d MA')
ax2.set_ylabel('Daily Reward (USD)')
ax2.legend(); ax2.set_title('Daily USD Rewards')
ax3 = axes[2]
ax3.plot(df.index, df['portfolio_usd'] / 1000, color='#7b1fa2', lw=1.5, label='Portfolio Value')
ax3.plot(df.index, df['cost_basis_usd'] / 1000, color='#e65100', lw=1.5, ls='--', label='Cost Basis (Tax)')
ax3.set_ylabel('Value (K USD)')
ax3.legend(); ax3.set_title('Portfolio Value vs Tax Cost Basis')
plt.tight_layout()
plt.show()Export
This final section handles the export of the comprehensive staking rewards ledger. The df DataFrame, which contains all the simulated daily metrics, is saved to a CSV file. This functionality is vital for external record-keeping, further analysis in other tools, or integration with personal finance and tax software.
df.to_csv('staking_rewards_tracker.csv')
print('Saved: staking_rewards_tracker.csv')Saved: staking_rewards_tracker.csv
Conclusion
This notebook provides a comprehensive framework for tracking and analyzing Ethereum staking rewards. Through a detailed simulation, we've demonstrated how to:
- Simulate Daily Rewards: Account for fluctuating ETH prices, minor daily APR variations, and the crucial effect of compounding.
- Quantify Compounding Benefits: Clearly illustrate the significant advantage of reinvesting rewards over a non-compounding approach.
- Calculate Financial Metrics: Track cumulative ETH balance, USD value, and the effective APR achieved.
- Determine Tax Cost Basis: Establish the income recognized at the time of receipt for tax purposes.
- Visualize Key Trends: Provide intuitive plots showing cumulative ETH rewards, daily USD income, and the critical comparison between portfolio value and tax cost basis.
By exporting the daily rewards ledger to a CSV file, this notebook offers a practical tool for personal financial management, tax reporting, and deeper analytical exploration of staking performance. The insights gained can help stakers make informed decisions about their reward management strategies and understand the true financial implications of their participation in network validation.