Project 01  ·  Independent project

Autonomous Market
Monitoring System

An independent market-monitoring project with an interactive strategy simulator using synthetic market data.

Status
Demo
Equities watched
10
Tick frequency
1 hr
Simulation data
Synthetic

A market-monitoring architecture.

This independent project explores a decision loop: ingest market data, evaluate signals, manage state, apply risk rules, and observe outcomes.

The architecture describes an Alpaca paper-trading integration with a signal engine, risk layer, state store, and monitoring dashboard. The public page demonstrates a simplified strategy simulator; current operation of the separate trading service is not verified here.

Simulation results depend on generated prices and parameters. They are not historical returns or evidence of current trading performance.

01
Data ingestion
Alpaca Markets API pulls hourly OHLCV bars for all 10 symbols. 60-bar rolling window. IEX feed.
02
Signal engine
RSI(14), SMA crossover (9/21), 50-bar trend filter, MACD histogram. Requires confluence — no single-indicator trades.
03
Risk layer
Hard stop-loss at 3%. Trailing stop at 3.5%. Daily loss circuit breaker at 5% of portfolio. Position size capped at 10%.
04
Execution
Market orders via Alpaca. Paper trading mode. Paper-trading integration design.
05
State management
Thread-safe state store tracks positions, peak prices, bars held, cooldown periods, and trade history.
06
Dashboard
Flask API + vanilla JS frontend. Auto-refreshes every 30s. Stop/Start bot controls. Accessible on local network.

How the bot decides.

Every hourly tick runs each symbol through the same decision tree. The strategy requires multiple conditions to align — it doesn't trade noise.

01
Trend filter

Price must be above the 50-bar SMA. No buys in downtrending stocks. This filter restricts entries to prices above the selected trend average.

Required
02
RSI dip entry

RSI(14) below 40 signals a short-term oversold condition within an uptrend. Buying weakness, not strength.

OR
03
MA crossover + MACD confirmation

9-bar SMA crossing above 21-bar SMA, confirmed by positive MACD histogram. Momentum-based entry requiring two signals to agree.

OR
04
Exit: trailing stop

Once in a position, peak price is tracked. A 3.5% drop from peak triggers exit. Locks in gains on winners, limits losses on losers.

Exit
05
Exit: signal deterioration

RSI overbought above 65, MA cross down, or MACD turning negative triggers a sell after minimum hold period of 3 bars.

Exit

Run the strategy yourself.

Adjust the parameters and see how strategy behavior changes. The illustrative simulation runs in your browser against generated synthetic prices. It does not place orders, connect to a live account, or reproduce a historical backtest.

Strategy simulator — synthetic data Synthetic data · illustrative results
40
3.5%
3
10%
2
Total return
—
Total trades
—
Win rate
—
Max drawdown
—

The guardrails.

Every autonomous system that touches money needs hard limits that can't be reasoned around. The design below describes risk controls for a paper-trading system. The browser simulator illustrates stop-loss, trailing-stop, and position-sizing behavior; it does not implement every control shown here.

Hard stop-loss
3.0%

Maximum loss per position before forced exit. No exceptions, no overrides.

Trailing stop
3.5%

Tracks peak price from entry. Locks in gains as the position moves in your favor.

Daily loss limit
5.0%

Circuit breaker. If realized losses hit 5% of portfolio value, no new trades fire for the rest of the day.

Max position size
10%

No single position exceeds 10% of available cash. Enforced at order placement.

The point is the deployment.

The project brings together data ingestion, rule-based decisions, risk controls, and an interactive interface. It is separate from my employer and client work.

One useful architectural comparison is: ingest data, evaluate against rules, manage state, execute actions, observe outputs. The domain is financial markets. The same broad pattern can inform other automated workflows.

# The core decision loop — runs every hour the market is open

def get_signal(df, bars_held, bars_since_exit, in_position):
  # Enforce minimum hold — prevents panic selling
  if in_position and bars_held < MIN_HOLD_BARS:
    return "hold"

  # Trend filter — no buys in downtrends
  if not in_uptrend:
    return "hold"

  # Cooldown after stop-loss — prevents revenge trading
  if bars_since_exit < COOLDOWN_BARS:
    return "hold"

  # Entry: RSI dip OR MA crossover with MACD confirmation
  if rsi < RSI_OVERSOLD or (ma_cross_up and macd_bullish):
    return "buy"

  return "hold"