feat: add Citations and WatchlistChat components, integrate with API
- Implemented Citations component to display citation data. - Created WatchlistDrawer and ChatSidebar components for managing watchlists and AI chat functionality. - Integrated API calls for watchlist management and chat interactions. - Updated index.tsx to include new components in the main application layout. - Added API client in lib/api.ts for structured API interactions. - Developed Alerts, Dashboard, Portfolio, Routines, Screener, and Report pages with relevant data fetching and UI components. - Introduced styles in tokens.css for consistent theming across the application. - Configured TypeScript and Vite for project setup and development.
This commit is contained in:
1 parent
0db2cf28b3
commit
8c184ccae1
111 files changed
+12349
-62
No files matched your search
@@ -0,0 +1,76 @@
|
||||
package alerts
|
||||
|
||||
import "testing"
|
||||
|
||||
// Accumulation fixture: 3 brokers net-buy + 1.6x volume fires.
|
||||
func TestAccumulationFires(t *testing.T) {
|
||||
nets := map[string]float64{"MG": 5e11, "AK": 4e11, "CC": 3e11, "BK": -1e11}
|
||||
f, ok := Accumulation("BBCA", nets, 1.6)
|
||||
if !ok {
|
||||
t.Fatal("want accumulation fire")
|
||||
}
|
||||
if f.Rule != RuleAccumulation {
|
||||
t.Fatalf("rule = %s", f.Rule)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccumulationSilent(t *testing.T) {
|
||||
nets := map[string]float64{"MG": 5e11, "BK": -4e11}
|
||||
if _, ok := Accumulation("BBCA", nets, 1.1); ok {
|
||||
t.Fatal("want silence: only 1 net-buy broker, low volume")
|
||||
}
|
||||
}
|
||||
|
||||
// Foreign reversal: 5d outflow then strong inflow fires.
|
||||
func TestForeignReversal(t *testing.T) {
|
||||
last6 := []float64{-1e11, -1e11, -1e11, -1e11, -1e11, 3.4e11}
|
||||
if _, ok := ForeignReversal("BBCA", last6); !ok {
|
||||
t.Fatal("want reversal fire")
|
||||
}
|
||||
if _, ok := ForeignReversal("BBCA", []float64{1e11, 1e11}); ok {
|
||||
t.Fatal("want silence on short series")
|
||||
}
|
||||
}
|
||||
|
||||
// Insider spike both paths.
|
||||
func TestInsiderSpike(t *testing.T) {
|
||||
if _, ok := InsiderSpike("BBCA", 3e6, 1e6, 1); !ok {
|
||||
t.Fatal("want volume-path fire")
|
||||
}
|
||||
if _, ok := InsiderSpike("BBCA", 0, 0, 3); !ok {
|
||||
t.Fatal("want cluster-path fire")
|
||||
}
|
||||
if _, ok := InsiderSpike("BBCA", 1e6, 1e6, 1); ok {
|
||||
t.Fatal("want silence")
|
||||
}
|
||||
}
|
||||
|
||||
// Unusual volume suppressed on earnings dates.
|
||||
func TestUnusualVolume(t *testing.T) {
|
||||
if _, ok := UnusualVolume("BBCA", "2026-09-11", 3.2, false); !ok {
|
||||
t.Fatal("want fire")
|
||||
}
|
||||
if _, ok := UnusualVolume("BBCA", "2026-09-11", 3.2, true); ok {
|
||||
t.Fatal("want silence on earnings date")
|
||||
}
|
||||
}
|
||||
|
||||
// Rotation sign flip.
|
||||
func TestRotation(t *testing.T) {
|
||||
if _, ok := SectorRotation("consumer", -3e8, 1.1e9); !ok {
|
||||
t.Fatal("want rotation fire")
|
||||
}
|
||||
if _, ok := SectorRotation("banks", 1e9, 2e9); ok {
|
||||
t.Fatal("want silence without flip")
|
||||
}
|
||||
}
|
||||
|
||||
// Suspension watch: watchlist fires, others silent.
|
||||
func TestSuspension(t *testing.T) {
|
||||
if _, ok := SuspensionWatch("TLKM", "2026-09-10", "volatilitas", true); !ok {
|
||||
t.Fatal("want fire on watchlist")
|
||||
}
|
||||
if _, ok := SuspensionWatch("TLKM", "2026-09-10", "volatilitas", false); ok {
|
||||
t.Fatal("want silence off-watchlist")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user