Quant Trading for Programmers 01: Why Programmers Are Well Suited To Quant Trading
· 41 min read · Views --
Last updated on

Quant Trading for Programmers 01: Why Programmers Are Well Suited To Quant Trading

Author: Alex Xiang


Quant Trading for Programmers 01: Why Programmers Are Well Suited To Quant Trading

The previous article was the column roadmap. It explained that this series will move forward through a real project instead of locking itself into a rigid table of contents. From this article on, we stop talking only about direction and start running the project.

First, the boundary: this series only covers research, backtesting, paper simulation, and notifications. It does not connect to brokerages, does not submit real trading orders, and is not investment advice. Quant trading is often presented as “finding a magic formula”, but I prefer to see it from an engineering perspective: break a trading idea into data, rules, validation, risk control, and review, then run it the same way every day.

That is familiar work for programmers.

Cover image for article 1 in Quant Trading for Programmers

Quant Trading Is Not A Money Button

When people first hear “quant trading”, two extreme images often appear.

One is Wall Street machine rooms, ultra-low latency, PhDs in mathematics, and complex models. The other is a short-video version with two moving averages and a slogan that says “buy the golden cross and sell the death cross”, as if following it mechanically will make money.

Neither image fits this series.

We are doing something more modest: use programs to express a trading idea completely, then check what happened in historical data and what happens in paper trading. This process does not guarantee profit, but it turns “I feel it will rise” into a system that can be questioned, verified, and reviewed.

In engineering terms, quant trading includes at least these objects:

  • Data: stock basics, prices, financial reports, trading calendars, volume, suspension status.
  • Rules: when a stock enters the watch pool, when it leaves, and what the position cap is.
  • Backtesting: place rules back on the historical timeline and simulate positions, cash, return, and drawdown day by day.
  • Risk control: limit single-stock weight, max holdings, trading cost, liquidity, and abnormal prices.
  • Paper trading: submit no real orders, but record paper orders, net value, reviews, and alerts.

Once the problem is decomposed this way, programmers enter familiar territory. We do not need to pretend to be fund managers first, and we do not need to memorize a whole finance textbook first. We can start by defining inputs and outputs, writing boundary conditions into tests, and saving run results.

Where Programmers Have An Advantage

The programmer’s advantage in quant trading is not “I can code, so I must be smarter”. The advantage mainly comes from four habits.

First, programmers are used to turning vague requirements into explicit interfaces.

“The trend is upward” cannot run. “The close price is above the 20-day moving average, and the 20-day moving average is above the 60-day moving average” can run. “Risk is too high” cannot be tested. “Single-stock weight cannot exceed 10% of total equity, and the portfolio can hold at most 10 stocks” can be tested.

Second, programmers are used to recording evidence.

If a strategy produces BUY_WATCH today, it should not only say “the model thinks it is good”. It should explain the recent 20-day momentum, financial-quality score, volume abnormality, risk-control status, and data source. A signal without evidence cannot be reviewed later.

Third, programmers know systems will break.

Data sources fail, APIs change, database migrations are missed, scheduled jobs run twice, configs get deleted, and time ranges are passed incorrectly. A quant platform is not a notebook cell that runs once and disappears. It needs health checks, logs, audits, retries, and permission controls.

Fourth, programmers naturally respect versioning.

Were strategy parameters changed? Which rule version was used in the backtest? Which date’s stock universe was used? Was financial-report latency respected? If none of these are recorded, a beautiful equity curve may only be an unreproducible illusion.

That is why this series names the project ZiQuant and treats it as a long-term project from day one, not a few scattered scripts.

Quant Trading Versus Discretionary Trading

Discretionary trading is not inferior. Many strong investors make decisions through industry knowledge, business judgment, financial-statement reading, and trading experience. These abilities are hard to replace with simple code.

The difference is that quant trading asks decision rules to be as explicit as possible.

A discretionary judgment may be written like this:

