Macro FX Monitor is a free, source-backed US macro dashboard focused on inflation, growth, Federal Reserve policy, Treasury yields, and the US dollar. It converts the latest data into a transparent DXY regime score, scenario analysis, and educational market commentary.
Live site: macro-fx-monitor.vercel.app
- Public dashboard covering 14 macro and market series
- DXY regime score from -10 to +10
- Short-, medium-, and long-horizon scenarios
- Source-backed weekly and monthly snapshots
- Economic release calendar
- Confirmation and invalidation playbook
- Buttondown double-opt-in newsletter
- Private Supabase-authenticated X Marketing Agent
- Browser-generated 1600 x 900 X cards
- Local Remotion MP4 rendering
/dashboard- macro dashboard and DXY regime/drivers/[slug]- detailed driver research/snapshot- latest generated macro note/newsletter- free newsletter signup/methodology- scoring methodology/data-sources- source attribution and cadence
- Next.js 15, React 19, and TypeScript
- Recharts
- FRED and public economic data
- Supabase Auth and server-side storage
- Buttondown newsletter delivery
- Remotion video rendering
- Vercel hosting
- GitHub Actions scheduled publishing
npm install
copy .env.example .env.local
npm run devThe development server runs at http://localhost:3000.
Minimum public-dashboard configuration:
FRED_API_KEY=your_fred_api_key
NEXT_PUBLIC_SITE_URL=http://localhost:3000Never commit .env.local.
Server-only variables:
BUTTONDOWN_API_KEY=
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
ADMIN_EMAIL=
CRON_SECRET=
OPENAI_API_KEY=
X_API_BEARER_TOKEN=Do not add NEXT_PUBLIC_ to ADMIN_EMAIL, BUTTONDOWN_API_KEY,
SUPABASE_SERVICE_ROLE_KEY, or other private credentials.
Public configuration:
NEXT_PUBLIC_SITE_URL=
NEXT_PUBLIC_REPOSITORY_URL=
NEXT_PUBLIC_CONTACT_EMAIL=- Enable email/password authentication in Supabase.
- Create the administrator in Supabase Auth.
- Set
SUPABASE_URL,SUPABASE_ANON_KEY, and the server-onlyADMIN_EMAIL. - Apply the SQL in
supabase/schema.sql, followed by the files insupabase/migrations/. - Sign in at
/login. - Open
/admin/marketing. - Add password reset redirect URLs in Supabase Auth so recovery links can land on
/set-password.
Anonymous visitors are redirected to /login. Authenticated accounts that do
not exactly match ADMIN_EMAIL see Access denied. Admin pages use noindex,
and robots rules exclude admin and authentication routes.
Password recovery notes:
- The app accepts Supabase recovery and invite links on
/set-password. - Recovery links should redirect to
/set-password. - Callback links using
/auth/callback?next=/set-passwordare also supported. - Add both local and production reset URLs to Supabase Auth redirect URLs.
Private tables use row-level security. The anon and authenticated roles
have no direct table privileges. Drafts, settings, replies, performance data,
and stored snapshots are accessed through authenticated server routes using
the server-only Supabase service-role key.
The public form sends a POST request to /api/subscribe. The server validates
the address, rejects the honeypot field, checks for an existing subscriber,
creates the subscriber through Buttondown, and verifies that Buttondown stored
the record before returning success.
Buttondown handles:
- Subscriber storage
- Duplicate-address behavior
- Double-opt-in confirmation emails
- Newsletter delivery
- Unsubscribe links
Add this variable to Vercel Production and Preview:
BUTTONDOWN_API_KEY=your_buttondown_api_keyButtondown may place new sender accounts under review. While under review,
subscriber creation or confirmation-email delivery can be rejected or delayed.
When Buttondown reports a review-state error, the API returns
503 BUTTONDOWN_REVIEW_PENDING instead of displaying a false success.
The app can verify that an address exists in Buttondown. It cannot independently prove that a confirmation email reached the recipient. Check Buttondown account status, subscriber state, and delivery logs when confirmation mail is missing.
Useful API checks:
- Invalid email:
400 INVALID_EMAIL - Missing Buttondown key:
503 NEWSLETTER_UNAVAILABLE - Provider review state:
503 BUTTONDOWN_REVIEW_PENDING - New registered address:
201 SUBSCRIBER_CREATED - Existing address:
200 SUBSCRIBER_EXISTS
Open /admin/marketing after signing in.
- Review the two or three rotating posts under Today's suggested posts.
- Edit a suggestion directly and check its character count.
- Copy it for manual posting, or generate scored variations.
- Mark the suggestion as copied, posted, or skipped.
- Save durable drafts in the Draft Library.
- Record the posted URL and performance later.
The topic rotation covers DXY, CPI, PPI, PPI versus CPI, Treasury yields, Fed expectations, macro regimes, and confirmation/invalidation. Recent draft topics are avoided when possible. Publishing remains manual: the app does not post, reply, like, follow, or send messages through X.
Optional AI writing:
AI_ENABLED=true
OPENAI_API_KEY=your_server_only_key
AI_MODEL=gpt-5-miniWithout AI configuration, the deterministic source-backed generator remains available.
/admin/marketing first loads the latest weekly snapshot stored in Supabase.
That snapshot contains the DXY score, bias, strongest drivers, recent macro
releases, and a FRED release calendar captured when the snapshot was generated.
If no stored snapshot is available, the page generates a live fallback from the
configured macro sources, but that fallback is not durable until it is saved.
The scheduled GitHub Actions workflows call /api/cron/publish-snapshot:
- Weekly: Saturday at 13:00 UTC
- Monthly: the first day of each month at 14:00 UTC
Those schedules run only when the repository variable
SNAPSHOT_PUBLISHING_ENABLED is true and the required secrets are configured.
The cron route stores the snapshot and publishes through Buttondown.
The admin-only Refresh latest macro snapshot button is different: it regenerates and stores only the weekly snapshot used by the marketing agent. It does not publish a newsletter, send email, or post on X. The System status panel marks a weekly snapshot stale after eight days.
Saved drafts are loaded from the private Supabase marketing_drafts table.
They do not rewrite themselves. Clicking Generate as new draft creates new
copy from the latest stored snapshot, saved settings, and recent draft text.
Recent text is passed to the scoring and optional AI layers to reduce repetition.
AI-written variations require AI_ENABLED, OPENAI_API_KEY, and the admin AI
setting. Without them, the deterministic source-backed fallback generator is
used.
The two or three items under Today's suggested posts are generated fresh
when /admin/marketing is rendered. They are not loaded from saved drafts.
Their topic rotation uses the current server date and avoids recently saved
draft topics when possible.
Clicking Generate today's X plan rebuilds the plan immediately from the latest snapshot, current settings, current server date, and recent drafts. The plan generation timestamp is shown in System status.
The snapshot knows the scheduled US macro releases returned by FRED when it was generated. It does not have a general news feed and therefore does not automatically know breaking news, geopolitical developments, FOMC commentary outside the modeled data/calendar, or events such as US-Iran negotiations. That would require a licensed or reviewed news API, event feed, or manually supplied source text. X discovery additionally requires an implemented X API adapter and valid X API access; the current project does not perform automatic discovery.
Image cards and video configurations come from the selected saved draft. A new draft receives image, voiceover, subtitle, and video fields based on the snapshot used at generation time. Existing saved drafts remain historical and do not update when a newer snapshot is generated.
PNG export is generated in the browser from the selected draft. MP4 rendering
is manual and local using the downloaded JSON and npm run video:render.
Automatic when configured:
- FRED requests use short server caches, but stored snapshots change only when a snapshot generation route runs.
- GitHub Actions can generate, store, and publish weekly/monthly snapshots.
- Opening the admin page generates a fresh daily suggestion plan.
- Buttondown manages subscriber confirmation and newsletter delivery.
Requires an admin click:
- Refreshing the marketing-only snapshot
- Rebuilding today's X plan without reloading the page
- Generating and saving a new X draft
- Copying or marking content as posted
Requires external services:
- Supabase: stored snapshots, drafts, settings, replies, and performance
- Buttondown: subscriber confirmation and newsletter delivery
- OpenAI API: optional AI-written variations
- X API: future discovery or posting features; neither is active now
The private X Marketing Agent combines four inputs before building the daily idea list:
- The latest stored macro snapshot
- The next seven days of economic calendar events
- Recent macro, USD, rates, oil, and geopolitical headlines
- Manual context entered by the administrator
All provider requests run on the server. Provider keys and the Supabase service
role key are never sent to the browser. The context tables use RLS and grant
direct access only to Supabase's service_role.
The recommended calendar provider is Financial Modeling Prep (FMP). Finnhub remains supported as an alternative:
ECONOMIC_CALENDAR_ENABLED=true
ECONOMIC_CALENDAR_PROVIDER=fmp
ECONOMIC_CALENDAR_API_KEY=Create an API key from the FMP dashboard and add these variables to the Vercel project. The calendar is used only inside the private admin workspace. Review the provider's current data-display and licensing terms before exposing raw provider data publicly.
Without that key, Refresh economic calendar uses the existing FRED release calendar as a free fallback. You can also add a manual event such as “FOMC is on Wednesday.” Calendar entries store the event date, time, importance, category, previous/forecast/actual values when available, source, and a DXY explanation.
The recommended news provider is Marketaux. Its free plan currently provides 100 daily requests, three instant articles per request, and global finance-news metadata. NewsAPI remains supported for existing installations, but its free plan is intended for development and delayed news.
NEWS_ENABLED=true
NEWS_PROVIDER=marketaux
NEWS_API_KEY=Create an API token from the Marketaux account page and add these variables to Vercel. Each refresh makes two focused requests: one for U.S. macro/Fed/DXY news and one for geopolitical, oil, sanctions, tariffs, and trade developments. The agent deduplicates the combined results before storing them.
Without a news key, the agent remains fully usable in manual mode. Add a headline, geopolitical development, or note for today in Fresh Market Context. Developing geopolitical information is phrased conditionally as “markets are watching” and is used only to discuss oil, yields, risk sentiment, inflation expectations, and possible USD relevance.
Generate today's X ideas creates up to ten editable ideas across educational concepts, event previews/reactions, headline or geopolitical context, the dashboard snapshot, confirmation/invalidation, risk management, and a thread idea. Every card shows its source context, reason for relevance, character count, risk score, and repetition score.
The generator compares normalized wording, hooks, and topics with drafts and posted items from the previous 14 days. Lower-repetition ideas are prioritized, and similar copy receives a warning. Saving an idea adds it to the private draft library and therefore to future content memory. Marking an idea posted records that status locally; it does not connect to or publish through the X API.
Automatic:
- FRED data remains available to the snapshot and calendar fallback.
- A configured calendar or news provider is queried only through admin refresh actions or a future scheduled server job.
- Opening the admin page reads the latest stored context and generates a fresh in-memory idea list.
Manual:
- Refresh calendar or news context
- Add administrator context
- Generate or clear today's saved plan
- Edit, copy, save, or mark an idea posted
- Publish on X
AI remains optional. With AI_ENABLED=true, a valid OPENAI_API_KEY, and the
admin AI setting enabled, saved-draft variations use the existing AI adapter.
The daily context plan always has a deterministic fallback and works without
paid AI, calendar, or news APIs.
In Visual Studio, choose an image card and select Download 1600 x 900 PNG.
The responsive admin preview is separate from export. The download is drawn directly onto a true 1600 x 900 browser canvas with a solid dark background, large typography, full-canvas panels, drivers, confirmation, invalidation, URL, and disclaimer.
The repository includes:
remotion/remotion/sample-props.jsonnpm run video:studionpm run video:render
The admin button downloads a JSON configuration. JSON is not a video. To generate MP4 locally:
- Download the JSON configuration.
- Replace
remotion/sample-props.jsonwith the downloaded file. - Run:
npm run video:renderOutput:
out/macro-fx-update.mp4
Optional preview:
npm run video:studioThe JSON includes the generated voiceoverScript, subtitles settings, and
optional music settings. Put only royalty-free, generated, or personally owned
audio in public/audio/. Rendering remains silent when music is disabled or no
music file exists.
Automatic:
- Public data loading and dashboard calculations
- Scheduled snapshot generation when GitHub Actions is enabled
- Buttondown subscriber registration and provider-managed confirmation
- Draft scoring and media configuration generation
Manual:
- Reviewing and posting X content
- Marking posts as copied, posted, or skipped
- Replacing
remotion/sample-props.json - Running local MP4 rendering
- Adding licensed background audio
npm run check
npm run lint
npm run build
npm run video:renderThe source-health endpoint is /api/data-status.
- X publishing and reply discovery are not connected to the X API.
- PNG generation runs in the administrator's browser.
- MP4 rendering is local, not a Vercel serverless job.
- Daily suggestion statuses are lightweight browser state; saved drafts are the durable Supabase history.
- Buttondown account review can delay confirmation-email delivery.
- The app cannot verify inbox placement after Buttondown accepts a subscriber.
- Real-time licensed DXY market data is not included.
See docs/DEPLOYMENT.md and SECURITY.md.
This product uses the FRED API but is not endorsed or certified by the Federal Reserve Bank of St. Louis. It is educational research, not investment advice.
This project is currently free and mainly built for learning and portfolio purposes. In the future, if there is real demand, I may add premium features such as advanced dashboards, macro alerts, historical datasets, ad-free access, exports, hosted paid versions, newsletters, or data services.
This project is currently source-visible for educational, learning, portfolio, and demonstration purposes only.
It is not open source. Commercial use, redistribution, resale, hosting, deployment, or use as a competing product is not permitted without written permission.
The project is free to view and study for learning purposes, but I reserve the right to monetize future versions, premium features, hosted access, newsletters, data services, alerts, or related products.