← back to Bertha
chore(alshi-dash): update 1 file (.js) [+256/-1]
fd178e43cbafc6bb0f04f95c72d93763a240fa2f · 2026-02-15 16:43:30 +0000 · DW Commit Agent
Files touched
Diff
commit fd178e43cbafc6bb0f04f95c72d93763a240fa2f
Author: DW Commit Agent <commit-agent@dw-agents.com>
Date: Sun Feb 15 16:43:30 2026 +0000
chore(alshi-dash): update 1 file (.js) [+256/-1]
---
kalshi-dash/server.js | 257 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 256 insertions(+), 1 deletion(-)
diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index b4c1cd9..2d123ad 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -1900,6 +1900,167 @@ async function scrapeMetaculus() {
}
}
+// ── PredictIt API (another prediction market for cross-reference) ──
+async function scrapePredictIt() {
+ try {
+ const controller = new AbortController();
+ setTimeout(() => controller.abort(), 8000);
+ const res = await fetch('https://www.predictit.org/api/marketdata/all/', {
+ signal: controller.signal,
+ headers: { 'User-Agent': 'Ken-Bot/1.0' }
+ });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return (data.markets || []).slice(0, 100).map(m => ({
+ title: m.name,
+ url: m.url || `https://www.predictit.org/markets/detail/${m.id}`,
+ score: Math.round((m.contracts?.[0]?.lastTradePrice || 0) * 100),
+ num_comments: m.contracts?.length || 0,
+ source: 'predictit',
+ extra: JSON.stringify({
+ contracts: (m.contracts || []).slice(0, 5).map(c => ({
+ name: c.name, lastPrice: c.lastTradePrice, bestBuy: c.bestBuyYesCost, bestSell: c.bestSellYesCost
+ }))
+ })
+ }));
+ } catch (e) {
+ console.log(`[Ken] PredictIt scrape failed: ${e.message}`);
+ return [];
+ }
+}
+
+// ── FRED Economic Data API (real economic indicators — no key needed for some endpoints) ──
+async function scrapeFredIndicators() {
+ const indicators = [
+ { series: 'CPIAUCSL', name: 'CPI Inflation' },
+ { series: 'UNRATE', name: 'Unemployment Rate' },
+ { series: 'GDP', name: 'GDP Growth' },
+ { series: 'FEDFUNDS', name: 'Federal Funds Rate' },
+ { series: 'T10Y2Y', name: '10Y-2Y Treasury Spread' },
+ { series: 'VIXCLS', name: 'VIX Volatility Index' },
+ { series: 'DGS10', name: '10-Year Treasury Yield' },
+ { series: 'DCOILWTICO', name: 'WTI Crude Oil Price' },
+ ];
+ const results = [];
+ for (const ind of indicators) {
+ try {
+ const controller = new AbortController();
+ setTimeout(() => controller.abort(), 5000);
+ const res = await fetch(`https://fred.stlouisfed.org/graph/fredgraph.csv?id=${ind.series}&cosd=${new Date(Date.now() - 90*86400000).toISOString().split('T')[0]}`, {
+ signal: controller.signal,
+ headers: { 'User-Agent': 'Ken-Bot/1.0' }
+ });
+ if (!res.ok) continue;
+ const csv = await res.text();
+ const lines = csv.trim().split('\n');
+ if (lines.length < 2) continue;
+ const lastLine = lines[lines.length - 1];
+ const [date, value] = lastLine.split(',');
+ if (value && value !== '.') {
+ results.push({
+ title: `${ind.name}: ${value} (${date})`,
+ url: `https://fred.stlouisfed.org/series/${ind.series}`,
+ score: Math.round(parseFloat(value) * 100) || 0,
+ source: 'fred_economic',
+ keyword: ind.series,
+ });
+ }
+ } catch {}
+ }
+ return results;
+}
+
+// ── NWS Active Weather Alerts (real severe weather data for weather markets) ──
+async function scrapeNWSAlerts() {
+ try {
+ const controller = new AbortController();
+ setTimeout(() => controller.abort(), 8000);
+ const res = await fetch('https://api.weather.gov/alerts/active?status=actual&message_type=alert&limit=50', {
+ signal: controller.signal,
+ headers: { 'User-Agent': 'Ken-Bot/1.0 (ken@designerwallcoverings.com)', 'Accept': 'application/geo+json' }
+ });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return (data.features || []).map(f => ({
+ title: `${f.properties.event}: ${f.properties.headline || f.properties.description?.substring(0, 200) || ''}`.substring(0, 500),
+ url: f.properties['@id'] || 'https://alerts.weather.gov',
+ score: f.properties.severity === 'Extreme' ? 100 : f.properties.severity === 'Severe' ? 75 : f.properties.severity === 'Moderate' ? 50 : 25,
+ num_comments: 0,
+ source: 'nws_alerts',
+ keyword: f.properties.event || 'weather',
+ }));
+ } catch (e) {
+ console.log(`[Ken] NWS Alerts failed: ${e.message}`);
+ return [];
+ }
+}
+
+// ── Congressional/Government Activity (GovTrack API) ──
+async function scrapeGovTrack() {
+ try {
+ const controller = new AbortController();
+ setTimeout(() => controller.abort(), 8000);
+ const res = await fetch('https://www.govtrack.us/api/v2/vote?order_by=-created&limit=20', {
+ signal: controller.signal,
+ headers: { 'User-Agent': 'Ken-Bot/1.0' }
+ });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return (data.objects || []).map(v => ({
+ title: `${v.chamber === 'senate' ? 'Senate' : 'House'} Vote: ${v.question || v.result || 'Unknown'}`.substring(0, 500),
+ url: `https://www.govtrack.us${v.link || ''}`,
+ score: v.total_plus || 0,
+ num_comments: v.total_minus || 0,
+ source: 'govtrack',
+ keyword: v.category || 'legislation',
+ }));
+ } catch (e) {
+ console.log(`[Ken] GovTrack failed: ${e.message}`);
+ return [];
+ }
+}
+
+// ── X/Twitter via Nitter instances (public, no auth needed) ──
+async function scrapeNitterTrending() {
+ const nitterInstances = [
+ 'https://nitter.poast.org',
+ 'https://nitter.privacydev.net',
+ 'https://nitter.cz',
+ ];
+ const searchTerms = ['kalshi', 'polymarket', 'prediction market', 'fed rate decision', 'hurricane season'];
+ const results = [];
+ for (const term of searchTerms) {
+ for (const instance of nitterInstances) {
+ try {
+ const controller = new AbortController();
+ setTimeout(() => controller.abort(), 6000);
+ const url = `${instance}/search?f=tweets&q=${encodeURIComponent(term)}&since=`;
+ const res = await fetch(url, { signal: controller.signal, headers: { 'User-Agent': 'Mozilla/5.0' } });
+ if (!res.ok) continue;
+ const html = await res.text();
+ // Extract tweet text from Nitter HTML
+ const tweetMatches = html.match(/<div class="tweet-content[^"]*"[^>]*>([\s\S]*?)<\/div>/g) || [];
+ for (const match of tweetMatches.slice(0, 5)) {
+ const text = match.replace(/<[^>]+>/g, '').trim().substring(0, 500);
+ if (text.length > 10) {
+ results.push({
+ title: text,
+ url: `${instance}/search?q=${encodeURIComponent(term)}`,
+ score: 0,
+ num_comments: 0,
+ source: 'twitter_nitter',
+ keyword: term,
+ });
+ }
+ }
+ break; // One working instance per term is enough
+ } catch {} // Nitter instances are unreliable, fail silently
+ }
+ await new Promise(r => setTimeout(r, 2000));
+ }
+ return results;
+}
+
// ── Discord Bot Intelligence (reads messages from joined servers) ──
const DISCORD_BOT_TOKEN = 'MTQ3MjYyNDg2OTk3NDg2ODA2Mg.GifeyF.C5l9KqQUia-Ex54Ldg23fuxislxwf2QtmkXYII';
const DISCORD_API = 'https://discord.com/api/v10';
@@ -2384,6 +2545,100 @@ async function redditIntelligenceLoop() {
totalPosts += tvTotal + lemmyTotal + lobstersTotal + tildesTotal + bskyTotal;
totalPosts += manifoldTotal + predMarketRedditTotal;
+ // ── PredictIt (cross-reference prediction market) ──
+ let predictItTotal = 0;
+ try {
+ const piMarkets = await scrapePredictIt();
+ for (const m of piMarkets) {
+ const sentiment = scoreSentiment(m.title);
+ await kenQ(`
+ INSERT INTO ken_sentiment (source, subreddit, keyword, post_title, post_url, score, num_comments, sentiment_score, raw_text)
+ VALUES ('predictit', 'predictit', 'market', $1, $2, $3, $4, $5, $6)
+ ON CONFLICT DO NOTHING
+ `, [m.title, m.url, m.score, m.num_comments || 0, sentiment, m.extra || '']);
+ predictItTotal++;
+ }
+ totalPosts += predictItTotal;
+ console.log(`[Ken] PredictIt: ${predictItTotal} markets`);
+ } catch (e) {
+ console.log(`[Ken] PredictIt failed: ${e.message}`);
+ }
+
+ // ── FRED Economic Indicators (real data for economic markets) ──
+ let fredTotal = 0;
+ try {
+ const fredData = await scrapeFredIndicators();
+ for (const ind of fredData) {
+ await kenQ(`
+ INSERT INTO ken_sentiment (source, subreddit, keyword, post_title, post_url, score, sentiment_score, raw_text)
+ VALUES ('fred_economic', 'fred', $1, $2, $3, $4, 0, '')
+ ON CONFLICT DO NOTHING
+ `, [ind.keyword, ind.title, ind.url, ind.score]);
+ fredTotal++;
+ }
+ totalPosts += fredTotal;
+ console.log(`[Ken] FRED Economic: ${fredTotal} indicators`);
+ } catch (e) {
+ console.log(`[Ken] FRED failed: ${e.message}`);
+ }
+
+ // ── NWS Active Weather Alerts (severe weather data for weather markets) ──
+ let nwsAlertTotal = 0;
+ try {
+ const alerts = await scrapeNWSAlerts();
+ for (const alert of alerts) {
+ const sentiment = scoreSentiment(alert.title);
+ await kenQ(`
+ INSERT INTO ken_sentiment (source, subreddit, keyword, post_title, post_url, score, num_comments, sentiment_score, raw_text)
+ VALUES ('nws_alerts', 'weather', $1, $2, $3, $4, 0, $5, '')
+ ON CONFLICT DO NOTHING
+ `, [alert.keyword, alert.title, alert.url, alert.score, sentiment]);
+ nwsAlertTotal++;
+ }
+ totalPosts += nwsAlertTotal;
+ console.log(`[Ken] NWS Alerts: ${nwsAlertTotal} active alerts`);
+ } catch (e) {
+ console.log(`[Ken] NWS Alerts failed: ${e.message}`);
+ }
+
+ // ── GovTrack Congressional Votes (legislation for political markets) ──
+ let govTrackTotal = 0;
+ try {
+ const votes = await scrapeGovTrack();
+ for (const v of votes) {
+ const sentiment = scoreSentiment(v.title);
+ await kenQ(`
+ INSERT INTO ken_sentiment (source, subreddit, keyword, post_title, post_url, score, num_comments, sentiment_score, raw_text)
+ VALUES ('govtrack', 'congress', $1, $2, $3, $4, $5, $6, '')
+ ON CONFLICT DO NOTHING
+ `, [v.keyword, v.title, v.url, v.score, v.num_comments || 0, sentiment]);
+ govTrackTotal++;
+ }
+ totalPosts += govTrackTotal;
+ console.log(`[Ken] GovTrack: ${govTrackTotal} congressional votes`);
+ } catch (e) {
+ console.log(`[Ken] GovTrack failed: ${e.message}`);
+ }
+
+ // ── Twitter/X via Nitter (public sentiment, no auth needed) ──
+ let nitterTotal = 0;
+ try {
+ const tweets = await scrapeNitterTrending();
+ for (const t of tweets) {
+ const sentiment = scoreSentiment(t.title);
+ await kenQ(`
+ INSERT INTO ken_sentiment (source, subreddit, keyword, post_title, post_url, score, num_comments, sentiment_score, raw_text)
+ VALUES ('twitter_nitter', 'twitter', $1, $2, $3, 0, 0, $4, '')
+ ON CONFLICT DO NOTHING
+ `, [t.keyword, t.title, t.url, sentiment]);
+ nitterTotal++;
+ }
+ totalPosts += nitterTotal;
+ console.log(`[Ken] Twitter/Nitter: ${nitterTotal} tweets`);
+ } catch (e) {
+ console.log(`[Ken] Twitter/Nitter failed: ${e.message}`);
+ }
+
// ── Discord (Kalshi, Polymarket, Prediction Markets servers) ──
let discordTotal = 0;
try {
@@ -2408,7 +2663,7 @@ async function redditIntelligenceLoop() {
}
if (global.gc) global.gc();
- console.log(`[Ken] ═══ FULL SWEEP: ${totalPosts} items (Reddit, HN, ${NEWS_FEEDS.length} feeds, TV, YT, Manifold, r/Kalshi, r/Polymarket, Lemmy, Lobsters, Tildes, Bluesky, Mastodon, Metaculus, Discord) ═══`);
+ console.log(`[Ken] ═══ FULL SWEEP: ${totalPosts} items (Reddit, HN, ${NEWS_FEEDS.length} feeds, TV, YT, Manifold, r/Kalshi, r/Polymarket, Lemmy, Lobsters, Tildes, Bluesky, Mastodon, Metaculus, PredictIt, FRED, NWS Alerts, GovTrack, Twitter, Discord) ═══`);
return totalPosts;
} catch (e) {
console.error('[Ken] Intelligence sweep error:', e.message);
← 1d7b7c1 chore(alshi-dash): update 1 file (.js) [+218/-20]
·
back to Bertha
·
chore(alshi-dash,kalshi-dash): update 2 files (.html) [+563/ 1124be9 →