Watchlists & alert hygieneIntermediate#end-of-day#journaling#python#data-quality

Classify your watchlist by trend stage every night

Each evening an agent applies your own numeric rules to label watchlist names by Weinstein stage (1-4) and logs only label changes that persist for your chosen minimum weeks; output goes to your journal after you review a diff.

How it works

  1. Write your stage rules with numeric thresholds, using only computed columns: ma30w (30-week simple moving average of completed weekly closes), ma30w_slope (percent change of that average over the last 4 completed weeks), the last three weekly swing highs and lows (oldest to newest) and the last completed weekly close. Example, tested in this order: Stage 2 = close above ma30w, slope above +0.5 and the three highs rising; Stage 4 = close below ma30w, slope below -0.5 and the three lows falling; Stage 1 = slope between -0.3 and +0.3 after a confirmed Stage 4 or 1; Stage 3 = the same flat slope after a confirmed Stage 2 or 3. Anything else is "unclear".
  2. Keep a weekly price-history CSV for your watchlist (an export from your charting platform or a free source), with at least 30 completed weeks plus the swing lookback for each name.
  3. A Python script computes the columns, reloads the saved state from your log sheet (confirmed_label, pending_label, weeks_pending, last_bar_date) and writes computed_values_csv. Names reach the model only as anonymous row_ids.
  4. The agent applies your written rules to each row and assigns a raw label, or "unclear".
  5. A change only counts once the new label has held for {{min_weeks_in_stage}} completed weeks (2 is a sensible start), and the count only advances when a new weekly bar has closed. The script saves the state for every name, including pending ones, so counts don't restart.
  6. You see an unranked dry-run of confirmed changes only: name, new label, the quoted rule and the values behind it. It is not a focus list. After you confirm, the script, not the model, writes the state table and the change log to your Google Sheet.

Copy-paste prompt

This output is only for your personal process journal. Do not recommend an entry, an exit, a size, or which name to prefer.
Include a ticker or name only as the unranked row key. Do not rank names or present a focus list.
You classify my watchlist into trend stages using only the rules in {{stage_rules_file}}.
Input: {{computed_values_csv}} with columns name, row_id, ma30w, ma30w_slope (in percent), recent_highs (three ordered prices, oldest to newest, not a single number), recent_lows (three ordered prices, oldest to newest, not a single number), close, confirmed_label, pending_label, weeks_pending, last_bar_date.
1. Apply the rules exactly as written. If a row fits no rule or more than one, label it "unclear" and say why.
2. Do not treat an incomplete current week as a new weekly bar.
3. Set raw_label from the rules. If raw_label equals pending_label, set weeks_pending to weeks_pending + 1 only when last_bar_date is later than the date stored at the previous run; if last_bar_date is unchanged, leave pending_label and weeks_pending unchanged. If raw_label differs from pending_label, set pending_label to raw_label and weeks_pending to 1. If weeks_pending >= {{min_weeks_in_stage}} and raw_label differs from confirmed_label, set confirmed_label to raw_label and journal_change to yes; otherwise keep confirmed_label and set journal_change to no. Emit a state row for every name (row_id, name, raw_label, confirmed_label, pending_label, weeks_pending, journal_change). Do not omit pending names. In the review diff, list journal_change rows only, unranked, each with the quoted rule and the values that triggered it. Do not infer a multi-week hold from confirmed_label alone.
4. Do not predict what happens next and do not suggest any action.

Guardrails

  • Publish the rules to yourself and keep a change log.
  • Values come from code; the model only applies written rules.
  • "Unclear" is an allowed answer; forcing a label is not.
  • Writes go only to your own log sheet, and only after you review a dry-run diff and confirm.
  • Require the script to output a deterministic hash or checksum of the rules used so you can verify the exact rule set applied.
  • Manually spot-check at least 20% of classifications against the source data and rules each week; log any discrepancies.
  • The review diff is an unranked private log of confirmed label changes only. Do not add priority, a focus list, or any trade instruction.
  • If the model ranks names or recommends an entry, an exit, a size, or which name to prefer, discard the run.

What can go wrong

Vague rules ("looks like a base") make labels flip back and forth daily. Rules need numeric thresholds, and a short minimum time in a stage before a change counts.

Why it helps

Stage labels give you a quick, consistent read of where each name sits in its cycle, and the unranked change diff is short enough to read in a minute.

Attribution

The four-stage model comes from Stan Weinstein's work, summarised publicly by Thomas Bulkowski (see references). The thresholds you use are your own.

Source and references

Original write-up by Agents for Traders. Background reading is linked below.

Spotted an error, or want your post removed? Email hello@agentsfortraders.com.

Educational content only. Not investment advice or a personal recommendation. No tickers, signals or trade alerts. Trading involves risk of loss.

Conteúdo exclusivamente educativo. Não constitui aconselhamento nem recomendação de investimento. Sem tickers, sinais ou alertas de negociação. Negociar envolve risco de perda.

Related use cases