Merge pull request #866 from santhreal/fix/journal-to-float-strip-currency

fix(journal): strip currency symbols before float coerce
This commit is contained in:
Haozhe Wu authored and GitHub committed 2026-07-27 15:49:02 +08:00
commit 5222f418cf
2 files changed
+43 -1

No files matched your search

+10 -1
View File
@@ -9,12 +9,20 @@ Excel (.xlsx/.xls) always opens as utf-8 internally via openpyxl/xlrd.
from __future__ import annotations
import re
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any
import pandas as pd
# Broker CSV/Excel cells often include ISO codes or currency glyphs around the
# number (Schwab/IBKR "$1,234.56", JP/CN "¥1000"). Commas are already stripped;
# without stripping these tokens float() fails and we silently store 0.0.
_CURRENCY_TOKEN_RE = re.compile(
r"(?i)(?<![A-Za-z])(?:USDT|USDC|USD|EUR|GBP|JPY|CNY|HKD)(?![A-Za-z])|[$€£¥¥]"
)
FormatName = str # "tonghuashun" | "eastmoney" | "futu" | "generic" | "unknown"
_A_SHARE_EXCHANGE_MAP = {
@@ -202,7 +210,8 @@ def _to_float(val: Any, default: float = 0.0) -> float:
if val is None:
return default
try:
s = str(val).replace(",", "").strip()
s = str(val).strip().replace("\u2212", "-")
s = _CURRENCY_TOKEN_RE.sub("", s).replace(",", "").strip()
return float(s) if s else default
except (ValueError, TypeError):
return default
+33
View File
@@ -19,6 +19,7 @@ from src.tools.trade_journal_parsers import (
_infer_market_from_symbol,
_normalize_side,
_qualify_a_share,
_to_float,
load_dataframe,
parse_tonghuashun,
parse_eastmoney,
@@ -656,3 +657,35 @@ def test_parse_tonghuashun_float_code_cell() -> None:
rec = parse_tonghuashun(df)
assert len(rec) == 1
assert rec[0].symbol == "600519.SH"
@pytest.mark.parametrize(
"raw,expected",
[
("$1,234.56", 1234.56),
("USD 12.5", 12.5),
("€99.00", 99.0),
("¥1,000", 1000.0),
("\u221212.5", -12.5),
("CNY12.5", 12.5),
],
)
def test_to_float_strips_currency_and_unicode_minus(raw: str, expected: float) -> None:
"""US/EU/Asia broker cells with currency glyphs must not become 0.0."""
assert _to_float(raw) == expected
def test_parse_generic_currency_price_not_zero() -> None:
df = pd.DataFrame([{
"datetime": "2024-01-02 10:00:00",
"symbol": "AAPL",
"side": "buy",
"quantity": "10",
"price": "$150.25",
"fee": "$1.00",
}])
rec = parse_generic(df)
assert len(rec) == 1
assert rec[0].price == 150.25
assert rec[0].fee == 1.0
assert rec[0].amount == 1502.5