Skip to content

Learn

Stock Backtest Research

Reconcile stock backtest end-of-run liquidation and terminal costs

A stock backtest’s last equity value can change after the final regular snapshot because the engine performs terminal settlement. A held position first has a marked value and unrealized profit; forced liquidation then applies an exit price, slippage and commission, leaving cash. The last reported snapshot must follow the declared settlement policy rather than accidentally retaining the earlier, cost-free mark.

This guide reconstructs that bridge with one synthetic long stock position. Static inspection of the local reference engine shows an end_of_backtest close followed by replacement of the final snapshot. The independent standard-library program below does not execute that engine. CoTrading’s corresponding reporting, market eligibility and real execution capabilities remain planned or unverified.

Distinguish three different end states

A marked-only report retains stock quantity, cash and an explicitly supplied closing mark. A strategy exit sells because an eligible strategy condition requested it. A terminal settlement sells in the simulation because the experiment ended. All three may appear near the same chart boundary, but their triggers and interpretation differ. A forced accounting exit must not be mislabeled as evidence that the strategy independently decided to sell.

Freeze which convention the report uses before comparing final results. Changing a marked-only account into a liquidated account adds costs and changes inventory even if the underlying stock prices are identical. Comparing one strategy before its exit fee with another after settlement mixes report bases. Preserve both the pre-settlement snapshot and the post-settlement state so readers can identify the source of the difference.

The fixture has no deposits, dividends, financing, tax or currency conversion. Each completed order pays a synthetic one-unit commission. Exit slippage is one percent below the supplied mark for the long sale; entry is explicitly priced at ten without entry slippage. These asymmetric assumptions are declared rather than concealed in a generic all-costs label.

The Investor.gov fee bulletin explains transaction fees and their effect on account value. It does not prescribe our one-unit charge or slippage rate. Historical research needs its own dated cost evidence. Here those values are controlled accounting inputs, not estimates recovered from a real brokerage statement.

Reproduce the final marked account

Start with cash 1,000, buy forty shares at ten and pay one fee. Cash becomes 599 and quantity forty. The supplied closing marks are ten, eleven and twelve over three indexed observations. Before terminal settlement, marked equity is respectively 999, 1,039 and 1,079. Unrealized price profit is zero, forty and eighty, measured against the entry price ten.

At the last ordinary snapshot, the stock market value is forty times twelve, or 480. Adding cash 599 gives 1,079. This value includes the paid entry fee through the lower cash balance, but no exit fee or exit slippage has yet occurred. It is a marked holding value, not an already liquidated amount available as account cash.

The script asserts the complete pre-settlement record: index two, cash 599, quantity forty, mark twelve, unrealized eighty and equity 1,079. Earlier snapshots are retained unchanged. A report containing only the final number would make it difficult to distinguish a price change from a settlement-cost adjustment or an accidental inventory deletion.

Apply the terminal sale exactly once

For the long liquidation, apply one-percent slippage to mark twelve, giving an exit price of 11.88. Forty shares produce 475.20 principal. Deduct the one-unit exit commission and credit 474.20 to cash. Final cash is 599 plus 474.20, or 1,073.20; inventory becomes zero and cumulative fees two.

The decrease from marked equity 1,079 is 5.80. Slippage explains forty times twelve minus 11.88, or 4.80, and commission explains one. This bridge should be calculated independently rather than inferring total exit costs from a rounded return percentage. Keeping the components visible exposes a duplicated fee or an incorrectly signed slippage adjustment.

Realized price profit is forty times 11.88 minus ten, or 75.20. After two commissions, net cash profit relative to initial capital is 73.20. The price gain and net cash gain are distinct, and the old unrealized eighty must not be added again. It belonged to the earlier marked snapshot and was replaced when the holding was closed.

The Python Decimal reference supports the decimal price and cash arithmetic used in this hand-check. Numeric comparisons accept equivalent decimal representations such as trailing zeros. This avoids mistaking a formatting difference for an economic discrepancy while still requiring the exact quantities, fees and exit price in the fill record.

Replace the final snapshot without adding a new date

After settlement, replace the third snapshot’s equity with final cash 1,073.20, set its quantity and unrealized profit to zero, and retain its terminal index. The snapshot list still has three observations. The earlier 999 and 1,039 records remain unchanged, while the separate preserved pre-terminal record still explains the former 1,079 value.

Appending an extra artificial date could change the length and timing used by metrics. Keeping the old final snapshot would omit exit costs. Subtracting the same costs again after already updating cash would double-charge them. The fixture therefore asserts the final equity equals cash, holdings are flat, unrealized is zero and total fees are exactly two.

It also calls the terminal-close helper again after liquidation and requires no extra fill, fee or cash movement. An already empty position cannot be sold twice. This is a lifecycle check rather than a claim that every possible engine retry is transactional. The example’s scope is one long position and a deterministic terminal accounting operation.

Compare a genuine strategy exit

The independent active-exit control sells at index one because a strategy request is explicitly supplied there. Its mark is eleven and the same exit-slippage convention gives 10.89. Forty shares yield 435.60 principal, or 434.60 after commission. Added to 599 cash, the account ends at 1,033.60 with zero shares and two total fees.

At the experiment’s later end, nothing remains to liquidate. The completed sale is tagged signal, and no end_of_backtest sale is added. The account does not receive a second terminal commission merely because the reporting loop reached its last row. This control distinguishes the cause of the exit and catches double-closing, rather than simply changing the successful terminal path’s price.

A marked-only reference disables forced settlement. It retains forty shares, cash 599, marked equity 1,079 and only the entry fee. Its larger final equity is not evidence that refusing to pay exit costs improves an executable strategy. It reports a different end state. Any performance comparison must first align those conventions or explicitly show the reconciliation.

Keep accounting liquidation separate from market eligibility

Some terminal bookkeeping paths can bypass ordinary sellability or raw-bar checks. The fixture accepts a blocked-market annotation and still computes the same synthetic settlement, while marking terminal execution as unverified. That annotation is not a real halt or T-plus-1 simulator; it makes the interpretation limit explicit. A flat modeled account does not prove a real broker could have sold the position that day.

If a final mark is stale, an accounting settlement based on it is especially different from an observed executable price. Archive the mark’s source and age, relevant market restrictions and the reason the run ended. A real liquidation analysis must apply those constraints separately. Do not use terminal cash as permission to claim that suspended or newly purchased restricted shares became immediately sellable.

Run and audit the settlement bridge

Download the complete example and execute python R603.py with Python 3.12 or newer. It uses only the standard library, synthetic marks and fixed cost inputs. Output includes the terminal account, marked-only reference, active-exit control and blocked-market annotation. It does not contact a broker or run a product backtest.

For an actual last-day discrepancy, collect pre-terminal quantity and mark, the terminal fill and reason, applied slippage, exit commission, resulting cash and final replaced snapshot. Compare those components before changing the strategy. The completed diagnostic is an explainable account bridge, not a historical return guarantee or proof of real liquidation feasibility.

FAQ

Why did the final value fall from 1,079 to 1,073.20?

The synthetic liquidation adds 4.80 of exit slippage and one exit fee. The earlier value was a marked holding, while the later value is modeled cash.

Does zero terminal inventory prove the stock was tradable?

No. Forced settlement is an accounting convention here. Market eligibility and actual execution require their own evidence.