ADVERTISING / NOTEBOOK LESSON

60 · A16 · Reserves, fill rate, and market utility

Sweep reserves on fixed simulated bids and inspect fill, revenue, and bidder utility.

Constructed mechanism / simulationRead-only · saved experiment

Saved outputs come from recorded teaching runs; opening this page does not rerun an experiment. The code and original outputs are preserved; original-language data and annotations may remain.

A16 · Reserves, fill rate, and market utility

Prerequisites: foundations 31–34; A15.

Evidence: explicitly constructed mechanism experiments, not real ad logs. This chapter does not claim industrial-system reproduction or online gains.

Learning order: predict → change one variable → run → explain.

English companion. All instructional Markdown is translated. Experiment code, Chinese language examples, execution counts, and saved outputs remain as in the source edition; historical output text may therefore be Chinese. The initial setup cell anchors the working directory and Python import path for this companion's deeper folder; it does not change the experiment. Saved outputs are historical evidence, not a new run. Run from the top after preparing the required data and models.

PYTHON · 01
# English companions live one directory deeper; keep the original experiment code unchanged.
from pathlib import Path as _TranslationPath
import os as _translation_os
import sys as _translation_sys
_translation_root = next((p for p in [_TranslationPath.cwd(), *_TranslationPath.cwd().parents]
                          if (p / "reclab").is_dir()), None)
if _translation_root is None:
    raise RuntimeError("Open this notebook from inside the Search Recommendation Ads Lab checkout.")
_translation_os.chdir(_translation_root)
if str(_translation_root) not in _translation_sys.path:
    _translation_sys.path.insert(0, str(_translation_root))

Problem and input/output contract

Construct 2,000 auctions, each with three independent U(0,2) values and truthful bids. Use second-price auctions with a uniform reserve: payment=max(reserve, second-highest bid), and no sale if the highest bid is below reserve. Sweep reserves on the same fixed bid matrix. Report revenue per request, fill rate, and winner utility. Unsold requests remain in the revenue denominator.

Before running, predict which result the changed variable will affect and which invariants must hold.

PYTHON · 02
from pathlib import Path
import sys
root=Path.cwd()
if not (root/'reclab').exists(): root=root.parent
if str(root) not in sys.path: sys.path.insert(0,str(root))
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from reclab import ads_curriculum as ac

Run the one-variable comparison

Inputs are small constructed examples visible in source. Output units and constraints are defined above. Run assertions to verify mathematics and accounting.

PYTHON · 03
rows=ac.reserves();display(pd.DataFrame(rows))
plt.plot([r['reserve'] for r in rows],[r['revenue'] for r in rows],marker='o',label='revenue/request');plt.plot([r['reserve'] for r in rows],[r['fill'] for r in rows],marker='o',label='fill');plt.legend();plt.show()
assert rows[-1]['fill']==0
assert all(rows[i]['fill']>=rows[i+1]['fill'] for i in range(len(rows)-1))
Saved notebook output · not executed on this page
reserve fill revenue utility
0 0.0 1.0000 0.990359 0.495017
1 0.5 0.9835 1.011443 0.467694
2 1.0 0.8665 1.052319 0.333432
3 1.5 0.5665 0.875826 0.128916
4 2.0 0.0000 0.000000 0.000000
<Figure size 640x480 with 1 Axes>
Saved notebook figure

Interpretation and limits

An excessive reserve drives fill to zero; revenue and fill need not move together. For regular U(0,2), the theoretical reserve is 1. A finite-sample grid checks only this assumption and cannot set real platform prices. Bidding strategies may also respond to mechanism changes.

Inspect source, then try an exercise

Change only the value distribution to a skewed one, retaining paired random draws. Explain why censored historical losing prices impede directly fitting the full value distribution.

PYTHON · 04
import inspect
print(inspect.getsource(ac.reserves))
Saved notebook output · not executed on this page
def reserves():
    bids=np.random.default_rng(42).uniform(0,2,(2000,3)); order=np.sort(bids,axis=1)
    rows=[]
    for reserve in (0.,.5,1.,1.5,2.):
        win=order[:,-1]>=reserve; pay=np.where(win,np.maximum(reserve,order[:,-2]),0)
        utility=np.where(win,order[:,-1]-pay,0)
        assert np.all(utility>=-1e-12)
        rows.append(dict(reserve=reserve,fill=float(win.mean()),revenue=float(pay.mean()),utility=float(utility.mean())))
    return rows

Sources and next step

A-RTB pp. 150–163. This is an original Lab exercise, not a copy of the complete lecture text.

Chinese GitHub chapter · Authors’ RTB slides. The Chinese deck is not a complete modern advertising-engineering course. Historical descriptions of platforms are not presented as current market facts.

After the exercise, return to the ads learning path and continue to the next semantic unit.

GO TO THE SOURCE

Sources for this lesson

Author tutorialEnglish

Weinan Zhang / Jian Xu · CIKM 2016 RTB Tutorial

PDF pages 150–163: reserve prices

164 author slides covering response prediction, bidding, attribution, pacing, targeting and reserve prices. Lab mechanisms are independently authored, not full paper replications.

Author tutorialEnglish

Weinan Zhang / Jian Xu · CIKM 2016 RTB Tutorial

164-page PDF: unit links open the relevant page

164 author slides covering response prediction, bidding, attribution, pacing, targeting and reserve prices. Lab mechanisms are independently authored, not full paper replications.

Completion marks are optional and stored only in this browser. Reading a page does not mark it complete.