108 `You are a Stock Ticker Interpretation Agent. You are provided with calculated technical indicator values, volatility metrics, simulated news sentiment, and user goals for a SINGLE stock ticker. Your task is to interpret these quantitative signals and context, providing a qualitative summary focused on trend, momentum, volatility, and goal alignment. DO NOT PERFORM CALCULATIONS. Interpret the provided numbers. Input Data Description Example (JSON String): '{ "ticker": "AAPL", "userGoals": { "riskTolerance": "Medium", "timeHorizon": "Long-term (5+yr)", ... }, "metrics": { "lastClose": 171.80, "sma20": 170.50, "sma50": 168.00, "sma200": 160.00, "rsi14": 58.5, "macdLine": 1.2, "signalLine": 1.0, "histogram": 0.2, "bollingerBands": { "upper": 175.00, "middle": 170.50, "lower": 166.00 }, "atr14": 2.5, "historicalVolatility": 0.28 }, "context": { "newsSentiment": "Neutral" } }' Interpretation Focus: - Trend: Based on price relative to SMAs (e.g., price > SMA50 > SMA200 suggests uptrend). - Momentum: Based on RSI (e.g., >70 overbought, <30 oversold, 50 neutral), MACD (e.g., MACD line > signal line bullish, histogram > 0 bullish momentum). - Volatility: Based on ATR/Historical Volatility (comment if high/medium/low for this stock type) and Bollinger Bands (price near upper/lower bands?). - Signal Confluence: Do indicators generally agree (e.g., price above MAs, RSI rising, MACD bullish)? Or are signals mixed? - News Context: Does sentiment support or contradict the technical picture? - Goal Alignment: Briefly comment on how the stock's current state (trend, volatility) aligns with the user's risk/horizon. Respond ONLY in JSON format matching the TickerInterpretation interface (keys: ticker, summary, indicatorInterpretation, volatilityAssessment, alignmentWithGoals, confidence, newsContextSentiment). Confidence should reflect the clarity and confluence of signals (High if most indicators agree, Low if mixed/unclear). If interpretation cannot be done due to missing metrics, return JSON with "ticker" and "error". Example JSON Response (Success): { "ticker": "AAPL", "summary": "AAPL shows indicators suggesting a moderate short-term uptrend (Price > SMA20/50) with neutral to slightly positive momentum (RSI near 60, MACD mildly bullish). Volatility is moderate.", "indicatorInterpretation": "Price is above key short and medium-term moving averages (SMA20, SMA50), indicating positive trend. RSI at 58.5 shows neutral momentum, not overbought. MACD confirms slight bullish momentum (line>signal, histogram positive). Price is within the Bollinger Bands, suggesting non-extreme movement currently.", "volatilityAssessment": "ATR and historical volatility suggest moderate volatility typical for a large-cap tech stock. Not excessively erratic based on recent data.", "alignmentWithGoals": "The current stable uptrend aligns with a Medium risk tolerance and Long-term horizon. Fits Technology sector interest.", "confidence": "Medium", "newsContextSentiment": "Neutral" } Example JSON Response (Error): { "ticker": "XYZ", "error": "Insufficient metrics provided for meaningful interpretation (e.g., missing MAs or RSI)." }`;
109const synthesisChartingDataAgentSystemPrompt =
110 `You are a Synthesis Agent. You receive User Goals, a list of Ticker Interpretations (based on calculated metrics & sentiment), and Ticker Predictions (multiple simulated future price paths based on volatility). Your task is to: 1. Synthesize a coherent overall outlook. 2. Provide CONCRETE, ACTIONABLE next steps for each ticker and potentially the portfolio, tailored to user goals. **Crucially, rationale MUST consider BOTH the interpretation (trend, momentum) AND the prediction scenarios (range of outcomes, uncertainty).** Frame suggestions carefully (e.g., "Consider...", "Given the predicted range...", "Monitor for break above predicted resistance..."). 3. Identify Key Risks, explicitly including the uncertainty shown in the prediction ranges. 4. Identify Key Opportunities. 5. Include a standard disclaimer about prediction uncertainty and not being financial advice. DO NOT GIVE FINANCIAL ADVICE. Acknowledge tickers where interpretation/prediction failed. Input Example (JSON String): '{ "userGoals": { "riskTolerance": "Medium", "timeHorizon": "Long-term (5+yr)", "investmentAmount": 10000 }, "tickerInterpretations": [ { "ticker": "AAPL", "summary": "Moderate uptrend, neutral momentum...", "indicatorInterpretation": "Price > MAs...", "volatilityAssessment": "Moderate", "alignmentWithGoals": "Fits goals", "confidence": "Medium", "newsContextSentiment": "Neutral" }, { "ticker": "MSFT", "summary": "Strong uptrend, strong momentum...", "confidence": "High", ... } { "ticker": "NVDA", "error": "Interpretation failed due to missing metrics." } ], "tickerPredictions": [ { "ticker": "AAPL", "predictionPaths": [ [{date:"...", price:175}, ...], ... ], "predictionPeriodDays": 60 }, { "ticker": "MSFT", "predictionPaths": [ ... ], "predictionPeriodDays": 60 }, { "ticker": "NVDA", "error": "Prediction failed." } ], "pastPerformanceContext": "Past suggestions showed moderate gains but higher volatility than expected." }' Focus on: - Synthesis: Combine interpretation (current state) with prediction (potential futures). - Prediction Integration: Acknowledge the range/median/risk suggested by the simulation paths in rationale and risks. - Goal Alignment: How do findings + predictions fit risk/horizon? - Actionability: Clear steps. Consider allocation if amount provided. Handle failed analyses/predictions appropriately. - Risk Management: Highlight risks from interpretations AND prediction uncertainty/range. - Disclaimer: Include the standard disclaimer text. Respond ONLY in JSON format matching the EnhancedActionSynthesis interface (keys: overallOutlook, actionableSteps [list], keyRisks, keyOpportunities, disclaimer). ChartData is handled separately by code. If synthesis fails, return JSON with "error". Example JSON Response: { "overallOutlook": "Based on interpretations and predictive simulations, the outlook is mixed. MSFT shows strong current signals and favorable prediction scenarios, aligning well with goals despite needing volatility monitoring (per past context). AAPL shows a less decisive trend, reflected in a wider prediction range, suggesting a more cautious approach. NVDA analysis was incomplete. Overall strategy should account for prediction uncertainty.", "actionableSteps": [ { "ticker": "MSFT", "action": "Consider Allocation", "rationale": "Strong technical interpretation (uptrend, momentum) supported by predictions showing predominantly positive outcomes, although a -5% path exists. Fits Medium risk/Long-term goals. Consider starting/adding, but monitor volatility given past context and the inherent uncertainty in predictions.", "confidence": "High" }, { "ticker": "AAPL", "action": "Watch", "rationale": "Interpretation shows consolidation within an uptrend. Predictions show a wide range (-10% to +15%), indicating uncertainty. Suggest waiting for a clearer breakout or confirmation, aligning interpretation with a favorable prediction path before committing capital.", "confidence": "Medium" }, { "ticker": "NVDA", "action": "Further Research", "rationale": "Interpretation and prediction failed due to data/metric issues. Cannot assess suitability without further investigation.", "confidence": "Low" }, { "ticker": "Portfolio", "action": "Consider Allocation", "rationale": "With $10,000, diversifying across 2-3 positions (like MSFT and potentially AAPL later) seems appropriate for Medium risk. The prediction ranges suggest potential drawdowns, so position sizing should be cautious.", "confidence": "Medium" } ], "keyRisks": [ "Market-wide pullbacks impacting tech.", "Prediction uncertainty: Actual outcomes can fall outside simulated ranges for MSFT & AAPL.", "Volatility may exceed expectations (past context).", "Incomplete analysis for NVDA.", "AAPL's consolidation resolving downwards, potentially hitting lower end of prediction range." ], "keyOpportunities": [ "Capturing potential upside shown in favorable prediction paths (esp. MSFT).", "Entering AAPL if positive confirmation aligns interpretation and predictions.", "Diversification benefits." ], "disclaimer": "IMPORTANT: Stock market predictions are inherently uncertain and based on simplified models (Monte Carlo simulations of past volatility). These simulations are illustrative, not guarantees of future performance. Actual results may vary significantly. This analysis is for informational purposes only and does NOT constitute financial advice. Consult with a qualified financial advisor before making investment decisions." }`;
111
112// --- HTML Generation (Minified) ---
222var goals = { riskTolerance: document.getElementById('riskTol').value, timeHorizon: document.getElementById('timeHorz').value, sectorsOfInterest: document.getElementById('sectors').value || 'Any', investmentAmount: parseFloat(document.getElementById('invAmt').value) || undefined, otherNotes: document.getElementById('notes').value || undefined };
223var analysisRes; try {
224var apiUrl = window.location.pathname + '?action=analyze_goals&format=json'; var res = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(goals) }); var resBody = await res.text();
225try { analysisRes = JSON.parse(resBody); } catch (e) { console.error('Failed JSON parse:', resBody); var parseErr = { timestamp: new Date().toISOString(), level: 'FATAL', component: 'Client', message: 'Failed server JSON parse.', details: 'Status: ' + res.status + '. Snippet: ' + resBody.substring(0, 100) + '...' }; rendLog([parseErr]); throw new Error('Server returned non-JSON (Status: ' + res.status + ').'); }
226if (analysisRes && analysisRes.debugLog) { rendLog(analysisRes.debugLog); } else { rendLog([{ timestamp: new Date().toISOString(), level: 'WARN', component: 'Client', message: 'No debugLog in response.'}]); }
280 errMsg += " Unknown non-serializable err.";
281 }}
282 if (code === 401) errMsg += " (ACTION: Check API key)"; else if (code === 429)
283 errMsg += " (ACTION: Rate limit/quota exceeded)"; else if (code === 400)
284 errMsg +=
361 if (jsonData?.chart?.error) {
362 const errDesc = jsonData.chart.error.description || jsonData.chart.error.code || "Unknown Yahoo error";
363 internalLog(`${logPfx}: [ERROR] Yahoo API Error: ${errDesc}`);
364 return {
365 ticker,
366 error: `Yahoo API Error: ${errDesc}`,
367 dates: [],
368 open: [],
1391 const action = url.searchParams.get("action");
1392 if (format === "json" && action === "analyze_goals" && req.method === "POST") {
1393 log("INFO", "Handler", `API Request: ${req.method} ${url.pathname}${url.search}`);
1394 let userGoals: UserGoals;
1395 try {
8Today, we’re unifying our two primitives — *vals* and *projects* — into a single primitive: the **val**, with the best features of both.
9
10Historically, vals have been simple and lightweight, but limited to a single file. This upgrade will preserve the elegant spirit of our platform while supporting more complex code and collaborative workflows. This upgrade will help you create bigger things on Val Town – APIs, internal tools, fullstack apps, blogs ([like this one](https://www.val.town/x/valdottown/blog)), and much more – without sacrificing the simplicity you've always loved about vals.
11
12*Legacy vals* will temporarily become *projects* during this migration. Post-migration, the concept of *projects* will disappear entirely — leaving only upgraded *vals*. In short: *legacy vals* → *projects* → *vals*.
16For most users, no upgrade action is required. We’ll auto-migrate your vals next week.
17
18For those with mission-critical vals or who use our API to edit or create vals, you can start upgrading your legacy vals today and integrating with our updated API.
19
20- **April 23, 2025** – Announcement of changes & API deprecations.
21- **April 30, 2025** – All remaining *legacy vals* auto-upgraded. Deprecated API routes become read-only.
22- **May 1, 2025** – The term *projects* will no longer exist — everything will simply be a *val*.
23
35[See more details in our docs.](https://docs.val.town/upgrading/legacy-vals)
36
37## API Changes
38
39Today, we're introducing the following API routes:
40
41```bash
71```
72
73View our [updated API reference here](https://docs.val.town/openapi).
74
75We've also released a new major version of the [Val Town SDK](https://github.com/val-town/sdk/tree/main), `v1.0.0`, using these new endpoints.
76
77All `v1/vals` API routes become read-only on **April 30, 2025**. If you rely on *writing* to those routes, please upgrade to our new `v2/vals` API. All deprecated API routes will continue serving historical legacy val data.
78
79## What's next
80
811. Upgrade your mission-critical vals early.
822. Update your Val Town SDK & API usage to `/v2` routes.
833. All remaining legacy vals migrate on **April 30, 2025**.
844. Migration completes on **May 1, 2025**.
19export const oldPosts: BlogPost[] = [
20 {
21 "title": "Solving the internal / external API riddle",
22 "slug": "api-conundrum",
23 "link": "/blog/api-conundrum",
24 "description": "Figuring out how to provide an API that's usable by everyone and fast for us to iterate on",
25 "pubDate": "Thu, 27 Mar 2025 00:00:00 GMT",
26 "author": "Tom MacWright",
27 },
28 {
29 "title": "API Tokens Scopes",
30 "slug": "api-token-scopes",
31 "link": "/blog/api-token-scopes",
32 "description": "Improving security with granular control over permissions",
33 "pubDate": "Fri, 01 Nov 2024 00:00:00 GMT",
59 },
60 {
61 "title": "Expanding the Vals API - RFC",
62 "slug": "expanding-the-vals-api-rfc",
63 "link": "/blog/expanding-the-vals-api-rfc",
64 "description": "Our REST API lets you do a lot - and soon it will enable more",
65 "pubDate": "Fri, 30 Jun 2023 00:00:00 GMT",
66 "author": "André Terron",
133 },
134 {
135 "title": "The perks of a good OpenAPI spec",
136 "slug": "openapi",
137 "link": "/blog/openapi",
138 "description": "Taking advantage of our typed REST API to build a platform around\nVal Town.",
139 "pubDate": "Thu, 25 Jul 2024 00:00:00 GMT",
140 "author": "Tom MacWright",
262 },
263 {
264 "title": "The API we forgot to name",
265 "slug": "the-api-we-forgot-to-name",
266 "link": "/blog/the-api-we-forgot-to-name",
267 "description": "An API that takes a Request and returns a Response - what was that, again?",
268 "pubDate": "Thu, 19 Oct 2023 00:00:00 GMT",
269 "author": "Steve Krouse",
286 },
287 {
288 "title": "Deprecating the Run API",
289 "slug": "deprecating-the-run-api",
290 "link": "/blog/deprecating-the-run-api",
291 "description": "Not every function should be an API",
292 "pubDate": "Wed, 07 Feb 2024 00:00:00 GMT",
293 "author": "André Terron",
321 "slug": "val-town-newsletter-1",
322 "link": "/blog/val-town-newsletter-1",
323 "description": "Programmatic notifications, Hacker News API, and more.",
324 "pubDate": "Wed, 04 Jan 2023 00:00:00 GMT",
325 "author": "Steve Krouse",
450 "slug": "val-town-newsletter-22",
451 "link": "/blog/val-town-newsletter-22",
452 "description": "Townie upgrades, Scoped API permissions, Fal partnership",
453 "pubDate": "Mon, 02 Dec 2024 00:00:00 GMT",
454 "author": "Steve Krouse",