US market profiles carry no transaction cost model — is this intended for the leaderboard?
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Needs clarification
- Activity status
- Active
- Tech stack
- python
- Domain
- backend, fintech-quant
Research direction
Start with dashboard/backend/infrastructure/market_data/profiles.py and dashboard/backend/domain/trading/execution.py, then check dashboard/backend/tests/infrastructure/market_data/test_market_profiles.py and the backtest metadata cited in the issue. The main first step is to get a maintainer decision on whether zero-cost US execution is intentional; the issue offers documentation or a cost-profile change depending on that answer. Done means implementing the agreed path and updating its relevant documentation or test expectations.
Written by the indexing model from the issue text.
Description
The A-share execution path has a full cost model. The US path has none, and a test pins it that way.
I want to check whether that asymmetry is intentional for leaderboard and dashboard runs, because it
changes how the published numbers should be read.
What the code does
MarketProfile.transaction_cost_profile defaults to None
(profiles.py:144),
and is set on exactly the two IFIND_ASHARE profiles (profiles.py:252, :272). Neither
(ALPACA, "djia_30") nor (VNPY_SIMULATION, "djia_30") sets it.
With a None profile, calculate_transaction_costs() returns a zero breakdown and fills at the
reference price
(execution.py:295-308):
if transaction_cost_profile is None:
price = float(reference_price)
gross = float(shares) * price
return {
"reference_price": price,
"price": price,
"slippage_amount": 0.0,
"commission": 0.0,
"stamp_duty": 0.0,
"transfer_fee": 0.0,
"total_fees": 0.0,
"net_cash_impact": -gross if normalized_side == "buy" else gross,
}
And it's locked by test
(test_market_profiles.py:172-174):
def test_us_profiles_keep_legacy_no_cost_behavior():
assert get_market_profile(ALPACA).transaction_cost_profile is None
assert get_market_profile(VNPY_SIMULATION).transaction_cost_profile is None
So the naming reads as deliberate legacy preservation rather than an oversight — hence a question
rather than a bug report.
Why it matters more for agents than for baselines
ASHARE_TRANSACTION_COST_PROFILE models adverse-direction slippage, price-tick rounding, a ¥5
per-order commission floor, stamp duty and transfer fee. The US path charges nothing on any of those
axes.
The leaderboard compares LLM agents against equal_weight_buyhold, mean_variance,
equal_weight_index and index references. Zero costs are close to harmless for buy-and-hold, which
trades once, and systematically generous to anything that turns over — which is every LLM agent
making an hourly decision. The comparison is therefore biased toward the higher-turnover side of the
board, and the bias grows with turnover rather than being a constant offset.
transaction_costs_applied is already plumbed through run metadata
(backtests.py:303-307),
so the provenance hook exists; it just reports false for every US run.
Questions
- Is zero-cost US execution intended for leaderboard runs, or is it legacy behaviour that predates
the A-share cost model and hasn't been revisited? - If intended — would you accept a docs PR stating it explicitly where returns and Sharpe are
presented? Right now a reader has to reachprofiles.pyto find out. Theclean: truecaveat in
docs/integrations/vnpy-cta.mdis a good model for the tone. - If not intended — would a
US_TRANSACTION_COST_PROFILE(per-share or bps commission plus a
slippage rate,price_tick=0.01) be welcome?calculate_transaction_costsalready handles
everything generically, so the change is a profile constant plus expectation updates; no
execution-path changes. Existing runs would need either a re-run or a profile-version stamp to
stay comparable, and I'd want your call on which before writing it.
Happy to open the PR for either outcome. Thanks for the unusually readable codebase — the commit
messages made this quick to trace.
- Dominant language
- Python
- Stars
- 767
- Forks
- 156
- Avg merge
- 21h 57m
- Merged PRs (30d)
- 92
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Open-Finance-Lab/AgenticTrading
-
fix(llm): a non-ASCII execution handoff raises UnicodeEncodeError instead of ExecutionHandoffErrorPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Open-Finance-Lab/AgenticTrading#659 ·
Maintainers usually reply within 1 day
-
fix(backtests): an LLM action with trailing whitespace ("buy ") is silently droppedPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Open-Finance-Lab/AgenticTrading#658 ·
Maintainers usually reply within 1 day
-
fix(llm): Gemini adapter drops thinking tokens from the output countPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Open-Finance-Lab/AgenticTrading#657 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Open-Finance-Lab/AgenticTrading#591 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Open-Finance-Lab/AgenticTrading#586 ·
Maintainers usually reply within 1 day
All issues in Open-Finance-Lab/AgenticTrading
Similar issues
-
Python Volcengine provider returns failures instead of raising themPossibly taken @Ricardo-M-L claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
agent-infra/sandbox#248 ·
-
Textractor leaves empty temporary files when remote retrieval failsPossibly taken @HuaTNA claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
test(bm_generation): pin the learning parameters and CPU sync shortcutPossibly taken @iloveeyjafjalla claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
qboson/kaiwu-pytorch-plugin#1341 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
elder-plinius/V3R1T4S#625 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
foxglove/mcap#1907 · 1 comment ·
Maintainers usually reply within 1 day