Strategy & Systems Memo · Paper-Trading Implementation

Occurrence-Filtered Momentum Reversal

A systematic pipeline that waits for the market to repeat itself, then waits again for that repetition to overcorrect — entering only where sustained attention and short-term exhaustion coincide, and exiting on a single self-adjusting order with no standing human decision in the loop.

Scope Signal screening → entry sizing → exit management Venue Simulated brokerage account (paper trading) Cadence 15-minute cycle, market hours only
Abstract

The strategy treats "a ticker keeps showing up" and "a ticker is short-term oversold" as two independent, weak signals that are unreliable alone but meaningfully stronger in conjunction. A rolling occurrence count identifies names the broader detection layer has flagged repeatedly over a lookback window; only that shortlist is then tested against a 14-period RSI oversold threshold. Positions that clear both filters are opened at a risk-scaled size and immediately handed a single trailing order that functions as both stop-loss and take-profit, so the position closes itself. Every threshold is externally configurable and takes effect without a code deployment.

§1

The Two-Factor Thesis

Persistence answers "is the market still paying attention to this name?" Oversold answers "has that attention pushed price past a short-term extreme?" Neither question is worth trading alone — the first is fired by names in the middle of a healthy uptrend as often as a breakdown; the second is fired by names in free-fall as often as a pause. The strategy only acts where both are true at once.

This is implemented as two sequential filters rather than one composite score, deliberately — each stage is independently inspectable, independently tunable, and independently disableable. A name can be rejected at the persistence stage without ever touching brokerage rate limits or price history, and the oversold threshold can be re-tuned without touching how persistence is counted.

§2

Pipeline Stages

Five stages, run in strict order every cycle. Each stage either narrows the candidate set or acts on what survived.

01Detect

Signal Detection

An independent scanning layer continuously evaluates a broad equity universe for breakout-style price action and writes a timestamped event — ticker, signal type, and price context — to a time-indexed signal store on every trigger. This stage runs on its own schedule, upstream of and decoupled from everything below it.

02Persist

Occurrence / Persistence Screen

On every 15-minute cycle, the signal store is scanned for the trailing Days Back window and grouped by ticker, counting distinct calendar days a ticker appears on — not raw event count, so a name firing three different signal types on one day still counts once. A ticker must clear a minimum Occurrence threshold of distinct days to advance.

03Confirm

Oversold Confirmation

Every ticker that survives Stage 2 gets a fresh daily-close price series pulled from the connected brokerage's market data endpoint, and a 14-period RSI is computed against it. Only names reading below the configured RSI threshold become entry candidates — persistence alone is never sufficient.

04Size & Enter

Position Sizing & Entry

Each candidate passes three guards before an order is placed: no existing open position in that ticker, sufficient buying power for the sized quantity, and a live account-equity read to size against. A market order is submitted for the computed quantity, day-valid, and the fill is confirmed before the exit order is attached.

05Protect

Exit Management

A single trailing-stop sell order is attached on fill, sized to the filled quantity. Every cycle also re-checks all open positions — not just ones opened this run — and attaches a covering order to any position missing one, so a position can never silently sit unprotected.

§3

Position Sizing

Size is expressed as a percentage of total account equity, not a fixed dollar amount or share count, so the position scales with the account automatically. The rounding rule below exists to keep every trade at exactly one share when the target is fractional, and to never round a position past its equity target — it only ever rounds down from an over-shoot, never up into one.

# Equity — the configured position-sizing percent (default 10) target = account_equity × (Equity / 100) raw_qty = round(target / price) if raw_qty == 0: qty = 1 # never a zero-share order elif raw_qty × price > target: qty = raw_qty - 1 # rounding up overshot the target else: qty = raw_qty qty = max(qty, 1) # floor of one share, even if it exceeds the target reject trade if qty × price > buying_power

The final line is a hard gate, not a resize — if even one share can't be covered by current buying power, the candidate is skipped entirely rather than entered at a smaller size than the strategy intended.

