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:
commit
5222f418cf
2 files changed
+43
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user