← All projects

Personal project, Python and the Alpaca paper trading API

Paper
Trading Bot

A swing trading system I built to test whether a fixed set of rules can be followed without emotion. It buys pullbacks in uptrends, shorts failed rallies in downtrends, sizes every position from the stop distance, and manages exits on its own. It trades simulated money only.

1%Of equity risked per trade
7%Hard stop against the position
+5% / +10%Half off, then the rest
10 daysTime stop if flat

01 Watch it trade

The real rules, running on a simulated market.

The chart below generates a random price series and lets the bot's rules trade it one day at a time. It runs once and then stops, so you can study the whole run and every trade before starting another. Prices are made up, so the result changes on every run, and some runs lose money. The made-up market moves in rising and falling phases that last a couple of months, which is the kind of market this strategy is designed for. In a market with no direction it roughly breaks even. The entries, stops, targets, and position sizes are calculated exactly as the bot calculates them.

Day 0
$100,000Account value
0.0%Return
0Closed trades
n/aWin rate

    Simulated prices for illustration. This is not a record of real or paper trading results, and it is not investment advice.

    03 The rules

    Every decision is written down before the trade.

    When It Enters

    It trades both directions. All five conditions must be true on the same day.

    CheckLongShort
    TrendPrice above the 50-day EMA, 21-day EMA risingPrice below the 50-day EMA, 21-day EMA falling
    SetupDips to the 21-day EMA and closes above itRallies to the 21-day EMA and closes below it
    RSI(14)Between 40 and 60, turning upBetween 40 and 60, turning down
    MACD (12, 26, 9)Histogram risingHistogram falling
    VolumeBelow its 20-day average, so the move against the trend is a quiet one
    MarketS&P 500 above its 50-day EMAS&P 500 below its 50-day EMA

    The market check means it only goes long when the broad market is rising and only shorts when it is falling. The simulation above trades a single made-up stock, so it skips that check.

    How Much It Trades

    Shares = (account value × 1%) ÷ (distance from entry to stop). A wider stop means fewer shares, so every trade risks the same share of the account. Positions are capped at 20% of the account, with at most five open at once.

    When It Exits

    • Stop: 7% against the position, below a long or above a short, set at entry and stored with the trade.
    • First target: close half at 5% in its favor and move the stop to the entry price, so the rest cannot lose.
    • Second target: close the remainder at 10% in its favor.
    • Trailing stop: after the first target, the stop follows 3% behind the best close.
    • Time stop: if a trade is within 1.5% of entry after 10 trading days, close it and free the capital.

    04 How it is built

    Small Python modules, one job each.

    The bot is written in Python and places orders through Alpaca's paper trading API, which fills simulated orders at live market prices. Each part of the system lives in its own file: signal generation, a second-stage data filter, risk and position sizing, portfolio and exit logic, order execution, logging, and performance tracking.

    What a Code Review Changed

    Auditing the first version turned up two bugs that mattered. Exits were recalculating the stop as a flat 2% instead of using the stop the trade was sized on, which closed trades early, and the profit target was fixed at 2%, too small for a swing trade. The fixes were to store each trade's stop at entry and reload it when checking exits, make targets configurable by strategy, add the volume filter, and add a daily loss limit. The rules on this page are the corrected design.

    What I took from it. The hard part of a trading system is not finding signals. It is making sure the risk rules written on paper are the ones the code enforces.