§4

Exit Mechanics

The exit uses one order type doing two jobs at once. A trailing-stop sell order tracks the highest price reached since it was placed and holds a sell trigger a fixed percentage below that high-water mark. Before the position has moved, that trigger sits below the entry price and behaves exactly like a conventional stop-loss. Once the position runs, the trigger rises with it and behaves exactly like a trailing take-profit — the same order, the same percentage, no state to hand off between "protecting capital" and "protecting gains."

entry time → price trailing stop acts as stop-loss — trigger below entry acts as trailing take-profit — trigger rises with the high
Figure 1. One order, two regimes. The trailing-stop trigger (teal) never moves down — before the position gains, it sits at a fixed offset below entry like a stop-loss; once price makes a new high, it ratchets up and behaves like a take-profit that locks in gains without capping the upside.
§5

Configuration Surface

Every threshold below lives in one externally editable object, not in code. Changing a value takes effect on the strategy's next 15-minute cycle — no redeploy, no restart.

ParameterGovernsDefault
DaysBack Lookback window, in calendar days, for the persistence screen (§2, Stage 02) 45
Occurrence Minimum distinct days a ticker must appear in that window to advance 3
RSI Oversold ceiling — candidates must read below this to qualify (§2, Stage 03) 29.9
Equity Position size as a percent of total account equity (§3) 10%
Trailing Trailing-stop offset from the high-water mark (§4) 5%
§6

System Architecture

Serverless throughout — nothing runs unless a scan is due or a status page is being read. Component names below are described generically; roles map directly onto managed AWS primitives.

Event Scheduler cron · market hours triggers /15min Execution Function screen · size · order (compute, on-demand) Signal Event Table NoSQL · ticker + time reads Configuration Object object storage · hand-editable reads Connected Brokerage account · positions · orders (paper account, isolated keys) checks + places orders Last-Run Record object storage writes read-only path — independent of the execution cycle above Status Function aggregates & serves (compute, on-demand) reads reads reads account state Authenticated Endpoint REST API · token-gated serves Dashboard
Figure 2. Two independent paths share the same account state. The upper path is the trading cycle: a scheduler fires the execution function every 15 minutes of market hours, which reads signals and configuration, acts against the brokerage, and leaves a record of what it did. The lower path is purely observational — a separate function assembles that same state for a dashboard on request and never writes anywhere.

Component roles

Compute
Execution Function — runs the full screen-size-order cycle on a fixed schedule; stateless between invocations, all state lives in the signal table, configuration object, and brokerage account.
Compute
Status Function — read-only aggregator behind the authenticated endpoint; touches nothing the execution function writes to and cannot place or modify an order.
Scheduling
Managed event scheduler — cron-style trigger restricted to a market-hours window, so the cycle never runs while the venue is closed.
NoSQL storage
Signal Event Table — append-only, time-indexed by ticker; the persistence screen (§2) is a grouped read over this table, nothing more.
Object storage
Configuration object & last-run record — small JSON documents, hand-editable in place; the strategy's tunable surface and its own audit trail live here, not in source control.
API layer
Authenticated REST endpoint — the only externally reachable surface; gated by a shared token, fronting the status function alone.
External
Connected brokerage — a dedicated paper-trading account with its own isolated credentials, kept separate from any other trading account the broader system operates.
§7

Operating Safeguards

The strategy ships with an explicit enable flag, defaulting off — deploying the pipeline and turning on trading are two separate, deliberate acts. It trades exclusively against a paper account whose credentials are provisioned separately from every other automated process in the broader system, so a credential or logic fault here cannot reach a different account. The market-hours-only schedule means a configuration mistake is bounded to the next open session, never compounding overnight or over a weekend. And because the exit reconciliation pass (§2, Stage 05) runs unconditionally every cycle, a position can end up under-protected only for the length of one 15-minute gap — never indefinitely.

Strategy & systems memo — internal reference v1.0