import { useState, useEffect, useCallback } from 'react';
export interface WhaleInsider {
marketId: string;
question: string | null;
slug: string | null;
address: string;
outcome: string; // 'Yes' | 'No' — the side the whale bought
amountUsd: number;
avgPrice: number; // 0..1 volume-weighted entry of the whale
currentPrice: number | null; // 0..1 current price of that side
lastTradeAt: string | null;
winRate: number | null; // 0..1 whale's positive-resolution win rate
closedPositions: number | null;
pnl7d: number | null;
}
interface Options { hours?: number; minAmount?: number; limit?: number; }
// Fresh BUYs by quality whales ("smart money just entered"). One row per
// (market, whale, side). Backed by /api/signals/whales/insider.
export function useWhaleInsider(options: Options = {}) {
const { hours = 24, minAmount = 5000, limit = 40 } = options;
const [rows, setRows] = useState<WhaleInsider[]>([]);
const [loading, setLoading] = useState(true);
const fetchData = useCallback(async () => {
setLoading(true);
try {
const params = new URLSearchParams({ hours: String(hours), min_amount: String(minAmount), limit: String(limit) });
const res = await fetch(`/api/signals/whales/insider?${params}`);
const d = await res.json();
if (d.success) setRows(d.data ?? []);
} catch { /* ignore */ }
finally { setLoading(false); }
}, [hours, minAmount, limit]);
useEffect(() => {
const t = setTimeout(fetchData, 0);
const interval = setInterval(fetchData, 5 * 60_000);
return () => { clearTimeout(t); clearInterval(interval); };
}, [fetchData]);
return { rows, loading, refresh: fetchData };
}
📜 Git History
b9c19bfchore(poli): reconcile local Flow/Insider/manual-trade work with deployed state3 days ago
Show last diff
Loading...