Skip to content

Learn

Stock Portfolio Research

Prepare trading records before deriving a stock strategy

A trading journal can contain many profitable-looking fills while providing very few completed stock round trips. Before deriving a candidate rule, establish which purchases and sales belong together, what fees belong to them, and whether the resulting profits share a currency. An input threshold measures whether a particular preparation workflow can proceed; it does not establish that a trading strategy is reliable.

This guide prepares a synthetic journal with explicit round identifiers. It checks five profitable completed USD rounds, keeps a separate HKD count, and preserves losses, flat trades, open positions and ambiguous groups. This is an external preparation method. It does not run a CoTrading rule extractor, generate a strategy, or demonstrate historical performance.

Freeze the journal and its interpretation

Start with an immutable export and a description of its scope: account, security identity, currency, time zone, execution identifiers and covered dates. A statement export, an order log and a fill log are different records. One order can produce several executions, and a cancellation is not an execution. Preserve the original fields before constructing normalized working rows.

Our fixture requires account, security, currency, execution ID, round ID, side, quantity, price, fee and an ordered integer time. Execution ID, round ID, account, security and currency must each be nonempty strings with at least one non-whitespace character. The supported currency set is explicitly USD and HKD; missing, blank and unknown currencies are rejected before pairing, without guessing or normalization. These times are synthetic sequence positions, not exchange timestamps. The example supports positive whole-share quantities. Fractional-share records need a separately specified quantity contract rather than rounding them into this one.

The SEC investor bulletin on fees discusses checking costs and trade confirmations. It supports reconciling the amounts supplied to an analysis. It does not prescribe our pairing algorithm, certify a five-round threshold, or say that any small set of profitable trades validates a strategy.

Pair only records whose relationship is established

The supplied round ID is an explicit fixture assumption. Identity equality is checked only after validating those fields: two blank accounts, absent securities or unknown currencies cannot establish a valid pair. A valid completed group contains exactly one purchase and one sale, with the same account, security, currency and quantity. The sale must follow the purchase. A single purchase remains open. Multiple purchases or sales produce an ambiguous group rather than an inferred match.

This deliberately narrow contract is not a general FIFO inventory engine. It does not reconstruct partial exits, average-cost positions, corporate-action adjustments or short covering. A real journal without trustworthy round identifiers needs a documented inventory policy and its own reconciliation before it can use a preparation gate. Inventing identifiers from nearby timestamps can pair unrelated holdings and manufacture winners.

Retain the execution IDs on each accepted pair. The output should allow a reviewer to trace a counted round back to its two original fills. Keep excluded groups and reasons in an adjacent ledger, because silently deleting a partial position would conceal the limits of the preparation result.

If an export later corrects a fee or execution identity, create a new preparation version and rerun every count. Record which input changed and why. A previously eligible snapshot does not authorize carrying its eligibility flag onto a revised journal without checking the revised pairs.

Reconcile profit after both execution fees

For one matched long round, net profit is quantity multiplied by sale price minus purchase price, less the purchase fee and sale fee. R1 buys one share at 100 and sells at 103. Each execution costs 0.5, so its net profit is 2 USD. A positive price difference alone is not the definition of a winner.

R6 buys at 100 and sells at 99 with the same fees, producing minus 2 USD. R7 sells at 101 and produces zero after costs. Neither counts toward the profitable-round gate. Preserve both in the closed-round ledger: discarding them would change the sample’s economic meaning even though the positive-round count stayed unchanged.

The example uses Decimal values created from decimal strings. The Python Decimal documentation describes decimal arithmetic and finite-value checks. Decimal can still represent NaN and infinity, so the parser explicitly rejects nonfinite prices and fees, nonpositive prices, and negative fees before calculating profit. A missing fee is an error, not an assumed zero cost.

Count the main case by currency

R1 through R5 each earn 2 USD after fees, so USD has five qualifying rounds and 10 USD profit across those winners. R6 and R7 remain closed but do not qualify. This winner subtotal is not the profit of the complete journal, and the eligibility flag is not a profitability report.

R8 contains only a purchase and is marked open. R9 contains two purchases and one sale and is marked ambiguous_pair. R10 mixes a USD purchase with an HKD sale and receives identity_quantity_or_time_mismatch. The program excludes these groups from the completed-profit count while retaining their statuses.

R11 is a separate complete HKD winner with net profit 2 HKD. Its count is one. The resulting counts are USD five and HKD one, so only the USD input group reaches the illustrative five-winner gate. We do not add USD and HKD profits or use the HKD winner to complete a USD sample.

Run the complete reproducible example

Download the complete example. Save it as R638.py and run Python 3.12 or later with python R638.py. It uses only the standard library and synthetic records, without a broker connection, model call, account credentials or downloaded market history.

The assertions check exact profits of 2, minus 2 and zero; the currency counts; the three exclusion statuses; duplicate execution rejection; missing-fee rejection; nonfinite-price rejection; missing, empty, whitespace and non-string identities; unsupported currencies; and incompatible account pairing. The output states USD_input_eligible=True, HKD_input_eligible=False and rules_generated=False. These are properties of this fixture and contract.

Keep the source file and its actual output with the prepared input snapshot. A reusable handoff should also include the interpretation policy and unresolved exclusions. Running this small example verifies the illustrated preparation logic; it does not verify a separate application’s import format or prove that an installed extraction service accepts the same fields.

Challenge the gate through a different mechanism

Remove R5 while keeping the HKD round. There are still five winners across currencies, but only four are USD. The USD group must now fail the gate. This counterexample catches an aggregation error that would survive a correct profit calculation on every individual pair.

A second check takes only the first five fills. They contain two completed USD winners and the purchase of the third round, which remains open. Five executions therefore do not mean five round trips. Counting rows, orders or profitable sell prices can produce a false eligibility flag without any arithmetic mistake in the accepted pairs.

Duplicate execution IDs raise an error before grouping, and a pair from different accounts receives a mismatch status. Those controls address provenance rather than currency aggregation. Investigate the source discrepancy instead of duplicating a fill or transferring its profit between accounts to reach the threshold.

Hand off an eligible sample without overstating it

Treat the five-profitable-round condition only as a reference preparation gate for a later extraction experiment. It is not a universal minimum sample size, statistical significance test or evidence of repeatable skill. The workflow has not evaluated losing opportunities, market exposure, selection bias, timing leakage or future execution costs.

A subsequent research design needs a frozen candidate rule, data available at each decision, an untouched evaluation interval, a benchmark and explicit cost assumptions. Preserve unsuccessful extraction attempts as well as successful candidates. Selecting only the best explanation of five winners can hide the search that produced it.

Do not send the prepared journal directly to live replication. Market availability, tradable security identities, account permissions and an application’s supported stock universe still require verification. Any fixed liquid reference basket is a scope restriction, not authority to scan or trade every stock. This article prepares inputs and leaves those later operational checks unresolved.

FAQ

Does five profitable rounds mean the strategy works?

No. It only reaches this illustrative input gate in one currency. The example generates no rule and performs no out-of-sample evaluation. Five selected winners can coexist with losses, an unclosed position, or substantial unmeasured market exposure.

Can missing fees or partial fills be repaired automatically?

Not under this contract. Missing fees fail validation and complex groups remain ambiguous. Obtain confirmed costs and establish a separate inventory policy before changing those statuses; do not fill missing information with assumptions merely to increase the qualifying count.