This stock has decent fundamentals, recent price action is acceptable, and valuation is not too expensive. We can watch it first.

A quant system needs to split it into harder conditions:

def generate_signal(stock, factors, risk):
    if risk.is_suspended or risk.is_st:
        return "RISK_WATCH"

    quality_ok = factors.roe_percentile >= 0.70 and factors.margin_percentile >= 0.60
    momentum_ok = factors.momentum_60d_percentile >= 0.65
    volatility_ok = factors.volatility_20d_percentile <= 0.80

    if quality_ok and momentum_ok and volatility_ok:
        return "BUY_WATCH"
    if quality_ok and not momentum_ok:
        return "HOLD_WATCH"
    return "OBSERVE"

This code is still rough, but it has one important advantage: other people can ask why, modify it, test it, and roll it back.

Discretionary trading is more like expert judgment in a complex environment. Quant trading is more like turning part of that judgment into repeatable experiments. They are not absolute opposites. A useful platform often lets programs organize candidates, risks, and evidence first, then lets humans make the final judgment.

That is why later signals will be named BUY_WATCH, HOLD_WATCH, and RISK_WATCH, not simply BUY and SELL. The system gives research and observation suggestions, not automatic trading commands.

Why Start With Paper Trading

Programmers easily fall into one trap: once a system can run, they want to connect it to real services.

In quant trading, this impulse is especially dangerous. A strategy that has not gone through sufficient backtesting, out-of-sample validation, paper observation, and human review should not connect to a real brokerage account.

Paper trading is not pretending that we already made money. It checks three types of problems.

The first type is engineering problems: whether signals are generated consistently every day, whether data refreshes on time, whether jobs run twice, and whether order quantities satisfy rules.

The second type is strategy problems: whether post-buy performance matches expectations, whether losses concentrate in certain market conditions, whether turnover is too high, and whether max drawdown is acceptable.

The third type is behavioral problems: when the system loses money continuously, can people still review by rule instead of changing parameters temporarily and chasing prices?

ZiQuant’s current project boundary is also written in the README: the platform only does quant research, backtesting, alerts, and paper trading. It will not submit orders to real brokerage accounts.

That limit is not timidity. It is engineering discipline.

A-Share Rules Change Code

If we only read textbooks or overseas examples, it is easy to write a backtest that looks correct but is unrealistic for A-shares.

Several A-share rules directly affect program design.

These rules are not details to add at the end. They should enter the data model and tests from the start.

For example, board lots of 100 shares affect order quantity:

def normalize_a_share_lot(shares: int) -> int:
    """Common A-share buy orders are rounded down to board lots of 100 shares."""
    if shares <= 0:
        return 0
    return shares // 100 * 100


assert normalize_a_share_lot(99) == 0
assert normalize_a_share_lot(100) == 100
assert normalize_a_share_lot(258) == 200

Trading costs must also enter the model early:

def estimate_a_share_fee(amount: float, side: str) -> float:
    commission = max(amount * 0.0003, 5.0)
    transfer_fee = amount * 0.00001
    stamp_tax = amount * 0.0005 if side == "sell" else 0.0
    return round(commission + transfer_fee + stamp_tax, 2)


buy_fee = estimate_a_share_fee(20_000, "buy")
sell_fee = estimate_a_share_fee(20_000, "sell")
print(buy_fee, sell_fee)

Later, when we write the backtest engine, we will add limit-up and limit-down non-execution, volume participation, slippage, simplified T+1 handling, and paper-order rejection reasons. For now, remember this: market rules become code constraints, not background text in an article.

Runnable Foundation Check

The first article’s code check should not be strategy return. It should confirm that project boundaries already exist in the repository. The current project uses this command to reproduce the foundation capabilities from articles 01-08:

uv run python -m scripts.chapter_examples foundation-check

The output for this chapter is:

Project-scope foundation-check output

