fix(openinsider_top): treat negative Value on sales as absolute for threshold parsing
Handle strings like '-,234,567' by normalizing and parsing magnitude; ensures sales rows are included when exceeding INSIDER_MIN_AMOUNT.
This commit is contained in:
@@ -64,26 +64,39 @@ class OpenInsiderTopCrawler(BaseCrawler):
|
||||
|
||||
@staticmethod
|
||||
def _parse_money(val: str) -> Optional[int]:
|
||||
"""Parse money text into absolute integer dollars.
|
||||
|
||||
Handles formats like:
|
||||
- "$1,234,567"
|
||||
- "($1,234,567)" (treat as negative but return magnitude)
|
||||
- "-$1,234,567" (treat as negative but return magnitude)
|
||||
- "1,234,567"
|
||||
Returns None if no digits found.
|
||||
"""
|
||||
if not val:
|
||||
return None
|
||||
s = val.strip()
|
||||
# Remove $ and commas and any parentheses
|
||||
for ch in ['$', ',', '(', ')', '+']:
|
||||
# Detect negative indicators before stripping
|
||||
is_negative = s.startswith('-') or '(' in s
|
||||
# Normalize: remove currency symbols, commas, parentheses, plus/minus, spaces
|
||||
for ch in ['$', ',', '(', ')', '+', '-', ' ']:
|
||||
s = s.replace(ch, '')
|
||||
# Some cells may include text like "$1,234,567 (incl. options)"
|
||||
# Keep only leading numeric part
|
||||
# Keep only leading digits
|
||||
num = ''
|
||||
for c in s:
|
||||
if c.isdigit():
|
||||
num += c
|
||||
elif c in ' .':
|
||||
elif c == '.':
|
||||
# ignore decimal points; values appear to be whole dollars
|
||||
continue
|
||||
else:
|
||||
break
|
||||
if not num:
|
||||
return None
|
||||
try:
|
||||
return int(num)
|
||||
value = int(num)
|
||||
# We return absolute magnitude; sign is not needed for threshold
|
||||
return abs(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
@@ -227,4 +240,3 @@ class OpenInsiderTopCrawler(BaseCrawler):
|
||||
f"抓取時間:{datetime.now().isoformat()}\n來源:\n- " + "\n- ".join(self.urls)
|
||||
)
|
||||
return subject, body
|
||||
|
||||
|
Reference in New Issue
Block a user