Spaces:
Running
Running
Sigrid De los Santos
commited on
Commit
·
c58a978
1
Parent(s):
538e205
debugging for analysis tables
Browse files- app.py +5 -13
- data/health_2025-07-26.md +103 -0
- html/health_2025-07-26.html +203 -0
- src/main.py +104 -117
app.py
CHANGED
@@ -1,13 +1,12 @@
|
|
1 |
import os
|
2 |
import sys
|
3 |
import tempfile
|
4 |
-
import
|
5 |
import streamlit as st
|
6 |
import pandas as pd
|
7 |
import requests
|
8 |
import openai
|
9 |
|
10 |
-
# Add 'src' to Python path
|
11 |
sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
|
12 |
from main import run_pipeline
|
13 |
|
@@ -40,17 +39,10 @@ if submitted:
|
|
40 |
if not openai_api_key or not tavily_api_key or not all([td['topic'] for td in topics_data]):
|
41 |
st.warning("Please fill in all fields.")
|
42 |
else:
|
43 |
-
# Reset old results
|
44 |
articles_df = pd.DataFrame()
|
45 |
insights_df = pd.DataFrame()
|
46 |
html_paths = []
|
47 |
|
48 |
-
# === Clear old reports ===
|
49 |
-
for folder in ["data", "html"]:
|
50 |
-
if os.path.exists(folder):
|
51 |
-
shutil.rmtree(folder)
|
52 |
-
os.makedirs(folder, exist_ok=True)
|
53 |
-
|
54 |
os.environ["OPENAI_API_KEY"] = openai_api_key
|
55 |
os.environ["TAVILY_API_KEY"] = tavily_api_key
|
56 |
|
@@ -113,7 +105,7 @@ if submitted:
|
|
113 |
with tab_articles:
|
114 |
st.subheader("📋 Articles Table")
|
115 |
if not articles_df.empty:
|
116 |
-
st.dataframe(articles_df[["Title", "URL", "Summary", "Priority", "Date"]],
|
117 |
use_container_width=True)
|
118 |
st.download_button(
|
119 |
label="⬇️ Download Articles CSV",
|
@@ -126,7 +118,7 @@ if submitted:
|
|
126 |
|
127 |
# === Insights Tab ===
|
128 |
with tab_insights:
|
129 |
-
st.subheader("📊 Investment Insights")
|
130 |
if not insights_df.empty:
|
131 |
st.dataframe(insights_df, use_container_width=True)
|
132 |
st.download_button(
|
@@ -137,6 +129,8 @@ if submitted:
|
|
137 |
)
|
138 |
else:
|
139 |
st.info("No insights available.")
|
|
|
|
|
140 |
with tab_debug:
|
141 |
st.subheader("🛠 Debug Log")
|
142 |
st.code("\n".join(logs) if logs else "No logs yet.")
|
@@ -144,8 +138,6 @@ if submitted:
|
|
144 |
except Exception as e:
|
145 |
spinner_box.error("❌ Failed.")
|
146 |
log_box.error(f"❌ Error: {e}")
|
147 |
-
# === Debug Tab ===
|
148 |
-
|
149 |
|
150 |
|
151 |
# import os
|
|
|
1 |
import os
|
2 |
import sys
|
3 |
import tempfile
|
4 |
+
import time
|
5 |
import streamlit as st
|
6 |
import pandas as pd
|
7 |
import requests
|
8 |
import openai
|
9 |
|
|
|
10 |
sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
|
11 |
from main import run_pipeline
|
12 |
|
|
|
39 |
if not openai_api_key or not tavily_api_key or not all([td['topic'] for td in topics_data]):
|
40 |
st.warning("Please fill in all fields.")
|
41 |
else:
|
|
|
42 |
articles_df = pd.DataFrame()
|
43 |
insights_df = pd.DataFrame()
|
44 |
html_paths = []
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
os.environ["OPENAI_API_KEY"] = openai_api_key
|
47 |
os.environ["TAVILY_API_KEY"] = tavily_api_key
|
48 |
|
|
|
105 |
with tab_articles:
|
106 |
st.subheader("📋 Articles Table")
|
107 |
if not articles_df.empty:
|
108 |
+
st.dataframe(articles_df[["Title", "URL", "Summary", "Priority", "Sentiment", "Confidence", "Signal", "Date"]],
|
109 |
use_container_width=True)
|
110 |
st.download_button(
|
111 |
label="⬇️ Download Articles CSV",
|
|
|
118 |
|
119 |
# === Insights Tab ===
|
120 |
with tab_insights:
|
121 |
+
st.subheader("📊 Top Investment Insights")
|
122 |
if not insights_df.empty:
|
123 |
st.dataframe(insights_df, use_container_width=True)
|
124 |
st.download_button(
|
|
|
129 |
)
|
130 |
else:
|
131 |
st.info("No insights available.")
|
132 |
+
|
133 |
+
# === Debug Tab ===
|
134 |
with tab_debug:
|
135 |
st.subheader("🛠 Debug Log")
|
136 |
st.code("\n".join(logs) if logs else "No logs yet.")
|
|
|
138 |
except Exception as e:
|
139 |
spinner_box.error("❌ Failed.")
|
140 |
log_box.error(f"❌ Error: {e}")
|
|
|
|
|
141 |
|
142 |
|
143 |
# import os
|
data/health_2025-07-26.md
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Health Sector Value Investing Memo – Week of July 24, 2025
|
2 |
+
|
3 |
+
---
|
4 |
+
|
5 |
+
### 📌 Executive Summary
|
6 |
+
|
7 |
+
- **Sentiment is mixed/neutral overall**; most headlines reflect ongoing innovation, moderate but targeted funding, and a few strategic acquisitions, but there’s caution in public markets and ongoing pressure on healthcare costs.
|
8 |
+
- **Risks:** Regulatory/policy uncertainty, margin compression in incumbent insurers, and still-high valuations in certain subsectors (AI, digital health) temper any momentum.
|
9 |
+
- **Catalysts:** New leadership hires, large asset transactions (Labcorp), community and preventative health initiatives are active. Multiple startups are raising significant funding rounds, especially focused on **AI in Medicaid enrollment** and **preventative care**.
|
10 |
+
- **Smart money appears focused** on early-stage, tech-enabled healthcare solutions, especially in areas where legacy players struggle to innovate or scale.
|
11 |
+
|
12 |
+
---
|
13 |
+
|
14 |
+
### 📊 Signals and Analysis
|
15 |
+
|
16 |
+
#### 1. **Vivalink and CHCC: Hospital-at-Home Blueprint**
|
17 |
+
- **What:** Vivalink (remote patient monitoring devices) and Cleveland Clinic Health Center (CHCC) announced a blueprint for nationwide hospital-at-home services.
|
18 |
+
- **Why:** As hospitals look to control costs and expand capacity, home-based care could be a significant growth market; Vivalink is a small, private company competing with giants, but partnerships with brand-names are a strong moat signal. [Vivalink and CHCC to Create National Hospital-at-Home Blueprint](https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/)
|
19 |
+
|
20 |
+
#### 2. **Fortuna Health: $18M Series A Led by a16z**
|
21 |
+
- **What:** Raised $18M Series A (led by Andreessen Horowitz) to build AI-driven Medicaid enrollment tools. Investor syndicate includes notable names: Y Combinator, executives from DoorDash, One Medical, Oscar Health, and more.
|
22 |
+
- **Why:** Medicaid and government benefit navigation are large, under-digitized markets. With public and private pressure to expand coverage, adoption and monetization potential is high if tech execution is strong. **Strong indication of smart money interest.** [Fortuna Health raises $18M to enhance AI for Medicaid enrollment](https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment)
|
23 |
+
|
24 |
+
#### 3. **Everlab: $10M Preventative Care Funding**
|
25 |
+
- **What:** Everlab, a digital preventative care startup, raised $10M with credible backers (previous comparables include PeopleOne Health with $32.3M led by GV/Google Ventures).
|
26 |
+
- **Why:** Preventative care is moated by network effects and adoption difficulty; fresh capital suggests future scale-up and M&A potential. [Everlab garners $10M for preventative care platform](https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform)
|
27 |
+
|
28 |
+
#### 4. **Labcorp Buys Community Health Lab Assets ($195M)**
|
29 |
+
- **What:** Labcorp (NYSE: LH) to acquire select Community Health outreach laboratory assets for $195M.
|
30 |
+
- **Why:** This acquisition consolidates Labcorp’s dominant position in lab services, potentially increasing **margins and economies of scale**. [Labcorp to buy some Community Health assets for $195M](https://www.medtechdive.com/news/Labcorp-Community-Health-outreach-lab-acquisition/753883/)
|
31 |
+
|
32 |
+
#### 5. **DrFirst New CEO: Laizer Kornwasser**
|
33 |
+
- **What:** DrFirst, a health IT and e-prescribing provider, appointed Laizer Kornwasser as CEO.
|
34 |
+
- **Why:** Notable leadership change. Kornwasser’s connections (previously at Humana, Diplomat Pharmacy) may open new payer/provider channels and M&A activity. [DrFirst Appoints Laizer Kornwasser as CEO](https://hitconsultant.net/2025/07/22/drfirst-appoints-laizer-kornwasser-as-ceo/)
|
35 |
+
|
36 |
+
#### 6. **Charta Health: $22M for AI Ops**
|
37 |
+
- **What:** Raised $22M to build AI-powered backend healthcare ops. Founders have ex-Rockset/OpenAI pedigree.
|
38 |
+
- **Why:** Early-stage, but deep tech capability and OpenAI connections signal future "picks and shovels" for next-gen clinical systems. Watch for enterprise SaaS adoption rates. [Charta Health raises $22M for AI healthcare operations platform](https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform)
|
39 |
+
|
40 |
+
#### 7. **Macro Signals: Insurance Pressures and Funding Flows**
|
41 |
+
- **Health insurer sentiment is negative** as future regulatory/policy risks and cost challenges cloud earnings outlook—Moody's gives a sector-wide "negative" rating. [Health Care Data CEO Gets Real About Wearables](https://www.newsweek.com/health-care-data-ceo-gets-real-about-wearables-access-health-2103576)
|
42 |
+
- **Digital health funding flows strongly toward AI/Medicaid** and ops automation—suggesting higher future value may accrue to capital-light startups over lagging incumbents. [Top digital health funding: Startups focus on AI, Medicaid](https://www.modernhealthcare.com/health-tech/mh-digital-health-top-funding-absolutecare-aidoc/)
|
43 |
+
|
44 |
+
---
|
45 |
+
|
46 |
+
### 🧠 Investment Thesis
|
47 |
+
|
48 |
+
#### **Outlook and Opportunity**
|
49 |
+
|
50 |
+
**Healthcare innovation remains robust**, with early-stage private markets attracting smart money—especially toward AI-driven, operationally scalable startups mediating complex government/payor flows (Medicaid, insurance, preventative care).
|
51 |
+
|
52 |
+
- **Public markets:** Cautiously neutral/bearish on established insurers and service providers (margin pressure, regulatory uncertainty).
|
53 |
+
- **Small- and mid-cap "enablers" (testing, health tech SaaS, remote monitoring):** Attractive if they show durable moats, recurring revenue, and prudent valuation.
|
54 |
+
- **Startup arena (key focus):** AI-in-Medicaid (Fortuna), preventative care (Everlab), AI healthcare ops (Charta), and digital clinical infrastructure (Vivalink) are top "watch" or "invest" candidates as funding and partnerships signal smart money rotation from legacy to tech-enabled plays.
|
55 |
+
|
56 |
+
#### **Risk/Reward**
|
57 |
+
|
58 |
+
- **Risks:** Regulatory changes (esp. Medicaid), tech execution, adoption speed, high valuations for some digital health names, failure to scale past early-stage funding.
|
59 |
+
- **Rewards:** Outsized growth in underpenetrated segments (Medicaid tech, remote/home care, AI health ops), potential for early liquidity via M&A/IPO if momentum persists.
|
60 |
+
|
61 |
+
#### **Key Themes**
|
62 |
+
|
63 |
+
- **Smart money is moving into digital-first, operationally differentiated solutions.**
|
64 |
+
- **Strategic M&A targets:** Clinical infrastructure and preventative care platforms.
|
65 |
+
- **Watch for partnerships with large health systems/payors as validation.**
|
66 |
+
- **Leadership changes in key startups/health IT firms may drive accelerated business development and M&A interest.**
|
67 |
+
|
68 |
+
---
|
69 |
+
|
70 |
+
## 🕵️♂️ **Stocks or Startups to Watch**
|
71 |
+
|
72 |
+
1. **Labcorp (LH)** – Strong FCF, reasonable P/E, proven M&A integration [Yahoo Finance: Labcorp (LH)](https://finance.yahoo.com/quote/LH/)
|
73 |
+
2. **Everlab** – Watch for follow-on rounds, partnerships, or early commercial traction. [Everlab garners $10M for preventative care platform](https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform)
|
74 |
+
3. **Fortuna Health** – Early leadership in Medicaid digitization; Andreessen Horowitz and top operator backing. [Fortuna Health raises $18M to enhance AI for Medicaid enrollment](https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment)
|
75 |
+
4. **Charta Health** – Early, but strong tech DNA and ex-OpenAI founders suggest future moat. [Charta Health raises $22M for AI healthcare operations platform](https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform)
|
76 |
+
5. **Vivalink** – Watch for further strategic partnerships or M&A; highly differentiated remote monitoring/data play. [Vivalink and CHCC to Create National Hospital-at-Home Blueprint](https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/)
|
77 |
+
|
78 |
+
---
|
79 |
+
|
80 |
+
## 🧩 **What Smart Money Might Be Acting On**
|
81 |
+
- Funding migration to AI-driven Medicaid navigation, automation, and preventative care platforms (Fortuna, Everlab, Charta Health).
|
82 |
+
- Strategic partnerships between innovative SMEs and major hospital systems (Vivalink/CHCC).
|
83 |
+
- Select M&A for scalable, moat-like clinical assets (Labcorp).
|
84 |
+
|
85 |
+
---
|
86 |
+
|
87 |
+
## 📚 References
|
88 |
+
|
89 |
+
1. [Vivalink and CHCC to Create National Hospital-at-Home Blueprint](https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/)
|
90 |
+
2. [Fortuna Health raises $18M to enhance AI for Medicaid enrollment](https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment)
|
91 |
+
3. [Everlab garners $10M for preventative care platform](https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform)
|
92 |
+
4. [Labcorp to buy some Community Health assets for $195M](https://www.medtechdive.com/news/Labcorp-Community-Health-outreach-lab-acquisition/753883/)
|
93 |
+
5. [DrFirst Appoints Laizer Kornwasser as CEO](https://hitconsultant.net/2025/07/22/drfirst-appoints-laizer-kornwasser-as-ceo/)
|
94 |
+
6. [Charta Health raises $22M for AI healthcare operations platform](https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform)
|
95 |
+
7. [Top digital health funding: Startups focus on AI, Medicaid](https://www.modernhealthcare.com/health-tech/mh-digital-health-top-funding-absolutecare-aidoc/)
|
96 |
+
8. [Health Care Data CEO Gets Real About Wearables](https://www.newsweek.com/health-care-data-ceo-gets-real-about-wearables-access-health-2103576)
|
97 |
+
9. [Yahoo Finance: Labcorp (LH)](https://finance.yahoo.com/quote/LH/)
|
98 |
+
|
99 |
+
---
|
100 |
+
|
101 |
+
### 🚦 **Investment Hypothesis (Actionable)**
|
102 |
+
|
103 |
+
**Watch or accumulate positions in "picks-and-shovels" healthcare enablers (Labcorp) and continue to monitor early-stage AI/Medicaid and preventative care startups entering scale-up phase.** Leadership changes and institutional VC backing in the sector suggest further catalyst events ahead. Beware of overextension/valuation in digital health; focus on demonstrated moats, partnerships, and cash flow resilience. Risk/reward presently skews in favor of smartly selected innovators over entrenched laggards.
|
html/health_2025-07-26.html
ADDED
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<!DOCTYPE html>
|
3 |
+
<html lang="en">
|
4 |
+
<head>
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<title>health_2025-07-26</title>
|
7 |
+
<style>
|
8 |
+
body {
|
9 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
10 |
+
margin: 0;
|
11 |
+
background-color: #f8f9fa;
|
12 |
+
color: #212529;
|
13 |
+
line-height: 1.6;
|
14 |
+
}
|
15 |
+
header {
|
16 |
+
background-color: #ffffff;
|
17 |
+
text-align: center;
|
18 |
+
padding: 1em;
|
19 |
+
border-bottom: 2px solid #dee2e6;
|
20 |
+
}
|
21 |
+
header img {
|
22 |
+
width: 100%;
|
23 |
+
height: auto;
|
24 |
+
max-height: 50vh;
|
25 |
+
object-fit: cover;
|
26 |
+
}
|
27 |
+
.credit {
|
28 |
+
font-size: 0.85em;
|
29 |
+
color: #6c757d;
|
30 |
+
margin-top: 0.5em;
|
31 |
+
}
|
32 |
+
.container {
|
33 |
+
display: flex;
|
34 |
+
flex-direction: row;
|
35 |
+
max-width: 1200px;
|
36 |
+
margin: 2em auto;
|
37 |
+
padding: 0 1em;
|
38 |
+
gap: 2em;
|
39 |
+
}
|
40 |
+
main {
|
41 |
+
flex: 3;
|
42 |
+
}
|
43 |
+
aside {
|
44 |
+
flex: 1;
|
45 |
+
background-color: #ffffff;
|
46 |
+
border: 1px solid #dee2e6;
|
47 |
+
border-radius: 8px;
|
48 |
+
padding: 1em;
|
49 |
+
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
|
50 |
+
height: fit-content;
|
51 |
+
}
|
52 |
+
main img {
|
53 |
+
max-width: 100%;
|
54 |
+
height: auto;
|
55 |
+
display: block;
|
56 |
+
margin: 1.5em auto;
|
57 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
58 |
+
}
|
59 |
+
h1, h2, h3 {
|
60 |
+
color: #0d6efd;
|
61 |
+
}
|
62 |
+
a {
|
63 |
+
color: #0d6efd;
|
64 |
+
text-decoration: none;
|
65 |
+
}
|
66 |
+
a:hover {
|
67 |
+
text-decoration: underline;
|
68 |
+
}
|
69 |
+
code {
|
70 |
+
background: #e9ecef;
|
71 |
+
padding: 0.2em 0.4em;
|
72 |
+
border-radius: 4px;
|
73 |
+
font-family: monospace;
|
74 |
+
}
|
75 |
+
pre {
|
76 |
+
background: #e9ecef;
|
77 |
+
padding: 1em;
|
78 |
+
overflow-x: auto;
|
79 |
+
border-radius: 6px;
|
80 |
+
}
|
81 |
+
blockquote {
|
82 |
+
border-left: 4px solid #0d6efd;
|
83 |
+
padding-left: 1em;
|
84 |
+
color: #495057;
|
85 |
+
margin: 1em 0;
|
86 |
+
background: #f1f3f5;
|
87 |
+
}
|
88 |
+
</style>
|
89 |
+
</head>
|
90 |
+
<body>
|
91 |
+
<header>
|
92 |
+
<img src="https://via.placeholder.com/1280x720.png?text=AI+News+Analyzer" alt="health_2025-07-26 Banner">
|
93 |
+
</header>
|
94 |
+
<div class="container">
|
95 |
+
<main>
|
96 |
+
<h1 id="health-sector-value-investing-memo-week-of-july-24-2025">Health Sector Value Investing Memo – Week of July 24, 2025</h1>
|
97 |
+
<hr />
|
98 |
+
<h3 id="executive-summary">📌 Executive Summary</h3>
|
99 |
+
<ul>
|
100 |
+
<li><strong>Sentiment is mixed/neutral overall</strong>; most headlines reflect ongoing innovation, moderate but targeted funding, and a few strategic acquisitions, but there’s caution in public markets and ongoing pressure on healthcare costs.</li>
|
101 |
+
<li><strong>Risks:</strong> Regulatory/policy uncertainty, margin compression in incumbent insurers, and still-high valuations in certain subsectors (AI, digital health) temper any momentum.</li>
|
102 |
+
<li><strong>Catalysts:</strong> New leadership hires, large asset transactions (Labcorp), community and preventative health initiatives are active. Multiple startups are raising significant funding rounds, especially focused on <strong>AI in Medicaid enrollment</strong> and <strong>preventative care</strong>.</li>
|
103 |
+
<li><strong>Smart money appears focused</strong> on early-stage, tech-enabled healthcare solutions, especially in areas where legacy players struggle to innovate or scale.</li>
|
104 |
+
</ul>
|
105 |
+
<hr />
|
106 |
+
<h3 id="signals-and-analysis">📊 Signals and Analysis</h3>
|
107 |
+
<h4 id="1-vivalink-and-chcc-hospital-at-home-blueprint">1. <strong>Vivalink and CHCC: Hospital-at-Home Blueprint</strong></h4>
|
108 |
+
<ul>
|
109 |
+
<li><strong>What:</strong> Vivalink (remote patient monitoring devices) and Cleveland Clinic Health Center (CHCC) announced a blueprint for nationwide hospital-at-home services.</li>
|
110 |
+
<li><strong>Why:</strong> As hospitals look to control costs and expand capacity, home-based care could be a significant growth market; Vivalink is a small, private company competing with giants, but partnerships with brand-names are a strong moat signal. <a href="https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/">Vivalink and CHCC to Create National Hospital-at-Home Blueprint</a></li>
|
111 |
+
</ul>
|
112 |
+
<h4 id="2-fortuna-health-18m-series-a-led-by-a16z">2. <strong>Fortuna Health: $18M Series A Led by a16z</strong></h4>
|
113 |
+
<ul>
|
114 |
+
<li><strong>What:</strong> Raised $18M Series A (led by Andreessen Horowitz) to build AI-driven Medicaid enrollment tools. Investor syndicate includes notable names: Y Combinator, executives from DoorDash, One Medical, Oscar Health, and more.</li>
|
115 |
+
<li><strong>Why:</strong> Medicaid and government benefit navigation are large, under-digitized markets. With public and private pressure to expand coverage, adoption and monetization potential is high if tech execution is strong. <strong>Strong indication of smart money interest.</strong> <a href="https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment">Fortuna Health raises $18M to enhance AI for Medicaid enrollment</a></li>
|
116 |
+
</ul>
|
117 |
+
<h4 id="3-everlab-10m-preventative-care-funding">3. <strong>Everlab: $10M Preventative Care Funding</strong></h4>
|
118 |
+
<ul>
|
119 |
+
<li><strong>What:</strong> Everlab, a digital preventative care startup, raised $10M with credible backers (previous comparables include PeopleOne Health with $32.3M led by GV/Google Ventures).</li>
|
120 |
+
<li><strong>Why:</strong> Preventative care is moated by network effects and adoption difficulty; fresh capital suggests future scale-up and M&A potential. <a href="https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform">Everlab garners $10M for preventative care platform</a></li>
|
121 |
+
</ul>
|
122 |
+
<h4 id="4-labcorp-buys-community-health-lab-assets-195m">4. <strong>Labcorp Buys Community Health Lab Assets ($195M)</strong></h4>
|
123 |
+
<ul>
|
124 |
+
<li><strong>What:</strong> Labcorp (NYSE: LH) to acquire select Community Health outreach laboratory assets for $195M.</li>
|
125 |
+
<li><strong>Why:</strong> This acquisition consolidates Labcorp’s dominant position in lab services, potentially increasing <strong>margins and economies of scale</strong>. <a href="https://www.medtechdive.com/news/Labcorp-Community-Health-outreach-lab-acquisition/753883/">Labcorp to buy some Community Health assets for $195M</a></li>
|
126 |
+
</ul>
|
127 |
+
<h4 id="5-drfirst-new-ceo-laizer-kornwasser">5. <strong>DrFirst New CEO: Laizer Kornwasser</strong></h4>
|
128 |
+
<ul>
|
129 |
+
<li><strong>What:</strong> DrFirst, a health IT and e-prescribing provider, appointed Laizer Kornwasser as CEO.</li>
|
130 |
+
<li><strong>Why:</strong> Notable leadership change. Kornwasser’s connections (previously at Humana, Diplomat Pharmacy) may open new payer/provider channels and M&A activity. <a href="https://hitconsultant.net/2025/07/22/drfirst-appoints-laizer-kornwasser-as-ceo/">DrFirst Appoints Laizer Kornwasser as CEO</a></li>
|
131 |
+
</ul>
|
132 |
+
<h4 id="6-charta-health-22m-for-ai-ops">6. <strong>Charta Health: $22M for AI Ops</strong></h4>
|
133 |
+
<ul>
|
134 |
+
<li><strong>What:</strong> Raised $22M to build AI-powered backend healthcare ops. Founders have ex-Rockset/OpenAI pedigree.</li>
|
135 |
+
<li><strong>Why:</strong> Early-stage, but deep tech capability and OpenAI connections signal future "picks and shovels" for next-gen clinical systems. Watch for enterprise SaaS adoption rates. <a href="https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform">Charta Health raises $22M for AI healthcare operations platform</a></li>
|
136 |
+
</ul>
|
137 |
+
<h4 id="7-macro-signals-insurance-pressures-and-funding-flows">7. <strong>Macro Signals: Insurance Pressures and Funding Flows</strong></h4>
|
138 |
+
<ul>
|
139 |
+
<li><strong>Health insurer sentiment is negative</strong> as future regulatory/policy risks and cost challenges cloud earnings outlook—Moody's gives a sector-wide "negative" rating. <a href="https://www.newsweek.com/health-care-data-ceo-gets-real-about-wearables-access-health-2103576">Health Care Data CEO Gets Real About Wearables</a></li>
|
140 |
+
<li><strong>Digital health funding flows strongly toward AI/Medicaid</strong> and ops automation—suggesting higher future value may accrue to capital-light startups over lagging incumbents. <a href="https://www.modernhealthcare.com/health-tech/mh-digital-health-top-funding-absolutecare-aidoc/">Top digital health funding: Startups focus on AI, Medicaid</a></li>
|
141 |
+
</ul>
|
142 |
+
<hr />
|
143 |
+
<h3 id="investment-thesis">🧠 Investment Thesis</h3>
|
144 |
+
<h4 id="outlook-and-opportunity"><strong>Outlook and Opportunity</strong></h4>
|
145 |
+
<p><strong>Healthcare innovation remains robust</strong>, with early-stage private markets attracting smart money—especially toward AI-driven, operationally scalable startups mediating complex government/payor flows (Medicaid, insurance, preventative care).</p>
|
146 |
+
<ul>
|
147 |
+
<li><strong>Public markets:</strong> Cautiously neutral/bearish on established insurers and service providers (margin pressure, regulatory uncertainty). </li>
|
148 |
+
<li><strong>Small- and mid-cap "enablers" (testing, health tech SaaS, remote monitoring):</strong> Attractive if they show durable moats, recurring revenue, and prudent valuation.</li>
|
149 |
+
<li><strong>Startup arena (key focus):</strong> AI-in-Medicaid (Fortuna), preventative care (Everlab), AI healthcare ops (Charta), and digital clinical infrastructure (Vivalink) are top "watch" or "invest" candidates as funding and partnerships signal smart money rotation from legacy to tech-enabled plays.</li>
|
150 |
+
</ul>
|
151 |
+
<h4 id="riskreward"><strong>Risk/Reward</strong></h4>
|
152 |
+
<ul>
|
153 |
+
<li><strong>Risks:</strong> Regulatory changes (esp. Medicaid), tech execution, adoption speed, high valuations for some digital health names, failure to scale past early-stage funding.</li>
|
154 |
+
<li><strong>Rewards:</strong> Outsized growth in underpenetrated segments (Medicaid tech, remote/home care, AI health ops), potential for early liquidity via M&A/IPO if momentum persists.</li>
|
155 |
+
</ul>
|
156 |
+
<h4 id="key-themes"><strong>Key Themes</strong></h4>
|
157 |
+
<ul>
|
158 |
+
<li><strong>Smart money is moving into digital-first, operationally differentiated solutions.</strong></li>
|
159 |
+
<li><strong>Strategic M&A targets:</strong> Clinical infrastructure and preventative care platforms.</li>
|
160 |
+
<li><strong>Watch for partnerships with large health systems/payors as validation.</strong></li>
|
161 |
+
<li><strong>Leadership changes in key startups/health IT firms may drive accelerated business development and M&A interest.</strong></li>
|
162 |
+
</ul>
|
163 |
+
<hr />
|
164 |
+
<h2 id="stocks-or-startups-to-watch">🕵️♂️ <strong>Stocks or Startups to Watch</strong></h2>
|
165 |
+
<ol>
|
166 |
+
<li><strong>Labcorp (LH)</strong> – Strong FCF, reasonable P/E, proven M&A integration <a href="https://finance.yahoo.com/quote/LH/">Yahoo Finance: Labcorp (LH)</a></li>
|
167 |
+
<li><strong>Everlab</strong> – Watch for follow-on rounds, partnerships, or early commercial traction. <a href="https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform">Everlab garners $10M for preventative care platform</a></li>
|
168 |
+
<li><strong>Fortuna Health</strong> – Early leadership in Medicaid digitization; Andreessen Horowitz and top operator backing. <a href="https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment">Fortuna Health raises $18M to enhance AI for Medicaid enrollment</a></li>
|
169 |
+
<li><strong>Charta Health</strong> – Early, but strong tech DNA and ex-OpenAI founders suggest future moat. <a href="https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform">Charta Health raises $22M for AI healthcare operations platform</a></li>
|
170 |
+
<li><strong>Vivalink</strong> – Watch for further strategic partnerships or M&A; highly differentiated remote monitoring/data play. <a href="https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/">Vivalink and CHCC to Create National Hospital-at-Home Blueprint</a></li>
|
171 |
+
</ol>
|
172 |
+
<hr />
|
173 |
+
<h2 id="what-smart-money-might-be-acting-on">🧩 <strong>What Smart Money Might Be Acting On</strong></h2>
|
174 |
+
<ul>
|
175 |
+
<li>Funding migration to AI-driven Medicaid navigation, automation, and preventative care platforms (Fortuna, Everlab, Charta Health).</li>
|
176 |
+
<li>Strategic partnerships between innovative SMEs and major hospital systems (Vivalink/CHCC).</li>
|
177 |
+
<li>Select M&A for scalable, moat-like clinical assets (Labcorp).</li>
|
178 |
+
</ul>
|
179 |
+
<hr />
|
180 |
+
<h2 id="references">📚 References</h2>
|
181 |
+
<ol>
|
182 |
+
<li><a href="https://hitconsultant.net/2025/07/23/vivalink-and-chcc-to-create-national-hospital-at-home-blueprint/">Vivalink and CHCC to Create National Hospital-at-Home Blueprint</a></li>
|
183 |
+
<li><a href="https://www.mobihealthnews.com/news/fortuna-health-raises-18m-enhance-ai-medicaid-enrollment">Fortuna Health raises $18M to enhance AI for Medicaid enrollment</a></li>
|
184 |
+
<li><a href="https://www.mobihealthnews.com/news/everlab-garners-10m-preventative-care-platform">Everlab garners $10M for preventative care platform</a></li>
|
185 |
+
<li><a href="https://www.medtechdive.com/news/Labcorp-Community-Health-outreach-lab-acquisition/753883/">Labcorp to buy some Community Health assets for $195M</a></li>
|
186 |
+
<li><a href="https://hitconsultant.net/2025/07/22/drfirst-appoints-laizer-kornwasser-as-ceo/">DrFirst Appoints Laizer Kornwasser as CEO</a></li>
|
187 |
+
<li><a href="https://www.mobihealthnews.com/news/charta-health-raises-22m-ai-healthcare-operations-platform">Charta Health raises $22M for AI healthcare operations platform</a></li>
|
188 |
+
<li><a href="https://www.modernhealthcare.com/health-tech/mh-digital-health-top-funding-absolutecare-aidoc/">Top digital health funding: Startups focus on AI, Medicaid</a></li>
|
189 |
+
<li><a href="https://www.newsweek.com/health-care-data-ceo-gets-real-about-wearables-access-health-2103576">Health Care Data CEO Gets Real About Wearables</a></li>
|
190 |
+
<li><a href="https://finance.yahoo.com/quote/LH/">Yahoo Finance: Labcorp (LH)</a></li>
|
191 |
+
</ol>
|
192 |
+
<hr />
|
193 |
+
<h3 id="investment-hypothesis-actionable">🚦 <strong>Investment Hypothesis (Actionable)</strong></h3>
|
194 |
+
<p><strong>Watch or accumulate positions in "picks-and-shovels" healthcare enablers (Labcorp) and continue to monitor early-stage AI/Medicaid and preventative care startups entering scale-up phase.</strong> Leadership changes and institutional VC backing in the sector suggest further catalyst events ahead. Beware of overextension/valuation in digital health; focus on demonstrated moats, partnerships, and cash flow resilience. Risk/reward presently skews in favor of smartly selected innovators over entrenched laggards.</p>
|
195 |
+
</main>
|
196 |
+
<aside>
|
197 |
+
<h3>🧠 Metrics</h3>
|
198 |
+
|
199 |
+
</aside>
|
200 |
+
</div>
|
201 |
+
</body>
|
202 |
+
</html>
|
203 |
+
|
src/main.py
CHANGED
@@ -62,12 +62,13 @@ def run_value_investing_analysis(csv_path, progress_callback=None):
|
|
62 |
result = analyze_article(summary)
|
63 |
sentiment = result.get("sentiment", "Neutral")
|
64 |
confidence = float(result.get("confidence", 0.0))
|
|
|
65 |
if progress_callback:
|
66 |
-
progress_callback(f"📰 [{title[:50]}...] → Sentiment: {sentiment}, Confidence: {confidence}")
|
67 |
except Exception as e:
|
68 |
if progress_callback:
|
69 |
progress_callback(f"[FinBERT ERROR] {e}")
|
70 |
-
sentiment, confidence = "Neutral", 0.0
|
71 |
|
72 |
priority = derive_priority(sentiment, confidence)
|
73 |
|
@@ -76,16 +77,19 @@ def run_value_investing_analysis(csv_path, progress_callback=None):
|
|
76 |
"URL": url,
|
77 |
"Summary": summary[:300] + "..." if summary else "",
|
78 |
"Priority": priority,
|
79 |
-
"Date": date,
|
80 |
"Sentiment": sentiment,
|
81 |
-
"Confidence": confidence
|
|
|
|
|
82 |
})
|
83 |
|
84 |
company_data.append({
|
85 |
"Company": topic,
|
86 |
"Sentiment": sentiment,
|
87 |
"Confidence": confidence,
|
|
|
88 |
"Summary": summary,
|
|
|
89 |
})
|
90 |
|
91 |
try:
|
@@ -109,17 +113,19 @@ def build_company_insights(company_data):
|
|
109 |
insights = []
|
110 |
for company, group in df.groupby("Company"):
|
111 |
mentions = len(group)
|
112 |
-
|
113 |
avg_confidence = round(group["Confidence"].mean(), 2)
|
|
|
114 |
highlights = " | ".join(group["Summary"].head(2).tolist())
|
115 |
insights.append({
|
116 |
"Company": company,
|
117 |
"Mentions": mentions,
|
118 |
-
"
|
119 |
-
"Confidence": avg_confidence,
|
|
|
120 |
"Highlights": highlights
|
121 |
})
|
122 |
-
return pd.DataFrame(insights).sort_values(by="Confidence", ascending=False).head(5)
|
123 |
|
124 |
# === Pipeline ===
|
125 |
def run_pipeline(csv_path, tavily_api_key, progress_callback=None):
|
@@ -136,161 +142,142 @@ def run_pipeline(csv_path, tavily_api_key, progress_callback=None):
|
|
136 |
insights_df = build_company_insights(company_data)
|
137 |
return html_paths, articles_df, insights_df
|
138 |
|
|
|
139 |
# import os
|
140 |
# import pandas as pd
|
141 |
# from datetime import datetime
|
142 |
# from dotenv import load_dotenv
|
143 |
-
# import traceback
|
144 |
-
|
145 |
# from md_html import convert_single_md_to_html as convert_md_to_html
|
146 |
# from news_analysis import fetch_deep_news, generate_value_investor_report
|
147 |
-
# from csv_utils import detect_changes
|
148 |
# from fin_interpreter import analyze_article
|
149 |
|
150 |
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
151 |
# DATA_DIR = os.path.join(BASE_DIR, "data")
|
152 |
# HTML_DIR = os.path.join(BASE_DIR, "html")
|
153 |
-
# CSV_PATH = os.path.join(BASE_DIR, "investing_topics.csv")
|
154 |
|
155 |
# os.makedirs(DATA_DIR, exist_ok=True)
|
156 |
# os.makedirs(HTML_DIR, exist_ok=True)
|
157 |
|
158 |
# load_dotenv()
|
159 |
|
160 |
-
|
161 |
-
# def
|
162 |
-
#
|
163 |
-
#
|
164 |
-
#
|
165 |
-
# >
|
166 |
-
#
|
167 |
-
# >
|
168 |
-
# ""
|
169 |
-
|
170 |
-
|
|
|
171 |
# def run_value_investing_analysis(csv_path, progress_callback=None):
|
172 |
-
# """
|
173 |
-
# Runs the analysis for all topics in the CSV.
|
174 |
-
# Returns:
|
175 |
-
# md_files (list of md file paths)
|
176 |
-
# all_articles (list of article dicts)
|
177 |
-
# """
|
178 |
# current_df = pd.read_csv(csv_path)
|
179 |
-
# prev_path = os.path.join(BASE_DIR, "investing_topics_prev.csv")
|
180 |
-
|
181 |
-
# if os.path.exists(prev_path):
|
182 |
-
# previous_df = pd.read_csv(prev_path)
|
183 |
-
# changed_df = detect_changes(current_df, previous_df)
|
184 |
-
# if changed_df.empty:
|
185 |
-
# if progress_callback:
|
186 |
-
# progress_callback("✅ No changes detected. Skipping processing.")
|
187 |
-
# return [], []
|
188 |
-
# else:
|
189 |
-
# changed_df = current_df
|
190 |
-
|
191 |
-
# new_md_files = []
|
192 |
# all_articles = []
|
|
|
193 |
|
194 |
-
# for _, row in
|
195 |
# topic = row.get("topic")
|
196 |
# timespan = row.get("timespan_days", 7)
|
197 |
-
# msg = f"🔍 Processing: {topic} ({timespan} days)"
|
198 |
-
# print(msg)
|
199 |
# if progress_callback:
|
200 |
-
# progress_callback(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
|
202 |
-
# news = fetch_deep_news(topic, timespan)
|
203 |
# if not news:
|
204 |
-
# warning = f"⚠️ No news found for: {topic}"
|
205 |
-
# print(warning)
|
206 |
# if progress_callback:
|
207 |
-
# progress_callback(
|
208 |
# continue
|
209 |
|
210 |
-
# # Add articles to all_articles
|
211 |
# for article in news:
|
|
|
|
|
|
|
|
|
|
|
212 |
# try:
|
213 |
-
#
|
214 |
-
#
|
215 |
-
#
|
216 |
-
#
|
217 |
-
#
|
218 |
-
# else:
|
219 |
-
# sentiment, confidence, signal = res[0], res[1], res[2]
|
220 |
# except Exception as e:
|
221 |
-
#
|
222 |
-
#
|
|
|
|
|
|
|
223 |
|
224 |
# all_articles.append({
|
225 |
-
# "Title":
|
226 |
-
# "URL":
|
227 |
-
# "Summary":
|
228 |
-
# "Priority":
|
229 |
-
# "Date":
|
230 |
-
# "Company": article.get("company", topic),
|
231 |
# "Sentiment": sentiment,
|
232 |
-
# "Confidence": confidence
|
233 |
-
# "Signal": signal
|
234 |
# })
|
235 |
|
236 |
-
#
|
237 |
-
#
|
238 |
-
#
|
239 |
-
#
|
|
|
|
|
240 |
|
241 |
-
#
|
242 |
-
#
|
243 |
-
#
|
244 |
-
# while os.path.exists(filepath):
|
245 |
-
# filename = f"{topic.replace(' ', '_').lower()}_{datetime.now().strftime('%Y-%m-%d')}_{counter}.md"
|
246 |
# filepath = os.path.join(DATA_DIR, filename)
|
247 |
-
#
|
248 |
-
|
249 |
-
#
|
250 |
-
#
|
|
|
251 |
|
252 |
-
#
|
253 |
|
254 |
-
#
|
255 |
-
#
|
256 |
-
#
|
257 |
-
#
|
258 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
|
|
260 |
# def run_pipeline(csv_path, tavily_api_key, progress_callback=None):
|
261 |
# os.environ["TAVILY_API_KEY"] = tavily_api_key
|
|
|
262 |
|
263 |
-
#
|
264 |
-
#
|
265 |
-
#
|
266 |
-
#
|
267 |
-
#
|
268 |
-
# new_html_paths.append(html_path)
|
269 |
|
270 |
# articles_df = pd.DataFrame(all_articles)
|
271 |
-
# insights_df = build_company_insights(
|
272 |
-
# return
|
273 |
-
|
274 |
-
|
275 |
-
# def build_company_insights(articles_df):
|
276 |
-
# if articles_df.empty:
|
277 |
-
# return pd.DataFrame()
|
278 |
-
# grouped = (
|
279 |
-
# articles_df.groupby("Company")
|
280 |
-
# .agg({
|
281 |
-
# "Title": "count",
|
282 |
-
# "Sentiment": lambda x: x.mode()[0] if not x.mode().empty else "Neutral",
|
283 |
-
# "Signal": lambda x: x.mode()[0] if not x.mode().empty else "Watch"
|
284 |
-
# })
|
285 |
-
# .reset_index()
|
286 |
-
# .rename(columns={"Title": "Mentions"})
|
287 |
-
# )
|
288 |
-
# return grouped
|
289 |
-
|
290 |
-
|
291 |
-
# if __name__ == "__main__":
|
292 |
-
# md_files, _ = run_value_investing_analysis(CSV_PATH)
|
293 |
-
# for md in md_files:
|
294 |
-
# convert_md_to_html(md, HTML_DIR)
|
295 |
-
# print(f"🌐 All reports converted to HTML at: {HTML_DIR}")
|
296 |
|
|
|
62 |
result = analyze_article(summary)
|
63 |
sentiment = result.get("sentiment", "Neutral")
|
64 |
confidence = float(result.get("confidence", 0.0))
|
65 |
+
signal = result.get("investment_decision", "Watch")
|
66 |
if progress_callback:
|
67 |
+
progress_callback(f"📰 [{title[:50]}...] → Sentiment: {sentiment}, Confidence: {confidence}, Signal: {signal}")
|
68 |
except Exception as e:
|
69 |
if progress_callback:
|
70 |
progress_callback(f"[FinBERT ERROR] {e}")
|
71 |
+
sentiment, confidence, signal = "Neutral", 0.0, "Watch"
|
72 |
|
73 |
priority = derive_priority(sentiment, confidence)
|
74 |
|
|
|
77 |
"URL": url,
|
78 |
"Summary": summary[:300] + "..." if summary else "",
|
79 |
"Priority": priority,
|
|
|
80 |
"Sentiment": sentiment,
|
81 |
+
"Confidence": confidence,
|
82 |
+
"Signal": signal,
|
83 |
+
"Date": date
|
84 |
})
|
85 |
|
86 |
company_data.append({
|
87 |
"Company": topic,
|
88 |
"Sentiment": sentiment,
|
89 |
"Confidence": confidence,
|
90 |
+
"Signal": signal,
|
91 |
"Summary": summary,
|
92 |
+
"Priority": priority
|
93 |
})
|
94 |
|
95 |
try:
|
|
|
113 |
insights = []
|
114 |
for company, group in df.groupby("Company"):
|
115 |
mentions = len(group)
|
116 |
+
dominant_signal = group["Signal"].mode()[0] if not group["Signal"].mode().empty else "Watch"
|
117 |
avg_confidence = round(group["Confidence"].mean(), 2)
|
118 |
+
high_priority_ratio = round((group['Priority'] == 'High').sum() / len(group) * 100, 1)
|
119 |
highlights = " | ".join(group["Summary"].head(2).tolist())
|
120 |
insights.append({
|
121 |
"Company": company,
|
122 |
"Mentions": mentions,
|
123 |
+
"Dominant Signal": dominant_signal,
|
124 |
+
"Avg Confidence": avg_confidence,
|
125 |
+
"Interest % (High Priority)": f"{high_priority_ratio}%",
|
126 |
"Highlights": highlights
|
127 |
})
|
128 |
+
return pd.DataFrame(insights).sort_values(by="Avg Confidence", ascending=False).head(5)
|
129 |
|
130 |
# === Pipeline ===
|
131 |
def run_pipeline(csv_path, tavily_api_key, progress_callback=None):
|
|
|
142 |
insights_df = build_company_insights(company_data)
|
143 |
return html_paths, articles_df, insights_df
|
144 |
|
145 |
+
|
146 |
# import os
|
147 |
# import pandas as pd
|
148 |
# from datetime import datetime
|
149 |
# from dotenv import load_dotenv
|
|
|
|
|
150 |
# from md_html import convert_single_md_to_html as convert_md_to_html
|
151 |
# from news_analysis import fetch_deep_news, generate_value_investor_report
|
|
|
152 |
# from fin_interpreter import analyze_article
|
153 |
|
154 |
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
155 |
# DATA_DIR = os.path.join(BASE_DIR, "data")
|
156 |
# HTML_DIR = os.path.join(BASE_DIR, "html")
|
|
|
157 |
|
158 |
# os.makedirs(DATA_DIR, exist_ok=True)
|
159 |
# os.makedirs(HTML_DIR, exist_ok=True)
|
160 |
|
161 |
# load_dotenv()
|
162 |
|
163 |
+
# # === Priority Logic ===
|
164 |
+
# def derive_priority(sentiment, confidence):
|
165 |
+
# sentiment = sentiment.lower()
|
166 |
+
# if sentiment == "positive" and confidence > 0.7:
|
167 |
+
# return "High"
|
168 |
+
# if sentiment == "negative" and confidence > 0.6:
|
169 |
+
# return "High"
|
170 |
+
# if confidence > 0.5:
|
171 |
+
# return "Medium"
|
172 |
+
# return "Low"
|
173 |
+
|
174 |
+
# # === Main Analysis ===
|
175 |
# def run_value_investing_analysis(csv_path, progress_callback=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
# current_df = pd.read_csv(csv_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
# all_articles = []
|
178 |
+
# company_data = []
|
179 |
|
180 |
+
# for _, row in current_df.iterrows():
|
181 |
# topic = row.get("topic")
|
182 |
# timespan = row.get("timespan_days", 7)
|
|
|
|
|
183 |
# if progress_callback:
|
184 |
+
# progress_callback(f"🔍 Processing topic: {topic} ({timespan} days)")
|
185 |
+
|
186 |
+
# try:
|
187 |
+
# news = fetch_deep_news(topic, timespan)
|
188 |
+
# if progress_callback:
|
189 |
+
# progress_callback(f"[DEBUG] fetch_deep_news returned {len(news) if news else 0} articles.")
|
190 |
+
# except Exception as e:
|
191 |
+
# if progress_callback:
|
192 |
+
# progress_callback(f"[ERROR] fetch_deep_news failed: {e}")
|
193 |
+
# continue
|
194 |
|
|
|
195 |
# if not news:
|
|
|
|
|
196 |
# if progress_callback:
|
197 |
+
# progress_callback(f"⚠️ No news found for topic: {topic}")
|
198 |
# continue
|
199 |
|
|
|
200 |
# for article in news:
|
201 |
+
# summary = article.get("summary", "") or article.get("content", "")
|
202 |
+
# title = article.get("title", "Untitled")
|
203 |
+
# url = article.get("url", "")
|
204 |
+
# date = article.get("date", datetime.now().strftime("%Y-%m-%d"))
|
205 |
+
|
206 |
# try:
|
207 |
+
# result = analyze_article(summary)
|
208 |
+
# sentiment = result.get("sentiment", "Neutral")
|
209 |
+
# confidence = float(result.get("confidence", 0.0))
|
210 |
+
# if progress_callback:
|
211 |
+
# progress_callback(f"📰 [{title[:50]}...] → Sentiment: {sentiment}, Confidence: {confidence}")
|
|
|
|
|
212 |
# except Exception as e:
|
213 |
+
# if progress_callback:
|
214 |
+
# progress_callback(f"[FinBERT ERROR] {e}")
|
215 |
+
# sentiment, confidence = "Neutral", 0.0
|
216 |
+
|
217 |
+
# priority = derive_priority(sentiment, confidence)
|
218 |
|
219 |
# all_articles.append({
|
220 |
+
# "Title": title,
|
221 |
+
# "URL": url,
|
222 |
+
# "Summary": summary[:300] + "..." if summary else "",
|
223 |
+
# "Priority": priority,
|
224 |
+
# "Date": date,
|
|
|
225 |
# "Sentiment": sentiment,
|
226 |
+
# "Confidence": confidence
|
|
|
227 |
# })
|
228 |
|
229 |
+
# company_data.append({
|
230 |
+
# "Company": topic,
|
231 |
+
# "Sentiment": sentiment,
|
232 |
+
# "Confidence": confidence,
|
233 |
+
# "Summary": summary,
|
234 |
+
# })
|
235 |
|
236 |
+
# try:
|
237 |
+
# report_body = generate_value_investor_report(topic, news)
|
238 |
+
# filename = f"{topic.replace(' ', '_').lower()}_{datetime.now().strftime('%Y-%m-%d')}.md"
|
|
|
|
|
239 |
# filepath = os.path.join(DATA_DIR, filename)
|
240 |
+
# with open(filepath, "w", encoding="utf-8") as f:
|
241 |
+
# f.write(report_body)
|
242 |
+
# except Exception as e:
|
243 |
+
# if progress_callback:
|
244 |
+
# progress_callback(f"[REPORT ERROR] {e}")
|
245 |
|
246 |
+
# return all_articles, company_data
|
247 |
|
248 |
+
# # === Insights Tab Data ===
|
249 |
+
# def build_company_insights(company_data):
|
250 |
+
# if not company_data:
|
251 |
+
# return pd.DataFrame()
|
252 |
|
253 |
+
# df = pd.DataFrame(company_data)
|
254 |
+
# insights = []
|
255 |
+
# for company, group in df.groupby("Company"):
|
256 |
+
# mentions = len(group)
|
257 |
+
# dominant_sentiment = group["Sentiment"].mode()[0] if not group["Sentiment"].mode().empty else "Neutral"
|
258 |
+
# avg_confidence = round(group["Confidence"].mean(), 2)
|
259 |
+
# highlights = " | ".join(group["Summary"].head(2).tolist())
|
260 |
+
# insights.append({
|
261 |
+
# "Company": company,
|
262 |
+
# "Mentions": mentions,
|
263 |
+
# "Sentiment": dominant_sentiment,
|
264 |
+
# "Confidence": avg_confidence,
|
265 |
+
# "Highlights": highlights
|
266 |
+
# })
|
267 |
+
# return pd.DataFrame(insights).sort_values(by="Confidence", ascending=False).head(5)
|
268 |
|
269 |
+
# # === Pipeline ===
|
270 |
# def run_pipeline(csv_path, tavily_api_key, progress_callback=None):
|
271 |
# os.environ["TAVILY_API_KEY"] = tavily_api_key
|
272 |
+
# all_articles, company_data = run_value_investing_analysis(csv_path, progress_callback)
|
273 |
|
274 |
+
# html_paths = []
|
275 |
+
# for md_file in os.listdir(DATA_DIR):
|
276 |
+
# if md_file.endswith(".md"):
|
277 |
+
# convert_md_to_html(os.path.join(DATA_DIR, md_file), HTML_DIR)
|
278 |
+
# html_paths.append(os.path.join(HTML_DIR, md_file.replace(".md", ".html")))
|
|
|
279 |
|
280 |
# articles_df = pd.DataFrame(all_articles)
|
281 |
+
# insights_df = build_company_insights(company_data)
|
282 |
+
# return html_paths, articles_df, insights_df
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
|