This output confirms three things: the project boundary is research, backtesting, paper trading, and alerts; it does not submit real brokerage orders; and the current ORM already has 22 model tables. Article 1 is not trying to prove a strategy can make money. It is proving that the project is not a bundle of one-off scripts from day one.

What This Series Will Build

The project running through this series is zi-quant-platform. It is not an empty shell created only for articles. It is a runnable FastAPI + PostgreSQL project.

Current startup:

cd ~/projects/zi-quant-platform
uv sync --extra dev
uv run uvicorn app.main:app --host 127.0.0.1 --port 8092

Health check:

curl http://127.0.0.1:8092/health

Run tests:

uv run pytest

Project tag for this chapter:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-01
uv sync --extra dev
uv run pytest

Later articles will continue along this project: stock universe, real market data, financial reports, factors, strategies, backtesting, paper trading, Lark alerts, DeepSeek-assisted strategy optimization, and production acceptance. Each article should make the project more complete than the previous one, while keeping it runnable.

Article 1 does not ask readers to finish all modules. We only do one thing: confirm that we are not writing disposable scripts, but building a long-term engineering project.

Hands-On Task: Create The Project README

If you start from scratch, first create a minimal project directory:

mkdir -p zi-quant-platform
cd zi-quant-platform
git init

Then write the first README.md:

# ZiQuant Platform

An A-share quant trading practice platform for programmers.

## Boundary

- Research, backtesting, alerts, and paper trading only.
- No brokerage connection.
- No real trading orders.
- Not investment advice.

## First-stage Goals

- Build the Python project skeleton.
- Design stock-universe and market-data structures.
- Implement A-share trading-rule checks.
- Run the first testable strategy experiment.

If you follow my repository directly, the first step is to confirm that the project can install, start, and run tests. Later articles will explain why each directory exists, why each table is designed this way, and which business action each API maps to.

This README looks simple, but it writes down the boundary. Quant systems are most dangerous when boundaries blur: a research system quietly becomes automatic trading, paper trading quietly becomes a real account, and strategy explanations quietly become investment advice. Writing the boundary on day one removes many later risks.

Common Pitfalls

The first pitfall is looking for a “magic strategy” immediately.

Strategies matter, but without stable data, trading constraints, backtest records, and risk control, more complex strategies become more dangerous. This series builds the foundation before building strategy.

The second pitfall is treating backtest return as real return.

Backtesting is a validation tool, not an ATM. If data contains look-ahead bias, trading cost is missing, suspensions and limit-up/limit-down are ignored, or the stock universe has survivorship bias, the equity curve may look good and still be useless.

The third pitfall is treating the LLM as a trader.

Later we will integrate DeepSeek, but its role is to read reports, explain strategies, propose candidate parameters, and generate research suggestions. It cannot decide trades directly, and it cannot bypass backtesting or human review.

The fourth pitfall is ignoring runtime state.

A quant platform deals with time, data sources, databases, and schedulers every day. It is not a local script that runs once and ends. We will put /health, /ready, job history, audit logs, and production acceptance into the project because these things determine whether the system can be trusted over time.

Chapter Update And Repository

This chapter adds:

  • A clear ZiQuant boundary: research, backtesting, alerts, and paper trading only.
  • The first README boundary for the project.
  • The main repository for the column and a runnable chapter 1 tag.

Repository:

https://github.com/ax2/zi-quant-platform

Code for this chapter:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-01
uv sync --extra dev
uv run pytest

Summary

Programmers are well suited to quant trading not because knowing code can beat the market, but because programmers are good at turning complex problems into systems that can run, be verified, and be reviewed.

From this article onward, we treat quant trading as an engineering project. Write boundaries first, then build the skeleton. Simulate before discussing live trading. Preserve evidence before discussing conclusions.

The next article enters project structure: using uv, pyproject.toml, .env, tests, and health checks to build ZiQuant’s Python engineering skeleton.