Skip to main content

Module timing

Module timing 

Source
Expand description

§Timing: should I own this for the long run, and when should I buy it?

SD v2 is good at one thing: telling how big the next move will be (chapter 3). It is not good at calling direction over days or weeks (chapters 2 and 8). A long-term investor needs two different answers, and this module gives both:

  1. Long-term probability of going up (LongModel): the chance the stock closes higher in 126 bars (six months) or 252 bars (one year). Over a year, the market’s upward drift is strong, so this probability is mostly drift, adjusted by trend, momentum, volatility and market weather. sd_timing research measures how much of it is skill.
  2. Short-term entry timing (TimingModel::plan): for a stock you already want, where is it likely to trade lower in the next few weeks, how likely is it to get there, and is waiting worth the risk of missing the fill? This is where SD’s movement forecast pays: a stock whose SD expects a big move has a wider, deeper dip ahead than a calm one, and the limit price should sit further away.

§The entry-timing idea, from zero

Suppose you will buy a stock within the next N trading days, no matter what. You can buy now at today’s close C, or place a limit order at a lower price L that is good for N days. If price trades through L, you pay L. If it never does, you buy at the close on day N, which, because stocks drift up, is usually higher than C.

So the question is a trade-off: a deeper limit saves more when it fills, but fills less often, and every miss costs you the drift. We measure the lowest low over the window in units of the stock’s normal movement:

  z_min = ln(lowest low over days t+1..t+N  ÷  C)  ÷  (σ · √N)

where σ is the 20-bar daily volatility. Across 125 symbols and 25 years, the distribution of z_min depends on where SD’s intensity (the expected-move rank) and squeeze state sit: coiled stocks with a big expected move dip further. LowTable stores that distribution as 101 quantiles per (window, state, intensity decile) bucket. Then:

  • P(fill at L) is the share of history in this bucket whose z_min reached L’s z.
  • The limit for certainty c is the c-quantile of z_min: the deepest price that history reached at least c of the time.
  • The best plan (EntryPlan) searches windows ≤ within and certainties ≥ certainty for the lowest expected effective entry: the average, over history, of “limit price if filled, day-N close if not”. If no plan beats buying now, the answer is “buy now”.

Exit timing is the mirror image (TimingModel::exit_plan): the highest high over the window, z_max, sets sell limits, and the six-month P(up) sets a “hold” or “sell” verdict (TimingConfig). plan_for returns all of it for one stock in one call.

Every table is learned from history and graded on later years it never saw: see docs/13-timing.md and reports/timing_*.txt.

Structs§

EntryPlan
A recommended way to buy one stock.
ExitPlan
A recommended way to sell (or trim) one holding.
LongModel
Long-term P(up) model over crate::direction::GROUPS columns.
LowTable
The distribution of z_min (and what happened next) for one bucket.
TimingAsk
What the person asked for.
TimingConfig
Knobs for plan_for.
TimingModel
Everything the timing indicator needs at run time. Produced by sd_timing research and embedded from timing_model.json.
TimingPlan
Everything SD timing says about one stock today.

Constants§

CERTAINTIES
Certainty grid the planner searches.
FILL_THROUGH
Limit orders are placed this far (0.1%) above the low history reached, so a fill always means price traded through the order: merely touching a price does not guarantee your order was reached in the queue.
LONG_HORIZONS
Long-term horizons (trading days): six months and one year.
STATES
Squeeze states, in bucket order.
WINDOWS
Entry windows (trading days) with learned tables.

Functions§

bucket_of
Bucket index: state × 10 + intensity decile.
limit_z
The limit (in z units) that a share c of history traded through.
long_rows
Direction rows (long-term features) and SD readings for one symbol, the way sd_timing computes them live and in research.
nearest_certainty
Index of the CERTAINTIES grid value nearest c.
plan_for
One call for everything: long-term P(up), entry plan, exit plan and verdict for the last bar of bars. spy and vix are the market’s weather (SPY and ^VIX daily bars; vix may be empty). Needs about 300 bars; ten years gives the monthly SD columns their full say.
sell_z
The sell limit (in z units of the highest high) that a share c of history traded through: P(z_max ≥ z) = c ⇔ the (1 − c)-quantile. Never below 0: a sell limit under today’s close is just selling now.
state_of
Squeeze state of a reading: 0 coiled, 1 fired (live), 2 quiet.
weather
Convenience: build market weather from SPY and VIX bars.