Contract Value Assessment
NBA contracts should be evaluated by comparing player value provided to salary cost. A player providing +5 WAR for $30 million may be a better contract than one providing +3 WAR for $15 million, depending on alternative uses of cap space. Analytics enables systematic contract evaluation.
Dollars Per Win Framework
def evaluate_contract(war, salary, market_rate_per_war=8_000_000):
"""Evaluate contract value using wins framework"""
expected_cost = war * market_rate_per_war
surplus_value = expected_cost - salary
return {
'war': war,
'salary': salary,
'expected_cost': expected_cost,
'surplus_value': surplus_value,
'contract_grade': 'Excellent' if surplus_value > 10_000_000 else
'Good' if surplus_value > 0 else
'Fair' if surplus_value > -5_000_000 else
'Poor'
}
Multi-Year Projections
Contract evaluation requires projecting value across the deal's length. A player who is excellent value in Year 1 may become negative value by Year 4 due to aging and rising salary. Total contract value sums projected value minus cost across all years.
Cap Management Strategy
Salary cap rules create complex optimization problems. Teams must balance current competitiveness with future flexibility, rookie deals with veteran contracts, and player quality with salary efficiency. Analytics informs these decisions through systematic contract valuation and roster simulation.
Implementation in R
# Referee tendency analysis
library(tidyverse)
analyze_referee_tendencies <- function(ref_data) {
ref_data %>%
group_by(referee_id, referee_name) %>%
summarise(
games = n(),
avg_total_fouls = mean(total_fouls),
avg_home_fouls = mean(home_fouls),
avg_away_fouls = mean(away_fouls),
home_foul_bias = mean(away_fouls - home_fouls),
avg_techs = mean(technical_fouls),
avg_flagrants = mean(flagrant_fouls),
avg_pace = mean(pace),
home_win_pct = mean(home_win),
.groups = "drop"
)
}
ref_games <- read_csv("referee_game_data.csv")
ref_analysis <- analyze_referee_tendencies(ref_games)
# Refs with home bias
home_bias <- ref_analysis %>%
filter(games >= 50) %>%
arrange(desc(home_foul_bias)) %>%
select(referee_name, games, home_foul_bias, home_win_pct)
print(home_bias)
Implementation in R
# Referee tendency analysis
library(tidyverse)
analyze_referee_tendencies <- function(ref_data) {
ref_data %>%
group_by(referee_id, referee_name) %>%
summarise(
games = n(),
avg_total_fouls = mean(total_fouls),
avg_home_fouls = mean(home_fouls),
avg_away_fouls = mean(away_fouls),
home_foul_bias = mean(away_fouls - home_fouls),
avg_techs = mean(technical_fouls),
avg_flagrants = mean(flagrant_fouls),
avg_pace = mean(pace),
home_win_pct = mean(home_win),
.groups = "drop"
)
}
ref_games <- read_csv("referee_game_data.csv")
ref_analysis <- analyze_referee_tendencies(ref_games)
# Refs with home bias
home_bias <- ref_analysis %>%
filter(games >= 50) %>%
arrange(desc(home_foul_bias)) %>%
select(referee_name, games, home_foul_bias, home_win_pct)
print(home_bias)