Report simulated stock portfolios separately by currency
A report containing USD, HKD and CNY stock accounts cannot add their cash or profits as though every number had the same unit. Separate the research pools before rule eligibility, opening capital and execution. Optional conversion for a presentation table belongs after the native ledgers and must not turn into an implied mixed-currency backtest.
This guide uses synthetic currency pools, with USD and CNY eligible for independent observation while HKD waits. No model, real account or market feed is used. The grouping and reporting method is an external extension; it does not establish that CoTrading runs persistent multicurrency accounts or that a position-aggregation FX display supports currency conversion inside a backtest engine.
Declare the supported currency contract
The fixture accepts exactly USD, HKD and CNY. Unknown, blank or unsupported currency identifiers raise an error even when a group contains five winners. A homogeneous set of unknown labels is not evidence of a valid settlement currency. Keep actual security/counter metadata with each pool rather than inferring a currency solely from a broad market label.
The ordinary-stock scope here concerns separately prepared US, Hong Kong and mainland-China research inputs. It does not assert that all listings in a market share one counter currency, that every ticker is covered, or that the synthetic whole-share quantities satisfy real exchange lot rules. Verify those contracts independently before adapting the account calculations to actual securities.
Freeze each pool’s basket, rule version, journal cutoff and observation interval. Several markets sharing a currency can still differ in calendars and execution behavior. Currency equality only clears the unit-of-account condition; it does not automatically make their securities eligible for a common strategy or justify silently sharing capital between independent experiments.
Evaluate the input gate separately for each pool
The reference preparation condition is at least five profitable completed rounds in the same currency. It is not five executions, five mixed-currency winners or proof of strategy effectiveness. The sample receives already checked integer counts: USD five, HKD four and CNY five. It does not reconstruct those rounds or call an extraction model.
HKD remains waiting_eligibility. Its cash, shares and NAV are None, meaning no observation account was opened under this policy. They are not zero-loss results or an allocation that should be funded automatically. Keep the waiting status in the report so a missing group cannot disappear when someone compares the active accounts.
Unknown opening capital is permissible only in that unfunded waiting record because it is never used for execution. An active pool requires finite positive starting capital and valid price/fee inputs. Do not fill a waiting group’s cash from another currency, treat a winner count as spendable money, or borrow eligibility from an otherwise successful account.
Fund and value each native account independently
For an eligible account, subtract its local purchase amount and fee from its own opening cash. Retain quantity and value the holding at a local mark. Before market movement, cash plus shares at the execution price must equal opening capital less fee. After marking, compute the account’s return using that pool’s own positive opening capital.
The Python Decimal documentation supports explicit decimal calculations and finite checks. The fixture rejects NaN or infinite money and negative fees before arithmetic. Each quantity is a nonnegative integer under the toy contract. This is arithmetic for declared inputs, not an actual validation of US fractional-share facilities, mainland lots or Hong Kong board-lot metadata.
USD opens with 1,000, buys two shares at 100 and pays one. Cash is 799, shares two, and a mark of 110 produces NAV 1,019, return 1.9%. CNY opens with 2,000, buys ten shares at 20 and pays two. Cash is 1,798 and the mark 21 produces NAV 2,008, return 0.4%. Neither account spends the other’s cash.
Keep native totals and headline results honest
Do not report 1,019 plus 2,008 as a single unconverted NAV. The function native_sum explicitly rejects more than one active currency. Likewise, the two percentage returns cannot simply be added, and choosing one pool as a headline does not convert the others into that currency. Label any selected headline’s scope and retain the other pools’ independent results.
Opening 1,000 USD and 2,000 CNY are independent assumptions, not evidence that a real investor deposited their combined economic value. A reference workflow may assign the same numeric initial capital to every currency pool; that still creates separate unit amounts rather than one shared budget. Any actual funding plan needs distinct cash sources and currency identities.
Waiting pools require particular care in a presentation table. Do not display HKD NAV zero next to USD and CNY returns, because that suggests an observed account lost or held no capital. Use the explicit waiting state and explain which prerequisite remains unmet. A missing result, a valid zero return and an unfunded experiment are different information states.
Add FX display only after native accounting
The optional helper multiplies active native NAV by a supplied number of USD per native unit. USD’s rate must be one. The synthetic CNY-to-USD rate is 0.14, so the displayed value is 1,019 + 2,008*0.14 = 1,300.12 USD. HKD is excluded from this display because its account has not opened, not because a zero conversion rate was assumed.
The ECB reference-rate page distinguishes information-only reference rates from transaction use. Our rate is invented and is not an ECB quote. For a real display, record source, timestamp, quote direction and base currency; the ECB’s own published table is quoted against EUR, so its numbers must not be misread as direct USD-per-CNY values.
This one-instant display does not buy currency, transfer capital, charge conversion spreads or reconstruct historical FX paths. It reports no aggregate portfolio return. Computing an economic base-currency return across time would require aligned FX at each relevant boundary, external flows and a declared valuation policy. A current display conversion is insufficient evidence that an underlying mixed-currency simulation exists.
Preserve missing-FX and invalid-input states
Remove the CNY rate and the helper returns FX_unknown with no aggregate USD value. The native USD and CNY ledgers remain unchanged and can still be reported independently. Missing conversion does not erase valid local returns, and it does not authorize assuming parity or filling the rate from an unrelated date merely to keep a dashboard total visible.
A NaN CNY conversion is rejected rather than displayed. Unsupported EUR, UNKNOWN, None or blank currency identifiers are rejected at pool creation. These counterexamples address unit and metadata failures, distinct from HKD’s legitimate waiting-for-eligibility state. Keep failure reasons separate so users know whether to obtain a rate, verify a security currency or collect more qualifying records.
If a pool later becomes eligible, create its own new observation start and opening assets. Do not backdate it to align with existing winners in another account. Comparisons across different start intervals need clear labels or a separate common-period study. A newly funded account should not inherit past profit or simulated holdings from an already active currency group.
Run and retain the separated report
Download the complete example, save R646.py and run python R646.py using Python 3.12 or later. Only the standard library and synthetic inputs are required. Assertions verify local cash, shares, NAV and returns, HKD’s None-valued waiting assets, display value 1,300.12, missing FX, nonfinite conversion and rejection of unconverted cross-currency aggregation.
Deliver each native ledger, its eligibility evidence, capital assumption and coverage scope, plus a separately labeled optional display table. Keep the rate version with the display rather than modifying the native account history. The five-winner threshold remains a preparation condition, and neither local positive return in this fixture proves that a learned rule will work, generalize or be deployable through a broker.
Retain the actual trading-counter identity when one issuer has listings or counters in different currencies. Company-name equality does not justify exchanging prices or qualifying-round counts between them. This fixture consumes already confirmed currency metadata and does not provide a universal counter resolver.
FAQ
Can HKD’s four winners borrow one from USD?
No. Eligibility is evaluated within the declared currency group. The waiting account remains unfunded here.
Does a USD display mean the engine traded foreign exchange?
No. The helper only converts marked values for one presentation instant and reports no mixed-currency backtest return.