Skip to content

Software engineering

The discipline of making quantitative software understandable, testable, changeable and supportable across requirements, interfaces and operation.

Software engineering is the disciplined design, construction, verification, operation and evolution of software to meet agreed needs. For a quant team, the result includes a calculation that colleagues can understand, check, change and support when inputs or requirements change.
Programming expresses the calculation in executable instructions. Software engineering also asks who needs the result, what inputs mean, how components fit together, what evidence supports a change, and what happens when a run fails. These activities overlap and repeat as the team learns; they need not be consecutive project phases. The SWEBOK chapters on requirements and design explain these responsibilities.

A number is only part of the requirement

Consider a fictional offline tool that marks one equity position. Two shares at USD 100 per share should produce USD 200. That example leaves questions unanswered: are fractional or short positions allowed, which currency is returned, and what should happen if the price is absent?

For this teaching example, agree a deliberately narrow contract:

  • The input is a Python dictionary with exactly the keys quantity and price_usd.
  • Each value is a string of one to seven ASCII digits, with a numerical value from 0 to 1,000,000 inclusive. Leading zeros are allowed; signs, whitespace, decimal points and exponent notation are rejected.
  • quantity means whole shares. price_usd means whole USD per share. Zero is allowed for either field by this example's policy.
  • The output is an integer number of USD: quantity multiplied by price. An invalid record raises ValueError; a missing price never becomes a zero price.

This intentionally excludes fractional shares, cents, short positions, fees, foreign currencies and deciding whether a mark is current. A real valuation requirement would need to resolve those questions for its instruments and users. The restrictions here make the boundary inspectable, rather than establish a generally suitable pricing policy.

Put the agreement at the boundary

An application programming interface specifies how another component calls the tool and interprets its result or failure. Keeping input handling separate from arithmetic makes it easier to replace a file reader or user interface without changing the valuation rule.

This small Python example implements the stated contract. Type annotations document intent; the explicit checks enforce it at runtime.

import re def value_usd(record: dict[str, str]) -> int: """Value one position under the whole-share, whole-USD contract.""" if not isinstance(record, dict) or set(record) != {"quantity", "price_usd"}: raise ValueError("quantity and price_usd are required; no extra fields") values = [] for field in ("quantity", "price_usd"): text = record[field] if not isinstance(text, str) or re.fullmatch(r"[0-9]{1,7}", text) is None: raise ValueError(f"{field} must contain 1 to 7 ASCII digits") number = int(text) if number > 1_000_000: raise ValueError(f"{field} exceeds the example limit") values.append(number) quantity, price = values return quantity * price print(f'USD {value_usd({"quantity": "2", "price_usd": "100"})}') # USD 200 try: value_usd({"quantity": "2"}) except ValueError: print("missing price rejected") # missing price rejected
The block was run with Python 3.14.4. Python's re.fullmatch checks the entire string. Integer arithmetic avoids rounding in this restricted example; choosing monetary precision and rounding for a broader contract is a separate design decision. No network or market-data service is involved.
Five engineering responsibilities around a fictional valuation: requirements specify units and missing-price rejection; the interface parses and validates; tests check USD 200 and the rejection; changes retain reviewable versions; operation retains evidence and a failure owner.
Five engineering responsibilities around a fictional valuation: requirements specify units and missing-price rejection; the interface parses and validates; tests check USD 200 and the rejection; changes retain reviewable versions; operation retains evidence and a failure owner.
Fictional offline example. Engineering connects the calculation to its requirements, checks, changes and use; operational failures and new needs feed back into the agreement.

Build evidence for the behaviour you need

A unit test can check the arithmetic or input validator in isolation. An integration test checks connected components, such as a file reader passing the intended fields into this boundary. The distinction concerns what is exercised, not the number of assertions.
The successful USD 200 result and the missing-price rejection check different requirements. Boundary cases, malformed records and changed interfaces need their own checks. If a defect is found, retain a regression test for it. Passing selected tests supplies evidence about those cases; it does not prove that the software has no defects or that the financial model is appropriate. SWEBOK's testing chapter makes both the scope and limits explicit.

Keep the next change understandable

Suppose the team later needs fractional shares. That changes the input and numerical contract. Review the requirement, representation, callers and tests together: removing a parser check alone would leave the integer calculation inconsistent with the new need. Version control keeps reviewable file history; documentation should explain decisions that a future maintainer would otherwise have to guess. Maintenance also includes adapting to new environments and needs, as described in SWEBOK's maintenance chapter.
Reproducibility requires a record of the computational setup and the actual inputs behind a result. Retain the code revision, input snapshot and configuration so a colleague can investigate a disputed valuation.
If the tool becomes a recurring service, decide who responds to failures, what evidence is retained, and when an invalid or stale input stops downstream use. Measure behaviour that matters to users, such as failed valuations and completion time; Google's monitoring guidance explains why useful monitoring connects observations to action. A production trading system adds further concerns around orders, state and controls. The small function above demonstrates one boundary; it has not been deployed or assessed as production infrastructure.

Learn the supporting techniques

  • Files and Exceptions develops parsing, validation and narrow exception handling. The full lesson is free with sign-in.
  • Testing Numerical Code develops numerical reference values, invariants and tolerance choices. Public preview; full lesson requires membership.
  • Reproducibility builds a run record and replay procedure. Public preview; full lesson requires membership.

Sources

Last updated
  • software engineering
  • quant software
  • input contracts
  • software lifecycle
← Back to the glossaryBack to top ↑