Day-ahead vs. real-time price spread at the CAISO trading hubs, conditioned on the ISO's own
load, wind, and solar forecast errors. DART = day-ahead LMP − real-time LMP: positive means the
day-ahead market cleared rich (an INC — selling day-ahead, buying back real-time — would have paid);
negative means real-time spiked above day-ahead (a DEC paid). Data: CAISO OASIS, updated daily.
New to DART? Start with one hour
If day-ahead electricity is $50/MWh and real-time is $40/MWh, DART is +$10/MWh. Selling 1 MW day-ahead and buying it back in real time for that hour is an INC; the gross difference is $10 before fees and other charges. A negative spread favors the opposite side, a DEC.
NP15 is Northern California, SP15 Southern California, and ZP26 the zone between them. HE20 means the interval ending at 20:00 Pacific time (19:00–20:00). LMP is the locational marginal price; MAE is mean absolute error. These are historical market diagnostics.
Loading OASIS data caches…
Range
Hub
Daily DART spread
Average of the 24 hourly spreads each trading day at the selected hub. Blue days: day-ahead
cleared above real-time (INCs paid). Red days: real-time ran above day-ahead (DECs paid).
DART fingerprint — hour × day
Each cell is one hour's spread. Vertical red bands are real-time price excursions;
persistent horizontal structure is the systematic hourly bias virtual bids chase.
Inspect one hour
Click a heatmap cell or daily bar, or choose a date and hour. The daily bar opens that day's largest absolute spread.
Select an hour to connect its prices and forecast revisions.
Forecast skill — how much the ISO's view moves between DA and RT
Trailing 7-day mean absolute error and bias. Load: the day-ahead demand
forecast vs. the RTPD (real-time market) forecast for the same hours — the same-definition demand
surprise the RT market trades on (the published "actual integrated load" sits on a different BTM-solar
accounting basis, so it is not compared directly). Wind & solar: DA production forecast
vs. actual generation; midday economic curtailment shows up as persistent positive bias in summer.
Spread conditional on net-load surprise
Hourly observations bucketed by how far real time's view of net load moved from day-ahead's:
(RTPD load fcst − DAM load fcst) − (wind + solar actual − DA forecast). When net load
comes in above the DA view (right side), real time must buy more energy than the DA market cleared —
the spread should go negative. Bars are the mean spread per bucket; the label is the share of hours with
DART > 0.
Hourly profile by error regime
Mean spread by hour-ending, split by days' net-load error sign (±400 MW threshold).
Weather-regime cuts
Days classified from actuals: solar & wind vs. period median, load by peak tercile.
Mean spread in midday (HE11–16) and evening ramp (HE17–21) hours.
Virtual-bidding intel
Left: expected value of a 1 MW INC by hour-ending over the selected range (a negative bar
means the DEC side paid). Right: cumulative P&L of mechanical 1 MW strategies — INC across the
evening ramp, DEC across midday, and a trailing-14-day signal that takes the historically profitable side of
each hour. Gross of fees, bid-cost recovery, and uplift; this is a diagnostic, not advice.
Data table
The long view — system-wide DART since 2020
System DLAP benchmark · independent of the hub/date filters above.
Everything above is the last few months at a single trading hub. This panel is the
six-year backdrop, and it is measured differently: DART at the load aggregation points
(DLAP), weighted PG&E 40% / SCE 40% / SDGE 20% — the spread as the system average load actually
experienced it. It is not affected by the hub and range filters above. The story is convergence: the
day-ahead and real-time markets used to disagree violently and now mostly don't, as batteries absorbed the
evening ramp that used to blow real-time prices past the day-ahead forecast.
Each dot is one day, coloured by the hour-ending in which that day's single largest |DART| landed
— violet and blue are overnight, green and amber the solar middle, orange and magenta the evening ramp.
Switch to Hour of peak spread to put that hour on the vertical axis, where the shift out of the
evening ramp is easiest to read.
Method. Day-ahead prices: OASIS PRC_LMP (DAM, hourly) at TH_NP15_GEN-APND /
TH_SP15_GEN-APND / TH_ZP26_GEN-APND. Real-time prices: PRC_INTVL_LMP (RTM 5-minute dispatch),
averaged to hour-ending — the unweighted hourly mean a 1 MW flat virtual settles against.
Load: SLD_FCST for the CAISO TAC — the DAM forecast is compared against the RTPD
(real-time market) forecast, not against "Total Actual Hourly Integrated Load": every OASIS forecast run
(2DA/DAM/RTPD/RTD) is published net of estimated behind-the-meter solar while the actual-load series is not,
a definitional gap that peaks around 8 GW midday. The DAM−RTPD revision is the same-definition
demand surprise the RT market actually prices. Actual integrated load is still used for the
peak-load regime classification. Wind/solar:
SLD_REN_FCST DAM forecast vs. actual generation summed over trading hubs; actual generation
reflects curtailment, so the solar "error" mixes forecast miss with economic curtailment — read it as
"MW that didn't show up," which is what the real-time market experiences. All dates are Pacific trading
days, hours are hour-ending 1–24. Backtests ignore transaction costs, bid-cost-recovery allocation,
and market impact. Nothing here is investment advice.
Long-history panel. Separate series, separate price definition: DART at the three
DLAPs (DLAP_PGAE-APND, DLAP_SCE-APND, DLAP_SDGE-APND) weighted
40/40/20, from the same PRC_LMP (DAM) and PRC_INTVL_LMP (RTM, averaged to the
hour) reports. Days before June 2026 were seeded from the hourly day-ahead-vs-actual series behind the
duck curve analysis and everything after is fetched from OASIS on the same
definitions; a seven-day overlap check reproduced the seeded values to three decimals, so the seam is
not a break in method. Days with fewer than 20 usable hours are dropped. The colour channel is the
hour-ending containing that day's single largest |DART| — a cyclical scale that closes on itself,
so HE24 and HE1 read as neighbours rather than opposites. Both this series and the hub series above
refresh together in the same daily job.