Add 06067 T0 analyst report

Request:
- Generate an analyst report for HK IPO ticker 06067.

Changes:
- Archived the official HKEXnews 06067 prospectus PDF and extracted text under project-relative data paths.
- Seeded 06067 T0 prospectus facts, source references, sync state, and analysis snapshots.
- Generated reports/2026-06-15_06067_T0_prospectus_analysis.md in Simplified Chinese with concrete T0/T1/T2/D1 dates and short-exit T2/D1 discipline.
- Updated the HKEX document archiver so over-allotment shares are only recorded when the prospectus supports them, with explicit no-option cases stored as zero.

Verification:
- Compiled archive_hkex_documents.py, generate_ipo_report.py, build_analysis_dataset.py, extract_pdf_text.py, and update_sync_state.py.
- Ran SQLite integrity_check and foreign_key_check.
- Verified the archived 06067 PDF hash, extracted-text manifest row, and analysis dataset row.
- Ran git diff --check.

Next useful context:
- 06067 is currently T0_prospectus; T1_allotment is pending for 2026-06-22.
This commit is contained in:
2026-06-15 15:03:07 +00:00
parent 77b405e4f3
commit 42c18131e8
14 changed files with 28912 additions and 2784 deletions
+19 -3
View File
@@ -407,6 +407,24 @@ def date_after(label_pattern: str, text: str) -> str | None:
return None
def parse_over_allotment_offer_shares(local_path: str, global_offer_shares: int | None) -> int | None:
text = normalize_pdf_text(first_pdf_text(local_path, 320))
if re.search(r"\bno\s+over-?allotment\s+option\b", text, flags=re.I):
return 0
explicit_shares = integer_after(
r"over-?allotment option.{0,500}?up to\s+([\d][\d,\s]*)\s+(?:additional\s+)?(?:H\s+)?Shares",
text,
)
if explicit_shares is not None:
return explicit_shares
if global_offer_shares and re.search(r"over-?allotment option", text, flags=re.I):
if re.search(r"(?:15%|15\s+per\s+cent|fifteen\s+per\s+cent)", text, flags=re.I):
return round(global_offer_shares * 0.15)
return None
def parse_prospectus_facts(local_path: str) -> ProspectusFacts:
text = normalize_pdf_text(first_pdf_text(local_path, 8))
board_lot = integer_after(r"minimum\s*of\s*([\d][\d,\s]*)\s*Hong\s*Kong\s*Offer\s*Shares", text)
@@ -422,9 +440,7 @@ def parse_prospectus_facts(local_path: str) -> ProspectusFacts:
global_shares = integer_after(r"Number of Offer Shares\s*:?\s+([\d][\d,\s]*)\s+(?:H\s+)?Shares", text)
hk_shares = integer_after(r"Number of Hong Kong Offer Shares\s*:?\s+([\d][\d,\s]*)", text)
intl_shares = integer_after(r"Number of International Offer Shares\s*:?\s+([\d][\d,\s]*)", text)
over_allotment = None
if global_shares:
over_allotment = round(global_shares * 0.15)
over_allotment = parse_over_allotment_offer_shares(local_path, global_shares)
public_pct = round(hk_shares / global_shares, 4) if global_shares and hk_shares else None
allotment_date = (
date_after(r"Announcement of the level of indications.*?basis of allocation", text)