9.6 KiB
9.6 KiB
Auction Valuation Mathematics - Technical Reference
1. Fair Market Value (FMV) - Core Valuation Formula
The baseline valuation is calculated using a weighted comparable sales approach:
FMV = \frac{\sum_{i=1}^{n} \left( P_i \cdot \omega_c \cdot \omega_t \cdot \omega_p \cdot \omega_h \right)}{\sum_{i=1}^{n} \left( \omega_c \cdot \omega_t \cdot \omega_p \cdot \omega_h \right)}
Variables:
P_i= Final hammer price of comparable lot i (€)\omega_c= Condition weight:\exp(-\lambda_c \cdot |C_{target} - C_i|)\omega_t= Time weight:\exp(-\lambda_t \cdot |T_{target} - T_i|)\omega_p= Provenance weight:1 + \delta_p \cdot (P_{target} - P_i)\omega_h= Historical weight:\left( \frac{1}{1 + e^{-kh \cdot (D_i - D_{median})}} \right)
Parameter Definitions:
C \in [0, 10]= Condition score (10 = perfect)T= Manufacturing yearP \in \{0,1\}= Provenance flag (1 = documented history)D_i= Days since comparable sale\lambda_c = 0.693= Condition decay constant (50% weight at 1-point difference)\lambda_t = 0.048= Time decay constant (50% weight at 15-year difference)\delta_p = 0.15= Provenance premium coefficientkh = 0.01= Historical relevance coefficient
2. Condition Adjustment Multiplier
Normalizes prices across condition states:
M_{cond} = \exp\left( \alpha_c \cdot \sqrt{C_{target}} - \beta_c \right)
Variables:
\alpha_c = 0.15= Condition sensitivity parameter\beta_c = 0.40= Baseline condition offsetC_{target}= Target lot condition score
Interpretation:
C = 10(mint):M_{cond} = 1.48(48% premium over poor condition)C = 5(average):M_{cond} = 0.91
3. Time-Based Depreciation Model
For equipment/machinery with measurable lifespan:
V_{age} = V_{new} \cdot \left( 1 - \gamma \cdot \ln\left( 1 + \frac{Y_{current} - Y_{manu}}{Y_{expected}} \right) \right)
Variables:
V_{new}= Original market value (€)\gamma = 0.25= Depreciation aggressivity factorY_{current}= Current yearY_{manu}= Manufacturing yearY_{expected}= Expected useful life span (years)
Example: 10-year-old machinery with 25-year expected life retains 85% of value.
4. Provenance Premium Calculation
\Delta_{prov} = V_{base} \cdot \left( \eta_0 + \eta_1 \cdot \ln(1 + N_{docs}) \right)
Variables:
V_{base}= Base valuation without provenance (€)N_{docs}= Number of verifiable provenance documents\eta_0 = 0.08= Base provenance premium (8%)\eta_1 = 0.035= Marginal document premium coefficient
5. Undervaluation Detection Score
Critical for identifying mispriced opportunities:
U_{score} = \frac{FMV - P_{current}}{FMV} \cdot \sigma_{market} \cdot \left( 1 + \frac{B_{velocity}}{B_{threshold}} \right) \cdot \ln\left( 1 + \frac{W_{watch}}{W_{bid}} \right)
Variables:
P_{current}= Current bid price (€)\sigma_{market} \in [0,1]= Market volatility factor (from indices)B_{velocity}= Bids per hour (bph)B_{threshold} = 10bph = High-velocity thresholdW_{watch}= Watch countW_{bid}= Bid count
Trigger condition: U_{score} > 0.25 (25% undervaluation) with confidence > 0.70
6. Bid Velocity Indicator (Competition Heat)
Measures real-time competitive intensity:
\Lambda_b(t) = \frac{dB}{dt} \cdot \exp\left( -\lambda_{cool} \cdot (t - t_{last}) \right)
Variables:
\frac{dB}{dt}= Bid frequency derivative (bids/minute)\lambda_{cool} = 0.1= Cool-down decay constantt_{last}= Timestamp of last bid (minutes)
Interpretation:
\Lambda_b > 5= Hot lot (bidding war likely)\Lambda_b < 0.5= Cold lot (potential sleeper)
7. Final Price Prediction Model
Composite machine learning-style formula:
\hat{P}_{final} = FMV \cdot \left( 1 + \epsilon_{bid} + \epsilon_{time} + \epsilon_{comp} \right)
Error Components:
-
Bid momentum error:
\epsilon_{bid} = \tanh\left( \phi_1 \cdot \Lambda_b - \phi_2 \cdot \frac{P_{current}}{FMV} \right) -
Time-to-close error:
\epsilon_{time} = \psi \cdot \exp\left( -\frac{t_{close}}{30} \right) -
Competition error:
\epsilon_{comp} = \rho \cdot \ln\left( 1 + \frac{W_{watch}}{50} \right)
Parameters:
\phi_1 = 0.15,\phi_2 = 0.10= Bid momentum coefficients\psi = 0.20= Time pressure coefficient\rho = 0.08= Competition coefficientt_{close}= Minutes until close
Confidence interval:
CI_{95\%} = \hat{P}_{final} \pm 1.96 \cdot \sigma_{residual}
8. Bidding Strategy Recommendation Engine
Optimal max bid and timing:
S_{max} =
\begin{cases}
FMV \cdot (1 - \theta_{agg}) & \text{if } U_{score} > 0.20 \\
FMV \cdot (1 + \theta_{cons}) & \text{if } \Lambda_b > 3 \\
\hat{P}_{final} - \delta_{margin} & \text{otherwise}
\end{cases}
Variables:
\theta_{agg} = 0.10= Aggressive buyer discount target (10% below FMV)\theta_{cons} = 0.05= Conservative buyer overbid tolerance\delta_{margin} = €50= Minimum margin below predicted final
Timing function:
t_{optimal} = t_{close} - \begin{cases}
5 \text{ min} & \text{if } \Lambda_b < 1 \\
30 \text{ sec} & \text{if } \Lambda_b > 5 \\
10 \text{ min} & \text{otherwise}
\end{cases}
Variable Reference Table
| Symbol | Variable | Unit | Data Source |
|---|---|---|---|
P_i |
Comparable sale price | € | bid_history.final |
C |
Condition score | [0,10] | Image analysis + text parsing |
T |
Manufacturing year | Year | Lot description extraction |
W_{watch} |
Number of watchers | Count | Page metadata |
\Lambda_b |
Bid velocity | bids/min | bid_history.timestamp diff |
t_{close} |
Time until close | Minutes | lots.closing_time - NOW() |
\sigma_{market} |
Market volatility | [0,1] | market_indices.price_change_30d |
N_{docs} |
Provenance documents | Count | PDF link analysis |
B_{velocity} |
Bid acceleration | bph² | Second derivative of \Lambda_b |
Backend Implementation (Quarkus Pseudo-Code)
@Inject
MLModelService mlModel;
public Valuation calculateFairMarketValue(Lot lot) {
List<Comparable> comparables = db.findComparables(lot, minSimilarity=0.75, limit=20);
double weightedSum = 0.0;
double weightSum = 0.0;
for (Comparable comp : comparables) {
double wc = Math.exp(-0.693 * Math.abs(lot.getConditionScore() - comp.getConditionScore()));
double wt = Math.exp(-0.048 * Math.abs(lot.getYear() - comp.getYear()));
double wp = 1 + 0.15 * (lot.hasProvenance() ? 1 : 0 - comp.hasProvenance() ? 1 : 0);
double weight = wc * wt * wp;
weightedSum += comp.getFinalPrice() * weight;
weightSum += weight;
}
double fm v = weightSum > 0 ? weightedSum / weightSum : lot.getEstimatedMin();
// Apply condition multiplier
fm v *= Math.exp(0.15 * Math.sqrt(lot.getConditionScore()) - 0.40);
return new Valuation(fm v, calculateConfidence(comparables.size()));
}
public BiddingStrategy getBiddingStrategy(String lotId) {
var lot = db.getLot(lotId);
var bidHistory = db.getBidHistory(lotId);
var watchers = lot.getWatchCount();
// Analyze patterns
boolean isSnipeTarget = watchers > 50 && bidHistory.size() < 5;
boolean hasReserve = lot.getReservePrice() > 0;
double bidVelocity = calculateBidVelocity(bidHistory);
// Strategy recommendation
String strategy = isSnipeTarget ? "SNIPING_DETECTED" :
(hasReserve && lot.getCurrentBid() < lot.getReservePrice() * 0.9) ? "RESERVE_AVOID" :
bidVelocity > 5.0 ? "AGGRESSIVE_COMPETITION" : "STANDARD";
return new BiddingStrategy(
strategy,
calculateRecommendedMax(lot),
isSnipeTarget ? "FINAL_30_SECONDS" : "FINAL_10_MINUTES",
getCompetitionLevel(watchers, bidHistory.size())
);
}
-- Core bidding intelligence
ALTER TABLE lots ADD COLUMN starting_bid DECIMAL(12,2);
ALTER TABLE lots ADD COLUMN estimated_min DECIMAL(12,2);
ALTER TABLE lots ADD COLUMN estimated_max DECIMAL(12,2);
ALTER TABLE lots ADD COLUMN reserve_price DECIMAL(12,2);
ALTER TABLE lots ADD COLUMN watch_count INTEGER DEFAULT 0;
ALTER TABLE lots ADD COLUMN first_bid_time TEXT;
ALTER TABLE lots ADD COLUMN last_bid_time TEXT;
ALTER TABLE lots ADD COLUMN bid_velocity DECIMAL(5,2);
-- Bid history (critical)
CREATE TABLE bid_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
lot_id TEXT REFERENCES lots(lot_id),
bid_amount DECIMAL(12,2) NOT NULL,
bid_time TEXT NOT NULL,
is_winning BOOLEAN DEFAULT FALSE,
is_autobid BOOLEAN DEFAULT FALSE,
bidder_id TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
-- Valuation support
ALTER TABLE lots ADD COLUMN condition_score DECIMAL(3,2);
ALTER TABLE lots ADD COLUMN year_manufactured INTEGER;
ALTER TABLE lots ADD COLUMN provenance TEXT;
CREATE TABLE comparable_sales (
id INTEGER PRIMARY KEY AUTOINCREMENT,
lot_id TEXT REFERENCES lots(lot_id),
comparable_lot_id TEXT,
similarity_score DECIMAL(3,2),
price_difference_percent DECIMAL(5,2)
);
CREATE TABLE market_indices (
category TEXT NOT NULL,
manufacturer TEXT,
avg_price DECIMAL(12,2),
price_change_30d DECIMAL(5,2),
PRIMARY KEY (category, manufacturer)
);
-- Alert system
CREATE TABLE price_alerts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
lot_id TEXT REFERENCES lots(lot_id),
alert_type TEXT CHECK(alert_type IN ('UNDervalued', 'ACCELERATING', 'RESERVE_IN_SIGHT')),
trigger_price DECIMAL(12,2),
is_triggered BOOLEAN DEFAULT FALSE
);