<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Meneses González</title>
    <description>The latest articles on DEV Community by Kevin Meneses González (@kevin_menesesgonzlez).</description>
    <link>https://dev.to/kevin_menesesgonzlez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2412421%2F23a50b66-3e3e-4d13-8809-9bc0b03c0f40.png</url>
      <title>DEV Community: Kevin Meneses González</title>
      <link>https://dev.to/kevin_menesesgonzlez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevin_menesesgonzlez"/>
    <language>en</language>
    <item>
      <title>I Tested 5 Developer-Focused Video Editing Tools — Here's What I Learned</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Wed, 03 Jun 2026 12:15:21 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/i-tested-5-developer-focused-video-editing-tools-heres-what-i-learned-3102</link>
      <guid>https://dev.to/kevin_menesesgonzlez/i-tested-5-developer-focused-video-editing-tools-heres-what-i-learned-3102</guid>
      <description>&lt;p&gt;Most "best video editing software" lists are written by people who have never opened a terminal.&lt;/p&gt;

&lt;p&gt;They rank tools by how nice the timeline looks and how many transitions ship in the free plan. Useful if you're editing a wedding montage. Useless if you're a developer who needs to generate 5,000 videos from a database while you sleep.&lt;/p&gt;

&lt;p&gt;Because for developers, the question isn't &lt;em&gt;which editor has the smoothest drag-and-drop.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's a completely different question.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building a SaaS that exports video,&lt;/li&gt;
&lt;li&gt;automating social content from data,&lt;/li&gt;
&lt;li&gt;or generating personalized clips at scale,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need an editor. You need a render engine you can call from code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real question developers are asking in 2026
&lt;/h2&gt;

&lt;p&gt;The shift happening right now is simple to state: video is becoming code.&lt;/p&gt;

&lt;p&gt;Instead of dragging clips on a timeline, you describe a video the way you describe a web page — components, data, props — and a machine renders the frames. No human in the loop. No "export" button clicked by a person at 2 a.m.&lt;/p&gt;

&lt;p&gt;That changes what "best" even means. Flexibility, scalability, and how cleanly the tool fits into an automated pipeline matter far more than the prettiness of the UI.&lt;/p&gt;

&lt;p&gt;So I spent time with the five tools developers actually reach for, and graded each on three axes: &lt;strong&gt;flexibility&lt;/strong&gt; (how much control you really get), &lt;strong&gt;ease&lt;/strong&gt; (time-to-first-render), and &lt;strong&gt;scalability&lt;/strong&gt; (what happens when you need thousands of videos, not three).&lt;/p&gt;

&lt;p&gt;Here's what held up.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Remotion — the reference standard for video in React
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.remotion.dev" rel="noopener noreferrer"&gt;Remotion&lt;/a&gt; lets you build real MP4 videos using React components. Created by Jonny Burger and open-sourced in 2021, it has quietly become the default answer when a developer asks "how do I make video with code."&lt;/p&gt;

&lt;p&gt;Every frame is a React component. Every animation is a function of the current frame. Because the whole video is code, you version it in Git, review it in pull requests, and feed it dynamic props — which is exactly why it pairs so well with LLM-generated scripts and data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full React: hooks, props, components — no proprietary DSL to learn.&lt;/li&gt;
&lt;li&gt;Total control over animation, down to the frame.&lt;/li&gt;
&lt;li&gt;Scales hard via Lambda rendering — thousands of videos from one codebase.&lt;/li&gt;
&lt;li&gt;Open-source core with a large, active community.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Steep curve if you don't already live in React.&lt;/li&gt;
&lt;li&gt;Render pipelines (especially serverless) take real setup effort.&lt;/li&gt;
&lt;li&gt;No HDR yet, a limitation inherited from headless Chrome rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; SaaS products, animated dashboards, fintech data videos, and any content automation where you want code-level control.&lt;/p&gt;

&lt;p&gt;Pricing is fair for its target: free for individuals and small teams, a company license from around $100/month, and enterprise terms above that.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. HyperFrames — video as HTML, built for AI agents
&lt;/h2&gt;

&lt;p&gt;This is the tool I had to re-learn while researching, because the early write-ups got it wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hyperframes.video" rel="noopener noreferrer"&gt;HyperFrames&lt;/a&gt; is HeyGen's open-source (Apache 2.0) framework that turns plain HTML, CSS and JavaScript into frame-accurate MP4. No React. No component system. No build step. You write something close to a normal web page — using &lt;code&gt;data-start&lt;/code&gt;, &lt;code&gt;data-duration&lt;/code&gt; and &lt;code&gt;data-track-index&lt;/code&gt; attributes for the timeline — and a headless browser captures it frame by frame.&lt;/p&gt;

&lt;p&gt;The bet is interesting. Remotion wagered on React as the future of programmatic video. HyperFrames is wagering on raw HTML, precisely because today's AI models write clean HTML far more reliably than they write complex React animation architectures.&lt;/p&gt;

&lt;p&gt;It ships with skill packs for Claude Code and Codex, so an agent can scaffold, write and render a full video from a single prompt. It supports GSAP, Lottie, Three.js and D3, and renders locally with no API key required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower barrier than Remotion — plain HTML, no framework lock-in.&lt;/li&gt;
&lt;li&gt;Open source, runs locally, no account or cloud dependency.&lt;/li&gt;
&lt;li&gt;Purpose-built for agentic workflows (Claude Code, Codex).&lt;/li&gt;
&lt;li&gt;50+ pre-built blocks installable via &lt;code&gt;npx hyperframes add&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Young: launched in 2026, so the ecosystem is still thin.&lt;/li&gt;
&lt;li&gt;Best suited to simpler motion — text, diagrams, data overlays.&lt;/li&gt;
&lt;li&gt;Fewer battle-tested production references than Remotion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; AI-agent pipelines, automated shorts, and data videos where an agent writes the code and renders the output end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Creatomate — JSON in, video out
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://creatomate.com" rel="noopener noreferrer"&gt;Creatomate&lt;/a&gt; (Create + Automate) is the tool of choice when you want templated video generation through a REST API without managing rendering infrastructure.&lt;/p&gt;

&lt;p&gt;You design a template once — in a visual editor or as JSON — then fire data at it and get back a rendered video, GIF, or image. It's a favorite in the no-code automation crowd because it drops cleanly into n8n, Make and Zapier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Genuinely robust, well-documented API.&lt;/li&gt;
&lt;li&gt;Generate video straight from JSON — ideal for data-driven content.&lt;/li&gt;
&lt;li&gt;First-class fit for n8n and Make automations.&lt;/li&gt;
&lt;li&gt;Visual editor lets non-developers maintain templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Credit-based pricing climbs fast at volume.&lt;/li&gt;
&lt;li&gt;Text-to-speech (ElevenLabs/Azure) is billed on top of render credits.&lt;/li&gt;
&lt;li&gt;Less low-level control than a code-native tool like Remotion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; agencies, marketing automation, and personalized video at moderate volume.&lt;/p&gt;

&lt;p&gt;Plans start around $41–54/month for roughly 150–200 minutes at 720p, scaling up from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Shotstack — the AWS of video
&lt;/h2&gt;

&lt;p&gt;If Creatomate is the friendly templating layer, &lt;a href="https://shotstack.io" rel="noopener noreferrer"&gt;Shotstack&lt;/a&gt; is the industrial-grade rendering backend. Define a composition as JSON, send it to the API, and Shotstack renders it at scale — thousands of videos in minutes — and serves them from its own CDN.&lt;/p&gt;

&lt;p&gt;It's been around since well before the current hype cycle, which shows: the API is mature, the behavior is predictable, and there's a free sandbox that doesn't ask for a credit card. It's a rendering engine, not a content-intelligence platform — you bring your own AI for voice or subtitles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely mature, well-documented API with SDKs for Node.js, PHP and more.&lt;/li&gt;
&lt;li&gt;Predictable, deterministic rendering — what you send is what you get.&lt;/li&gt;
&lt;li&gt;Built to scale; white-label editor SDK you can embed in your own product.&lt;/li&gt;
&lt;li&gt;Free sandbox for testing before you commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More technical to set up than a visual-first tool.&lt;/li&gt;
&lt;li&gt;Resolution-based pricing gets expensive at 1080p+.&lt;/li&gt;
&lt;li&gt;No native AI features — you wire in voice and captions yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; SaaS platforms and any application that needs to render large volumes of video reliably.&lt;/p&gt;

&lt;p&gt;Pricing runs pay-as-you-go at roughly $0.30/min, or plans from about $39/month at lower per-minute rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. React Video Editor (RVE) — a timeline UI you don't have to build
&lt;/h2&gt;

&lt;p&gt;Building a video editor from scratch is brutal: timelines, drag-and-drop, multi-track state, media handling. RVE exists so you don't have to.&lt;/p&gt;

&lt;p&gt;It's a React/Next.js editor that uses Remotion underneath for rendering. There's a free, &lt;a href="https://github.com/reactvideoeditor/free-react-video-editor" rel="noopener noreferrer"&gt;open-source baseline&lt;/a&gt; to learn the building blocks, plus commercial &lt;a href="https://www.reactvideoeditor.com" rel="noopener noreferrer"&gt;Pro and SDK options&lt;/a&gt; for teams that want a production-ready editor without burning a month of engineering on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open source baseline — inspect and learn the architecture for free.&lt;/li&gt;
&lt;li&gt;Pure React/Next.js; customizable to your product.&lt;/li&gt;
&lt;li&gt;Saves weeks of work if you need an in-app editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Younger project with a smaller community.&lt;/li&gt;
&lt;li&gt;Documentation is still catching up.&lt;/li&gt;
&lt;li&gt;Built on Remotion, so a Remotion license may apply depending on use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; React teams shipping an embedded video editor, internal tools, or creative SaaS features.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "video as code" actually looks like
&lt;/h2&gt;

&lt;p&gt;Theory is cheap. Here's the same idea — a simple fintech price card — expressed in the three paradigms these tools represent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remotion (React):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCurrentFrame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interpolate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PriceCard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCurrentFrame&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opacity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interpolate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extrapolateRight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clamp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0A1628&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opacity&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FFFFFF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#3B82F6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;HyperFrames (HTML):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-track-index=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;data-start=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;data-duration=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color:#FFFFFF"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;AAPL&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color:#3B82F6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;$214.30&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- render: npx hyperframes render scene.html --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creatomate / Shotstack (JSON via API, called from Python):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.creatomate.com/v1/renders&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer YOUR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;template_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-template-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modifications&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$214.30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three philosophies. React owns the components. HTML optimizes for what AI writes well. JSON-over-API hides the rendering entirely.&lt;/p&gt;

&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;daily auto-generated market recap videos,&lt;/li&gt;
&lt;li&gt;personalized onboarding clips per user,&lt;/li&gt;
&lt;li&gt;thousands of localized product shorts from one template.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The ranking, at a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Flexibility&lt;/th&gt;
&lt;th&gt;Ease&lt;/th&gt;
&lt;th&gt;Scalability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Remotion&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;td&gt;6/10&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyperFrames&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creatomate&lt;/td&gt;
&lt;td&gt;7/10&lt;/td&gt;
&lt;td&gt;9/10&lt;/td&gt;
&lt;td&gt;9/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shotstack&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;td&gt;7/10&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RVE&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;td&gt;6/10&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the scores as trade-offs, not a leaderboard. Remotion wins on control and loses on ramp-up. Creatomate wins on speed-to-first-video and gives up low-level control. Nobody wins all three.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honorable mentions — the AI generation layer
&lt;/h2&gt;

&lt;p&gt;These don't compete with the tools above. They sit next to them, generating the raw footage you then assemble:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://runwayml.com" rel="noopener noreferrer"&gt;Runway&lt;/a&gt;&lt;/strong&gt; — generative AI video.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.descript.com" rel="noopener noreferrer"&gt;Descript&lt;/a&gt;&lt;/strong&gt; — edit video by editing the transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.capcut.com" rel="noopener noreferrer"&gt;CapCut&lt;/a&gt;&lt;/strong&gt; — fast, creator-focused editing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.veed.io" rel="noopener noreferrer"&gt;VEED&lt;/a&gt;&lt;/strong&gt; — marketing and subtitle-heavy workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://lumalabs.ai" rel="noopener noreferrer"&gt;Luma AI&lt;/a&gt;&lt;/strong&gt; — text-to-video generation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern worth noticing: the code-first tools are the &lt;em&gt;assembly&lt;/em&gt; layer, and these are the &lt;em&gt;content&lt;/em&gt; layer. The strongest pipelines in 2026 chain both — Runway or Luma generates a clip, Remotion or HyperFrames composes it with data and renders the final cut.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to actually choose
&lt;/h2&gt;

&lt;p&gt;Forget the feature lists for a second and answer three questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you live in React?&lt;/strong&gt; Then Remotion, and RVE if you need a ready-made editor UI on top of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are AI agents writing your video code?&lt;/strong&gt; HyperFrames was built for exactly that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you just want a video back from an API and never think about rendering?&lt;/strong&gt; Creatomate for templated content with a visual editor, Shotstack when you need it to scale like infrastructure.&lt;/p&gt;

&lt;p&gt;There's no universal winner. There's only the tool that disappears into &lt;em&gt;your&lt;/em&gt; pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For developers, "best video tool" means best render engine, not best timeline.&lt;/li&gt;
&lt;li&gt;Remotion (React) and HyperFrames (HTML) split the code-first world by what they optimize for: human control vs. AI ergonomics.&lt;/li&gt;
&lt;li&gt;API-first tools (Creatomate, Shotstack) trade control for not having to run rendering infrastructure at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I generate videos without a video editor?&lt;/strong&gt;&lt;br&gt;
Yes. Tools like Remotion, HyperFrames, Creatomate and Shotstack let you produce MP4 video entirely from code or an API — no timeline, no manual editing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the difference between Remotion and HyperFrames?&lt;/strong&gt;&lt;br&gt;
Remotion renders video from React components and is the more mature choice for product teams. HyperFrames renders video from plain HTML and is optimized for AI agents writing the code. Both render through a headless browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which tool is best for generating thousands of videos?&lt;/strong&gt;&lt;br&gt;
Shotstack and Remotion (on Lambda) are built for high-volume rendering. Creatomate also scales well but its credit pricing climbs at large volumes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to know how to code to use these?&lt;/strong&gt;&lt;br&gt;
For Remotion, HyperFrames and RVE, yes. Creatomate and Shotstack can be driven through no-code tools like n8n and Make, though the API unlocks the most power.&lt;/p&gt;




&lt;p&gt;If you're a software or API company looking to explain a developer product through high-quality educational content — real code, not marketing fluff — feel free to connect with me on LinkedIn.&lt;/p&gt;

&lt;p&gt;Video stopped being something you &lt;em&gt;edit&lt;/em&gt; and started being something you &lt;em&gt;generate&lt;/em&gt;. The developers who internalize that won't be the ones with the best timeline skills.&lt;/p&gt;

&lt;p&gt;They'll be the ones who treat video like every other build artifact: code, data, and a render step.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>video</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>Top 5 Data Visualizations for Algorithmic Trading (With Python Code)</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Sun, 31 May 2026 09:30:00 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/top-5-data-visualizations-for-algorithmic-trading-with-python-code-5p2</link>
      <guid>https://dev.to/kevin_menesesgonzlez/top-5-data-visualizations-for-algorithmic-trading-with-python-code-5p2</guid>
      <description>&lt;p&gt;Most algo traders write signals. Almost none visualize them correctly.&lt;/p&gt;

&lt;p&gt;You can have a backtest with 300 trades, a Sharpe ratio of 1.4, and still have no idea whether your system is working — or getting lucky. The numbers don't show you where the strategy breathes. Charts do.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building a quantitative trading system,&lt;/li&gt;
&lt;li&gt;running backtests and not knowing how to interpret the results,&lt;/li&gt;
&lt;li&gt;or trying to communicate your edge to investors or teammates,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem Isn't the Data. It's What You Can't See.
&lt;/h2&gt;

&lt;p&gt;A developer I know spent three months building a mean-reversion strategy. Solid execution, clean Python, well-documented. He ran the backtest. The results looked good.&lt;/p&gt;

&lt;p&gt;What he couldn't see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Three consecutive months of drawdown that would have ended any fund&lt;/li&gt;
&lt;li&gt;80% of returns coming from a single volatile week in March&lt;/li&gt;
&lt;li&gt;His volume filters triggering on micro-cap stocks with no real liquidity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The strategy wasn't broken. His visualization layer was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualization is not decoration. It is part of the analysis.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I understood that, I stopped treating charts as outputs and started treating them as inputs to the research process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why EODHD Is the Right Data Layer for This
&lt;/h2&gt;

&lt;p&gt;Before the code, a word on data quality.&lt;/p&gt;

&lt;p&gt;Every chart in this article is powered by &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=algo-trading-data-viz&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;EODHD APIs&lt;/a&gt;. Not because it's the only option — but because it's the one I consistently use for production-grade algo trading research.&lt;/p&gt;

&lt;p&gt;What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-of-day prices for 70,000+ tickers across 60+ exchanges&lt;/li&gt;
&lt;li&gt;Intraday data down to 1-minute resolution&lt;/li&gt;
&lt;li&gt;Fundamental data, economic indicators, and options chains — all through a clean REST API&lt;/li&gt;
&lt;li&gt;Python-friendly JSON responses with predictable schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The free tier covers most of what you need to start. Paid plans scale with your data volume.&lt;/p&gt;

&lt;p&gt;👉&lt;em&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=algo-trading-data-viz&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Get started with EODHD here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Architecture: From API to Chart
&lt;/h2&gt;

&lt;p&gt;Before we dive into charts, it's worth understanding how data flows from the EODHD API into your visualization layer.&lt;/p&gt;

&lt;p&gt;The pipeline has four stages: fetch raw OHLCV data from the REST API, normalize it into a pandas DataFrame, compute derived metrics (signals, indicators, returns), and finally render the visualization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj88d6pz72vf8902aswkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj88d6pz72vf8902aswkl.png" alt=" " width="641" height="434"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The 5 Visualizations
&lt;/h2&gt;




&lt;h3&gt;
  
  
  1. Candlestick Chart with Moving Averages — Trend Structure at a Glance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it shows:&lt;/strong&gt; Price action as OHLC candles, layered with a fast (20-period) and slow (50-period) exponential moving average.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for algo trading:&lt;/strong&gt;&lt;br&gt;
The candlestick + EMA combination is the foundation of every trend-following system. Before deploying any directional strategy, you need to see whether the asset is trending, consolidating, or reversing. Moving average crossovers are a common signal generation mechanism — and seeing them plotted against real price action reveals how late, noisy, or clean those signals actually are.&lt;/p&gt;

&lt;p&gt;A crossover that looks clean in a table of dates looks completely different when you see it happening during a sideways chop period. The chart reveals what the numbers hide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;plotly.graph_objects&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;plotly.subplots&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;make_subplots&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;TICKER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;from_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2024-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/eod/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fmt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;period&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;from_date&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Compute EMAs
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_20&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;ewm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;ewm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Figure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Candlestick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OHLC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_20&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orange&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMA 20&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMA 50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; — Candlestick with EMA 20/50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;xaxis_rangeslider_visible&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plotly_dark&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EMA crossover signal detection with entry/exit markers on the chart&lt;/li&gt;
&lt;li&gt;Multi-timeframe confluence overlays (daily trend + intraday entry)&lt;/li&gt;
&lt;li&gt;Automated alerts when price closes above/below a moving average&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Volume Profile — Where the Market Actually Traded
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it shows:&lt;/strong&gt; A horizontal histogram of traded volume at each price level over a defined period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for algo trading:&lt;/strong&gt;&lt;br&gt;
Price tells you &lt;em&gt;when&lt;/em&gt; moves happened. Volume profile tells you &lt;em&gt;where&lt;/em&gt; the market spent its time. High-volume nodes are price magnets — levels where large participants built positions. Low-volume nodes are inefficiencies — levels the market crossed through quickly and is likely to revisit.&lt;/p&gt;

&lt;p&gt;If your strategy is entering near a high-volume node, you have natural support or resistance. If it's entering in a low-volume area, you're in air. No other visualization shows this as clearly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch data (reuse fetch_ohlcv from above)
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Build volume profile
&lt;/span&gt;&lt;span class="n"&gt;price_range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;linspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vol_profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zeros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterrows&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;vol_profile&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;volume&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="n"&gt;bin_centers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ax1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;gridspec_kw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;width_ratios&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0d1117&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Left: price chart
&lt;/span&gt;&lt;span class="n"&gt;ax1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#58a6ff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_facecolor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0d1117&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; — Close Price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tick_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Right: volume profile (horizontal bars)
&lt;/span&gt;&lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;barh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_centers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vol_profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;price_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#388bfd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_facecolor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0d1117&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Volume Profile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tick_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yaxis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tick_right&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tight_layout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Point of Control (POC) detection — the single price level with the highest volume&lt;/li&gt;
&lt;li&gt;Value Area calculation (70% of volume) for mean-reversion entries&lt;/li&gt;
&lt;li&gt;Multi-session profiles to compare volume distribution across market regimes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Equity Curve with Drawdown Panel — Backtest Health in One View
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it shows:&lt;/strong&gt; The cumulative return of a strategy over time (top panel) + the drawdown at every point (bottom panel).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for algo trading:&lt;/strong&gt;&lt;br&gt;
A positive total return tells you almost nothing. What matters is the &lt;em&gt;path&lt;/em&gt; to that return. A strategy that returns +40% over 3 years with a -35% drawdown in the middle is not the same as one that returns +40% with a max drawdown of -8%. One you can trade. The other will cause you to abandon the system at exactly the wrong moment.&lt;/p&gt;

&lt;p&gt;The drawdown panel is the psychological test. If you can't stomach what you see there, you can't run that strategy live.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;plotly.graph_objects&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;plotly.subplots&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;make_subplots&lt;/span&gt;

&lt;span class="c1"&gt;# --- Simulate a simple MA crossover strategy ---
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;ewm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;ewm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ema_30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily_return&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strategy_return&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily_return&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;equity_curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strategy_return&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;cumprod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;running_max&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;equity_curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;cummax&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;drawdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;equity_curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;running_max&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# --- Plot ---
&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;make_subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;shared_xaxes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;row_heights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;vertical_spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;equity_curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tozeroy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#58a6ff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Equity Curve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;drawdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tozeroy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#f85149&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;fillcolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rgba(248,81,73,0.2)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Drawdown (%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plotly_dark&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MA Crossover Strategy — Equity Curve &amp;amp; Drawdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;showlegend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key metrics to annotate on this chart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Max Drawdown&lt;/strong&gt; — the deepest valley from peak&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery Time&lt;/strong&gt; — how long it took to reach a new equity high&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calmar Ratio&lt;/strong&gt; — annualized return / max drawdown (one number that summarizes risk-adjusted performance)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Correlation Heatmap — Portfolio Risk Hidden in Plain Sight
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it shows:&lt;/strong&gt; A matrix of pairwise return correlations between multiple assets or strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for algo trading:&lt;/strong&gt;&lt;br&gt;
Diversification only works if your assets are actually uncorrelated. Most traders think they're diversified because they hold different tickers. They're not — they're holding different tickers that all fall together in a risk-off event.&lt;/p&gt;

&lt;p&gt;A correlation heatmap shows you the real structure of your portfolio. Dark red cells = concentrated risk. Near-zero cells = genuine diversification. This is the chart you show before adding a new strategy or asset to your book.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sns&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="n"&gt;TICKERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MSFT.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGL.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JPM.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GLD.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;price_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TICKERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;df_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;price_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df_t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price_data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;corr_matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0d1117&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heatmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;corr_matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;annot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.2f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RdYlGn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmin&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vmax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linewidths&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cbar_kws&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shrink&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Asset Return Correlation Matrix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pad&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tick_params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tight_layout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correlation monitoring over rolling windows to detect regime shifts&lt;/li&gt;
&lt;li&gt;Portfolio optimizer that constrains position sizing based on pairwise correlation&lt;/li&gt;
&lt;li&gt;Alert when two previously uncorrelated assets start moving together&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. RSI + Bollinger Bands Overlay — Momentum Meets Volatility
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it shows:&lt;/strong&gt; RSI (Relative Strength Index) as a momentum oscillator below the price chart, with Bollinger Bands (20-period SMA ± 2σ) overlaid on price.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters for algo trading:&lt;/strong&gt;&lt;br&gt;
Neither RSI nor Bollinger Bands alone is particularly reliable. Together, they become a high-conviction signal framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Price touching the lower Bollinger Band &lt;strong&gt;while&lt;/strong&gt; RSI is below 30 = potential oversold reversal entry&lt;/li&gt;
&lt;li&gt;Price breaking above the upper band &lt;strong&gt;while&lt;/strong&gt; RSI is above 70 = potential momentum continuation or overbought exit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the kind of multi-indicator confluence that most systematic strategies are built around. Seeing it visually — before you code the logic — prevents you from building signal combinations that never actually coincide in real market data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;plotly.graph_objects&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;plotly.subplots&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;make_subplots&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_ohlcv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Bollinger Bands
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_std&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_upper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_std&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_lower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_std&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# RSI
&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;gain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rsi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;make_subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;shared_xaxes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;row_heights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;vertical_spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.04&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# --- Price + Bollinger Bands ---
&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#58a6ff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_upper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rgba(255,165,0,0.5)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BB Upper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_lower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tonexty&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fillcolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rgba(255,165,0,0.05)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rgba(255,165,0,0.5)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BB Lower&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bb_mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BB Mid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# --- RSI ---
&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rsi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#c9d1d9&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RSI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_hline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_dash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;red&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_hline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_dash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;green&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plotly_dark&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TICKER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; — Bollinger Bands + RSI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;580&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signal detection when both conditions are met simultaneously (dual-condition scanner)&lt;/li&gt;
&lt;li&gt;Backtesting the mean-reversion rule: buy when price &amp;lt; BB lower AND RSI &amp;lt; 30&lt;/li&gt;
&lt;li&gt;Squeeze detection using Bollinger Band width as a volatility compression indicator&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;❓ &lt;strong&gt;Do I need a paid EODHD plan to run these examples?&lt;/strong&gt;&lt;br&gt;
✅ The free tier of EODHD includes end-of-day data for most major exchanges, which is enough to run all five visualizations in this article. You only need a paid plan if you require intraday data (1-minute or 5-minute candles), real-time feeds, or access to premium data categories like options chains.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Which Python charting library is best for algo trading — Plotly or Matplotlib?&lt;/strong&gt;&lt;br&gt;
✅ Use Plotly for any visualization that benefits from interactivity: equity curves you want to zoom, heatmaps you want to hover over, multi-panel dashboards. Use Matplotlib for static outputs, publication-quality figures, or when you're exporting to PDF reports. Both are used in this article because each has a domain where it genuinely wins.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Can I use these visualizations in a live trading dashboard, not just backtesting?&lt;/strong&gt;&lt;br&gt;
✅ Yes. The EODHD API supports intraday data with minute-level resolution on paid plans. Swap the &lt;code&gt;period="d"&lt;/code&gt; parameter in &lt;code&gt;fetch_ohlcv&lt;/code&gt; to &lt;code&gt;period="m"&lt;/code&gt; for minute data. The chart code stays identical — only the data granularity changes. For a fully automated live dashboard, combine these functions with a scheduler like APScheduler or a workflow tool like n8n.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;What does the Volume Profile actually measure vs. standard volume bars?&lt;/strong&gt;&lt;br&gt;
✅ Standard volume bars (shown at the bottom of most charts) show volume &lt;em&gt;over time&lt;/em&gt; — how much was traded in each candle. Volume Profile shows volume &lt;em&gt;at price&lt;/em&gt; — how much was traded at each price level across a defined period. The second view is far more useful for identifying support/resistance zones and understanding where institutional positions were built.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Is algorithmic trading data visualization useful if I'm not running fully automated strategies?&lt;/strong&gt;&lt;br&gt;
✅ Absolutely. Even manual or semi-systematic traders benefit from these charts. The equity curve and drawdown panel are essential for anyone journaling their performance. The correlation heatmap is useful for any multi-asset portfolio. Visualization is not about automation — it's about reducing blind spots.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Markets don't reward complexity. They reward clarity.&lt;/p&gt;

&lt;p&gt;The five charts in this article won't give you an edge by themselves. But they will show you where your edge actually exists — and, more importantly, where it doesn't.&lt;/p&gt;

&lt;p&gt;Start with the candlestick overlay to understand trend structure. Add the drawdown panel to understand psychological survivability. Use the correlation matrix before you add any new position to your book.&lt;/p&gt;

&lt;p&gt;The rest follows.&lt;/p&gt;




&lt;h2&gt;
  
  
  Start Building With Better Data
&lt;/h2&gt;

&lt;p&gt;Every chart in this article runs on EODHD APIs. If you're serious about algorithmic trading research, the data layer is not the place to cut corners.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=algo-trading-data-viz&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Get started with EODHD here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What you get access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-of-day and intraday data for 70,000+ tickers across 60+ exchanges&lt;/li&gt;
&lt;li&gt;Fundamentals, economic indicators, and options chains — all through one clean REST API&lt;/li&gt;
&lt;li&gt;A free tier that covers everything in this article, no credit card required&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Work With Me
&lt;/h2&gt;

&lt;p&gt;I produce technical content for fintech and developer tools companies — tutorials, API walkthroughs, data-driven articles that actually get read.&lt;/p&gt;

&lt;p&gt;If you're building something in the trading, data, or developer tools space and need content that explains your product without sounding like a press release:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;Connect on LinkedIn&lt;/a&gt;&lt;/strong&gt; or reach out directly at &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>stocks</category>
      <category>data</category>
      <category>dashboards</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Interactive Brokers API vs EODHD: Which One Actually Saves You Time?</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Fri, 29 May 2026 09:00:35 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/interactive-brokers-api-vs-eodhd-which-one-actually-saves-you-time-15l7</link>
      <guid>https://dev.to/kevin_menesesgonzlez/interactive-brokers-api-vs-eodhd-which-one-actually-saves-you-time-15l7</guid>
      <description>&lt;p&gt;Most developers assume that using a broker's API gives you a direct advantage when building financial tools.&lt;/p&gt;

&lt;p&gt;The assumption: if your broker has an API, you might as well use it for data.&lt;/p&gt;

&lt;p&gt;The reality: trading APIs and data APIs solve fundamentally different problems — and confusing the two will cost you weeks of unnecessary setup, a running desktop app, and a live brokerage account before you write a single line of analysis code.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building a stock screener or portfolio analyzer,&lt;/li&gt;
&lt;li&gt;automating financial research with Python,&lt;/li&gt;
&lt;li&gt;or integrating market data into an AI agent,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;this comparison matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Interactive Brokers API Actually Is (And What It Isn't)
&lt;/h2&gt;

&lt;p&gt;Interactive Brokers is a serious brokerage. Their API — built around TWS (Trader Workstation) and the &lt;code&gt;ib_insync&lt;/code&gt; Python library — is designed for one primary use case: &lt;strong&gt;executing trades programmatically&lt;/strong&gt; from a live account.&lt;/p&gt;

&lt;p&gt;It also exposes market data. Historical prices, fundamentals, options chains. The data is there.&lt;/p&gt;

&lt;p&gt;But the access model is the problem.&lt;/p&gt;

&lt;p&gt;To pull a single historical price series using the IBKR API, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An active Interactive Brokers brokerage account (funded or paper)&lt;/li&gt;
&lt;li&gt;TWS or IB Gateway running locally on your machine&lt;/li&gt;
&lt;li&gt;A socket connection open on port 7497 or 4002&lt;/li&gt;
&lt;li&gt;Pacing limits: IBKR throttles historical data requests to ~60 per 10 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the setup &lt;em&gt;before&lt;/em&gt; you write any analysis logic.&lt;/p&gt;

&lt;p&gt;Here's the simplest working example using &lt;code&gt;ib_insync&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ib_insync&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;IB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Stock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;util&lt;/span&gt;

&lt;span class="c1"&gt;# Requires TWS or IB Gateway running on localhost
&lt;/span&gt;&lt;span class="n"&gt;ib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7497&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clientId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SMART&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reqHistoricalData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;endDateTime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;durationStr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;30 D&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;barSizeSetting&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1 day&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;whatToShow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CLOSE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;useRTH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;df&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;ib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Output (example):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         date   close
20  2026-04-28  211.23
21  2026-04-29  213.45
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This works. But notice what it requires: a running desktop application, an authenticated session, and a live connection. If TWS isn't open, your script fails silently. If you're running this on a server, you need IB Gateway configured and maintained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deep integration if you're already trading with IBKR&lt;/li&gt;
&lt;li&gt;Access to live quotes, options data, and order execution in one place&lt;/li&gt;
&lt;li&gt;Well-maintained Python library (&lt;code&gt;ib_insync&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires a funded or paper brokerage account&lt;/li&gt;
&lt;li&gt;TWS or IB Gateway must be running — not suitable for lightweight server deployments&lt;/li&gt;
&lt;li&gt;Historical data pacing restrictions limit bulk research workloads&lt;/li&gt;
&lt;li&gt;Not designed for broad market screening across thousands of symbols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; algo traders who are already IBKR clients and need to combine execution with data in a single workflow.&lt;/p&gt;


&lt;h2&gt;
  
  
  What EODHD Is (And Why the Model Is Different)
&lt;/h2&gt;

&lt;p&gt;EODHD — End of Day Historical Data — is a pure financial data API. No brokerage account. No desktop software. No socket connections.&lt;/p&gt;

&lt;p&gt;One API key. REST calls. JSON responses. That's it.&lt;/p&gt;

&lt;p&gt;The architecture is what makes it developer-friendly by design: you send an HTTP request to an endpoint, you get structured data back. The same way you'd call any modern API — from a Jupyter notebook, a FastAPI backend, a cron job on a cloud server, or an AI agent.&lt;/p&gt;

&lt;p&gt;Here's the equivalent historical price request in EODHD:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_eodhd_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/eod/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fmt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-03-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-04-30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         date    close
20  2026-04-28   211.23
21  2026-04-29   213.45
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same data. No running application. No account requirement. Deployable anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST API — no local dependencies, works on any server or cloud environment&lt;/li&gt;
&lt;li&gt;70+ exchanges covered globally, 30+ years of historical data&lt;/li&gt;
&lt;li&gt;Fundamentals, macroeconomic indicators, options chains, news sentiment — all under one API key&lt;/li&gt;
&lt;li&gt;No pacing restrictions for most endpoints (rate limits are generous on paid plans)&lt;/li&gt;
&lt;li&gt;Free tier available for evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No trade execution — data only (by design)&lt;/li&gt;
&lt;li&gt;Real-time quotes have a 15–20 min delay on lower-tier plans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; developers building research tools, AI agents, portfolio analytics, or any financial application where data access needs to be clean, fast, and deployment-independent.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
💡 &lt;strong&gt;Try EODHD on your next project&lt;/strong&gt;&lt;br&gt;
API key in 30 seconds. No brokerage account required. Free tier included — EOD data for US exchanges out of the box.&lt;br&gt;
👉 &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=interactive-brokers-api-vs-eodhd-financial-data-python&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Get started with EODHD&lt;/a&gt;&lt;br&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Most Useful EODHD Endpoints for Developers
&lt;/h2&gt;

&lt;p&gt;EODHD's value isn't just in historical prices. The breadth of the API is where it differentiates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End-of-Day Prices&lt;/strong&gt; (&lt;code&gt;/api/eod/&lt;/code&gt;)&lt;br&gt;
Daily OHLCV for 70+ global exchanges. Adjusted for splits and dividends. 30+ years of history for major symbols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fundamentals&lt;/strong&gt; (&lt;code&gt;/api/fundamentals/&lt;/code&gt;)&lt;br&gt;
Full company financials: income statements, balance sheets, cash flow, earnings history, analyst estimates. Structured JSON you can feed directly into a model or dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/fundamentals/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;filter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Financials::Income_Statement::yearly&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Real-Time / Live Data&lt;/strong&gt; (&lt;code&gt;/api/real-time/&lt;/code&gt;)&lt;br&gt;
Delayed quotes (~15–20 min) or real-time on higher plans. Bulk requests supported — fetch up to 50 tickers in one call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Macroeconomic Indicators&lt;/strong&gt; (&lt;code&gt;/api/macro-indicator/&lt;/code&gt;)&lt;br&gt;
GDP, CPI, unemployment, interest rates per country. Useful for macro-driven models and risk analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;News &amp;amp; Sentiment&lt;/strong&gt; (&lt;code&gt;/api/news/&lt;/code&gt;)&lt;br&gt;
Financial news filtered by ticker. Useful for NLP pipelines and sentiment-aware trading signals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Options Data&lt;/strong&gt; (&lt;code&gt;/api/options/&lt;/code&gt;)&lt;br&gt;
Full options chain per symbol including Greeks, open interest, and volume.&lt;/p&gt;

&lt;p&gt;Each endpoint follows the same REST pattern. You learn one, you know all.&lt;/p&gt;


&lt;h2&gt;
  
  
  Side-by-Side Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Interactive Brokers API&lt;/th&gt;
&lt;th&gt;EODHD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup required&lt;/td&gt;
&lt;td&gt;TWS/IB Gateway + account&lt;/td&gt;
&lt;td&gt;API key only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account required&lt;/td&gt;
&lt;td&gt;Yes (brokerage)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Local / desktop-dependent&lt;/td&gt;
&lt;td&gt;Any server, cloud, notebook&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historical data&lt;/td&gt;
&lt;td&gt;Yes (paced, limited)&lt;/td&gt;
&lt;td&gt;Yes (30+ years, bulk-friendly)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fundamentals&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Full financial statements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global coverage&lt;/td&gt;
&lt;td&gt;Major exchanges&lt;/td&gt;
&lt;td&gt;70+ exchanges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time data&lt;/td&gt;
&lt;td&gt;Yes (with live account)&lt;/td&gt;
&lt;td&gt;Delayed / real-time (plan-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trade execution&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suitable for AI agents&lt;/td&gt;
&lt;td&gt;Difficult&lt;/td&gt;
&lt;td&gt;Yes — REST native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free tier&lt;/td&gt;
&lt;td&gt;Paper account only&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Free with brokerage account&lt;/td&gt;
&lt;td&gt;From $19.99/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  The MCP Advantage: EODHD as an AI-Native Data Layer
&lt;/h2&gt;

&lt;p&gt;This is where EODHD's architecture creates a significant gap that didn't exist two years ago.&lt;/p&gt;

&lt;p&gt;With the rise of AI agents — tools built on Claude, GPT-4, LangChain, or custom LLM pipelines — financial data access needs to be &lt;strong&gt;agent-callable&lt;/strong&gt;. That means structured, predictable, HTTP-based endpoints that an AI model can invoke without managing state, connections, or authentication flows mid-conversation.&lt;/p&gt;

&lt;p&gt;EODHD has an official MCP (Model Context Protocol) server.&lt;/p&gt;

&lt;p&gt;This means you can give Claude, Cursor, or any MCP-compatible agent direct access to EODHD endpoints — without writing a single line of integration code.&lt;/p&gt;

&lt;p&gt;A practical example: instead of building an API wrapper, a prompt chain, and an output parser, you connect the EODHD MCP server and ask your agent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Fetch the last 6 months of Apple's revenue growth and compare it to its 5-year average."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent calls the fundamentals endpoint, receives structured JSON, and performs the analysis — all within a single reasoning loop.&lt;/p&gt;

&lt;p&gt;Here's what that integration looks like in a Python agent setup using the EODHD MCP:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example: Claude SDK + EODHD MCP integration
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-opus-4-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mcp_servers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://mcpv2.eodhd.dev/v2/mcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eodhd-mcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Using EODHD data, get Apple&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s (AAPL.US) end-of-day prices &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;for the last 30 days and calculate the 10-day moving average.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Interactive Brokers has no equivalent. The IBKR API requires an open socket, a running GUI application, and explicit connection management — none of which fits the stateless, HTTP-native model that AI agents operate on.&lt;/p&gt;

&lt;p&gt;If you're building anything AI-powered on top of financial data in 2026, the integration model matters as much as the data itself.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
🤖 &lt;strong&gt;EODHD + MCP: financial data for AI agents&lt;/strong&gt;&lt;br&gt;
Connect your LLM pipeline to 70+ global exchanges in one step. No wrappers. No boilerplate. Just structured data your agent can actually use.&lt;br&gt;
👉 &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=interactive-brokers-api-vs-eodhd-financial-data-python&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Explore the EODHD MCP server&lt;/a&gt;&lt;br&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  When to Use Each One
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Interactive Brokers API when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're already an IBKR client and need to combine order execution with data in a single script&lt;/li&gt;
&lt;li&gt;You're building an algo trading system that needs to execute, not just analyze&lt;/li&gt;
&lt;li&gt;You're running a live trading strategy that requires real-time bid/ask data tied to your positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use EODHD when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a research tool, screener, or portfolio analyzer with no execution component&lt;/li&gt;
&lt;li&gt;You want to deploy a financial data pipeline on a cloud server without managing desktop software&lt;/li&gt;
&lt;li&gt;You're integrating market data into an AI agent, LLM pipeline, or MCP-based workflow&lt;/li&gt;
&lt;li&gt;You need global coverage across 70+ exchanges with consistent data structure&lt;/li&gt;
&lt;li&gt;You're prototyping — EODHD's free tier lets you validate the idea before committing to a plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The choice isn't really about which API is "better." It's about what your project actually needs.&lt;/p&gt;

&lt;p&gt;If your project needs to place orders: use IBKR.&lt;/p&gt;

&lt;p&gt;If your project needs clean, accessible, scalable financial data: EODHD is the obvious answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;❓ &lt;strong&gt;Can I use the Interactive Brokers API without a funded account?&lt;/strong&gt;&lt;br&gt;
✅ Yes, IBKR offers a paper trading account that gives you access to their API without real capital. However, you still need to register, get approved, and run TWS or IB Gateway locally. It's functional for testing but not suited for lightweight or server-based deployments.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Is EODHD free to use?&lt;/strong&gt;&lt;br&gt;
✅ EODHD has a free tier that includes end-of-day data for US exchanges with limited API calls. It's enough to prototype and evaluate the API structure. Paid plans start at $19.99/month and unlock fundamentals, global exchanges, bulk endpoints, and real-time data.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Does EODHD provide real-time stock data?&lt;/strong&gt;&lt;br&gt;
✅ EODHD provides delayed quotes (~15–20 minutes) on standard plans. Real-time data is available on higher-tier plans. For most research, backtesting, and AI agent use cases, delayed data is sufficient and significantly cheaper.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Can I use EODHD with an AI agent or LLM pipeline?&lt;/strong&gt;&lt;br&gt;
✅ Yes — this is one of EODHD's strongest advantages in 2026. EODHD has an official MCP server that makes it directly callable from Claude, Cursor, and any MCP-compatible agent. You don't need to build an API wrapper; you connect the server and your agent can query financial data natively within its reasoning loop.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;What's the best financial data API for Python developers in 2026?&lt;/strong&gt;&lt;br&gt;
✅ It depends on your use case. If you need trade execution, IBKR is the standard. If you need broad, clean, accessible financial data for analysis, AI, or research — EODHD covers more exchanges, requires less setup, and integrates natively with modern AI tooling via its MCP server.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The Interactive Brokers API is a serious tool. Well-maintained, deep, powerful.&lt;/p&gt;

&lt;p&gt;But it's built for traders, not data engineers.&lt;/p&gt;

&lt;p&gt;EODHD is built for the other use case: developers who need financial data as a clean input — in a notebook, on a server, inside an agent — without managing a brokerage session in the background.&lt;/p&gt;

&lt;p&gt;The gap widens further when you introduce AI agents into the equation. REST-native APIs with MCP support fit how modern LLM pipelines are built. Socket-based desktop APIs don't.&lt;/p&gt;

&lt;p&gt;Choose the tool that matches your architecture, not just your data needs.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
📦 &lt;strong&gt;Ready to drop the overhead?&lt;/strong&gt;&lt;br&gt;
EODHD gives you 70+ exchanges, 30 years of history, fundamentals, macro data, and an MCP server — all under one API key. Start free, scale when you need to.&lt;br&gt;
👉 &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=interactive-brokers-api-vs-eodhd-financial-data-python&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Start with EODHD free tier&lt;/a&gt;&lt;br&gt;

&lt;/div&gt;





&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>mcp</category>
      <category>stocks</category>
      <category>trading</category>
    </item>
    <item>
      <title>5 Powerful MCP Use Cases for Financial AI Agents in 2026</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Sun, 24 May 2026 10:43:27 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/5-powerful-mcp-use-cases-for-financial-ai-agents-in-2026-3dm</link>
      <guid>https://dev.to/kevin_menesesgonzlez/5-powerful-mcp-use-cases-for-financial-ai-agents-in-2026-3dm</guid>
      <description>&lt;p&gt;Most people still use AI like it's a smarter Google.&lt;/p&gt;

&lt;p&gt;They open ChatGPT or Claude… ask a few questions… copy a few answers… and that's it.&lt;/p&gt;

&lt;p&gt;But something massive is changing right now.&lt;/p&gt;

&lt;p&gt;AI is evolving from "chatbots" into systems that can actually work with real-world tools and live data.&lt;/p&gt;

&lt;p&gt;And one of the biggest reasons is MCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; is quietly becoming the bridge between LLMs and external systems.&lt;/p&gt;

&lt;p&gt;Instead of asking an AI generic questions… you can now connect it directly to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;financial APIs&lt;/li&gt;
&lt;li&gt;live market data&lt;/li&gt;
&lt;li&gt;trading systems&lt;/li&gt;
&lt;li&gt;research workflows&lt;/li&gt;
&lt;li&gt;automated decision pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem? Most developers still don't understand how powerful this becomes when combined with financial data.&lt;/p&gt;

&lt;p&gt;Without real-time context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI hallucinate prices&lt;/li&gt;
&lt;li&gt;invent earnings numbers&lt;/li&gt;
&lt;li&gt;provide outdated market information&lt;/li&gt;
&lt;li&gt;generate unreliable trading insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which makes them useless for serious financial workflows.&lt;/p&gt;

&lt;p&gt;That's where MCP changes the game.&lt;/p&gt;

&lt;p&gt;By connecting LLMs to live financial APIs like EODHD APIs, you can build AI agents that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analyze markets&lt;/li&gt;
&lt;li&gt;evaluate companies&lt;/li&gt;
&lt;li&gt;summarize financial news&lt;/li&gt;
&lt;li&gt;generate trading signals&lt;/li&gt;
&lt;li&gt;automate research pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we'll explore 5 practical MCP use cases for financial AI agents — including real-world ideas developers can build today.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is MCP (Model Context Protocol)?
&lt;/h2&gt;

&lt;p&gt;MCP is essentially a standardized way for AI models to interact with external tools and systems.&lt;/p&gt;

&lt;p&gt;Instead of working only with training data, the model can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request live information&lt;/li&gt;
&lt;li&gt;access APIs&lt;/li&gt;
&lt;li&gt;interact with databases&lt;/li&gt;
&lt;li&gt;execute workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think about it like giving Claude or ChatGPT "real-time financial senses".&lt;/p&gt;

&lt;p&gt;And this becomes incredibly powerful in finance because markets are dynamic. Yesterday's data is already old.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why MCP Matters for Financial AI
&lt;/h2&gt;

&lt;p&gt;Financial AI agents fail for one main reason: they don't have reliable context.&lt;/p&gt;

&lt;p&gt;Without live data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;valuations become outdated&lt;/li&gt;
&lt;li&gt;technical indicators become inaccurate&lt;/li&gt;
&lt;li&gt;earnings analysis becomes irrelevant&lt;/li&gt;
&lt;li&gt;trading decisions become dangerous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connecting MCP with a live financial data provider like EODHD APIs solves this problem.&lt;/p&gt;

&lt;p&gt;You can feed your AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;real-time stock prices&lt;/li&gt;
&lt;li&gt;fundamentals&lt;/li&gt;
&lt;li&gt;earnings&lt;/li&gt;
&lt;li&gt;insider transactions&lt;/li&gt;
&lt;li&gt;news sentiment&lt;/li&gt;
&lt;li&gt;technical indicators&lt;/li&gt;
&lt;li&gt;macroeconomic data&lt;/li&gt;
&lt;li&gt;historical OHLC data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the AI is no longer "guessing". It's analyzing reality.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=5-powerful-mcp-use-cases-for-financial-ai-agents-in-2026-422a2105f7c0&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Explore EODHD APIs&lt;/a&gt;&lt;/strong&gt; — Real-time market data, fundamentals, news, and technical indicators for financial AI agents.&lt;br&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  1. AI-Powered Portfolio Research Agent
&lt;/h2&gt;

&lt;p&gt;One of the best MCP use cases is building a portfolio research assistant.&lt;/p&gt;

&lt;p&gt;Instead of manually opening Yahoo Finance, earnings reports, news websites, and spreadsheets… you can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Analyze my portfolio risk exposure and summarize the biggest concerns."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetch live prices&lt;/li&gt;
&lt;li&gt;analyze volatility&lt;/li&gt;
&lt;li&gt;compare sector exposure&lt;/li&gt;
&lt;li&gt;summarize news&lt;/li&gt;
&lt;li&gt;detect concentration risk&lt;/li&gt;
&lt;li&gt;explain drawdowns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NVIDIA overweight exposure&lt;/li&gt;
&lt;li&gt;excessive tech correlation&lt;/li&gt;
&lt;li&gt;weak diversification&lt;/li&gt;
&lt;li&gt;unusual volatility spikes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This transforms AI into a true investment research companion.&lt;/p&gt;

&lt;p&gt;And because the data comes through MCP using EODHD APIs, the analysis is grounded in real financial information instead of hallucinations.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. AI Earnings Analysis Agent
&lt;/h2&gt;

&lt;p&gt;Earnings season creates information overload.&lt;/p&gt;

&lt;p&gt;Thousands of reports. Conference calls. Guidance updates. Revenue surprises.&lt;/p&gt;

&lt;p&gt;Most traders simply cannot process all of it fast enough.&lt;/p&gt;

&lt;p&gt;An MCP-powered AI agent can automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieve earnings data&lt;/li&gt;
&lt;li&gt;summarize reports&lt;/li&gt;
&lt;li&gt;compare quarter-over-quarter growth&lt;/li&gt;
&lt;li&gt;detect guidance changes&lt;/li&gt;
&lt;li&gt;explain what matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What were the most important insights from Tesla's latest earnings report?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI could instantly summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;revenue growth&lt;/li&gt;
&lt;li&gt;margins&lt;/li&gt;
&lt;li&gt;AI investments&lt;/li&gt;
&lt;li&gt;automotive delivery numbers&lt;/li&gt;
&lt;li&gt;management guidance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the most practical real-world use cases for financial AI — especially for investors, analysts, fintech startups, and trading communities.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. AI Trading Signal Generator
&lt;/h2&gt;

&lt;p&gt;This is where things get really interesting.&lt;/p&gt;

&lt;p&gt;Using MCP + market data APIs, you can create AI agents that combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical indicators&lt;/li&gt;
&lt;li&gt;news sentiment&lt;/li&gt;
&lt;li&gt;volume analysis&lt;/li&gt;
&lt;li&gt;price action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RSI oversold&lt;/li&gt;
&lt;li&gt;unusual trading volume&lt;/li&gt;
&lt;li&gt;positive earnings sentiment&lt;/li&gt;
&lt;li&gt;bullish momentum breakout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI agent can then explain &lt;em&gt;why&lt;/em&gt; a signal exists instead of just showing numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example output:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Apple shows bullish momentum after earnings, supported by increasing volume and positive AI-related news sentiment."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is far more useful than traditional black-box indicators.&lt;/p&gt;

&lt;p&gt;And with EODHD APIs, developers can access historical market data, technical indicators, real-time prices, and financial news APIs — perfect for algorithmic trading workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Autonomous Market News Intelligence Agent
&lt;/h2&gt;

&lt;p&gt;Most traders consume too much information and still miss what matters.&lt;/p&gt;

&lt;p&gt;Financial news is overwhelming. A smarter approach is building an AI filtering layer.&lt;/p&gt;

&lt;p&gt;With MCP, your AI agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monitor market news&lt;/li&gt;
&lt;li&gt;detect unusual events&lt;/li&gt;
&lt;li&gt;summarize key developments&lt;/li&gt;
&lt;li&gt;prioritize important stories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of reading 100 headlines… you receive 5 critical events, summarized in plain English, with market implications attached.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Semiconductor stocks are rising after new AI infrastructure spending announcements."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Oil prices dropped after unexpected inventory data."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This becomes incredibly valuable for swing traders, macro investors, and busy professionals.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. AI-Powered Quant Research Assistant
&lt;/h2&gt;

&lt;p&gt;This is probably the most exciting long-term use case.&lt;/p&gt;

&lt;p&gt;Imagine an AI assistant capable of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;testing trading ideas&lt;/li&gt;
&lt;li&gt;analyzing correlations&lt;/li&gt;
&lt;li&gt;explaining strategy performance&lt;/li&gt;
&lt;li&gt;generating research insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Find momentum-based strategies that performed well during high-volatility periods."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Compare mean reversion performance across tech stocks over the last 10 years."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI can use historical data, volatility metrics, technical indicators, and statistical analysis tools.&lt;/p&gt;

&lt;p&gt;This dramatically reduces research time for quantitative traders.&lt;/p&gt;

&lt;p&gt;And when combined with Python frameworks like &lt;code&gt;pandas&lt;/code&gt;, &lt;code&gt;vectorbt&lt;/code&gt;, &lt;code&gt;backtesting.py&lt;/code&gt;, or Streamlit, you can build incredibly powerful systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why EODHD APIs Fit Perfectly for MCP Workflows
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges when building financial AI agents is finding reliable data infrastructure.&lt;/p&gt;

&lt;p&gt;That's why EODHD APIs are especially interesting for MCP-based workflows.&lt;/p&gt;

&lt;p&gt;They provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;real-time market data&lt;/li&gt;
&lt;li&gt;historical OHLC data&lt;/li&gt;
&lt;li&gt;financial fundamentals&lt;/li&gt;
&lt;li&gt;earnings&lt;/li&gt;
&lt;li&gt;economic events&lt;/li&gt;
&lt;li&gt;technical indicators&lt;/li&gt;
&lt;li&gt;financial news APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which means developers can build AI agents, trading dashboards, automated research systems, and quant workflows — without stitching together multiple fragmented providers.&lt;/p&gt;

&lt;p&gt;If you want to experiment with AI-powered finance projects, it's honestly one of the best places to start.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=5-powerful-mcp-use-cases-for-financial-ai-agents-in-2026-422a2105f7c0&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Explore EODHD APIs&lt;/a&gt;&lt;/strong&gt; — Real-time market data, fundamentals, news, and technical indicators for financial AI agents.&lt;br&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Most people still think AI is about generating text.&lt;/p&gt;

&lt;p&gt;But the real shift is happening somewhere else.&lt;/p&gt;

&lt;p&gt;AI is becoming operational. Connected. Context-aware. Integrated with real systems.&lt;/p&gt;

&lt;p&gt;And finance is one of the industries where this transformation will happen fastest.&lt;/p&gt;

&lt;p&gt;Because whoever can process information faster, filter noise better, and automate financial research… will have a massive advantage.&lt;/p&gt;

&lt;p&gt;MCP is one of the most important pieces enabling that future.&lt;/p&gt;

&lt;p&gt;And we're still extremely early.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>api</category>
      <category>mcp</category>
      <category>claude</category>
      <category>ai</category>
    </item>
    <item>
      <title>The 5 Best OCR APIs for Developers in 2026 (Compared)</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Fri, 22 May 2026 08:54:32 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/the-5-best-ocr-apis-for-developers-in-2026-compared-55p9</link>
      <guid>https://dev.to/kevin_menesesgonzlez/the-5-best-ocr-apis-for-developers-in-2026-compared-55p9</guid>
      <description>&lt;p&gt;Most developers underestimate how painful document processing still is.&lt;/p&gt;

&lt;p&gt;Invoices. PDFs. Receipts. Contracts. Financial reports.&lt;/p&gt;

&lt;p&gt;A huge amount of business data is still trapped inside documents.&lt;/p&gt;

&lt;p&gt;And most teams still solve this problem the same way they did 10 years ago:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manual copy-paste,&lt;/li&gt;
&lt;li&gt;fragile OCR tools,&lt;/li&gt;
&lt;li&gt;messy spreadsheets,&lt;/li&gt;
&lt;li&gt;broken automations,&lt;/li&gt;
&lt;li&gt;and workflows that collapse the moment a PDF layout changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now combine that with the rise of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents,&lt;/li&gt;
&lt;li&gt;RAG systems,&lt;/li&gt;
&lt;li&gt;automation pipelines,&lt;/li&gt;
&lt;li&gt;and LLM workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly, extracting clean structured data from documents becomes one of the most important layers in the entire AI stack.&lt;/p&gt;

&lt;p&gt;That's why OCR APIs and document parsing platforms are exploding right now.&lt;/p&gt;

&lt;p&gt;But not all tools are built the same.&lt;/p&gt;

&lt;p&gt;Some are optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developer workflows,&lt;/li&gt;
&lt;li&gt;AI-native parsing,&lt;/li&gt;
&lt;li&gt;invoice automation,&lt;/li&gt;
&lt;li&gt;enterprise document ingestion,&lt;/li&gt;
&lt;li&gt;or RAG pipelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So after researching the current market, here are 5 OCR/document extraction APIs that stand out the most in 2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. LlamaParse (LlamaIndex)
&lt;/h2&gt;

&lt;p&gt;LlamaParse is probably the most interesting OCR/document parsing platform right now for AI engineers.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because it's not just "OCR".&lt;/p&gt;

&lt;p&gt;It's built specifically for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLMs,&lt;/li&gt;
&lt;li&gt;AI agents,&lt;/li&gt;
&lt;li&gt;and RAG systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference matters.&lt;/p&gt;

&lt;p&gt;Traditional OCR extracts text. LlamaParse tries to preserve semantic structure and context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAG systems&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;Financial reports&lt;/li&gt;
&lt;li&gt;Complex PDFs&lt;/li&gt;
&lt;li&gt;LLM ingestion pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-native parsing&lt;/li&gt;
&lt;li&gt;Markdown and JSON outputs&lt;/li&gt;
&lt;li&gt;Advanced table extraction&lt;/li&gt;
&lt;li&gt;Multi-modal parsing&lt;/li&gt;
&lt;li&gt;Agentic parsing modes&lt;/li&gt;
&lt;li&gt;Complex layout understanding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free tier available&lt;/li&gt;
&lt;li&gt;Credit-based pricing&lt;/li&gt;
&lt;li&gt;Around 10,000 free credits/pages monthly depending on parsing mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excellent for complex PDFs&lt;/li&gt;
&lt;li&gt;Built for AI workflows&lt;/li&gt;
&lt;li&gt;Strong parsing quality&lt;/li&gt;
&lt;li&gt;Great ecosystem for developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More expensive at scale&lt;/li&gt;
&lt;li&gt;Overkill for simple OCR use cases&lt;/li&gt;
&lt;li&gt;Requires understanding of RAG/LLM workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Mindee
&lt;/h2&gt;

&lt;p&gt;Mindee is one of the most developer-friendly OCR APIs available today.&lt;/p&gt;

&lt;p&gt;Fast setup. Excellent documentation. Very practical APIs.&lt;/p&gt;

&lt;p&gt;This is the kind of tool developers love because you can go from "PDF chaos" to "working automation" in a few hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python developers&lt;/li&gt;
&lt;li&gt;OCR automation&lt;/li&gt;
&lt;li&gt;Invoice extraction&lt;/li&gt;
&lt;li&gt;Receipt OCR&lt;/li&gt;
&lt;li&gt;API integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invoice OCR&lt;/li&gt;
&lt;li&gt;Receipt OCR&lt;/li&gt;
&lt;li&gt;Passport/document parsing&lt;/li&gt;
&lt;li&gt;Python SDK&lt;/li&gt;
&lt;li&gt;API-first architecture&lt;/li&gt;
&lt;li&gt;Batch processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starter plan: ~€44/month&lt;/li&gt;
&lt;li&gt;500 pages included&lt;/li&gt;
&lt;li&gt;Usage-based scaling available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely developer-friendly&lt;/li&gt;
&lt;li&gt;Great documentation&lt;/li&gt;
&lt;li&gt;Strong API ecosystem&lt;/li&gt;
&lt;li&gt;Fast implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less focused on advanced RAG&lt;/li&gt;
&lt;li&gt;Enterprise AI features more limited than some competitors&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Nanonets
&lt;/h2&gt;

&lt;p&gt;Nanonets sits somewhere between OCR platform, AI workflow engine, and automation suite.&lt;/p&gt;

&lt;p&gt;Instead of focusing only on extraction, they focus heavily on business automation.&lt;/p&gt;

&lt;p&gt;This makes it attractive for companies that want OCR, approvals, integrations, AI extraction, and workflows together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business automation&lt;/li&gt;
&lt;li&gt;Finance operations&lt;/li&gt;
&lt;li&gt;Invoice processing&lt;/li&gt;
&lt;li&gt;AI document workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI OCR&lt;/li&gt;
&lt;li&gt;Workflow automation&lt;/li&gt;
&lt;li&gt;Table extraction&lt;/li&gt;
&lt;li&gt;ERP integrations&lt;/li&gt;
&lt;li&gt;Email ingestion&lt;/li&gt;
&lt;li&gt;Approval systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free credits available&lt;/li&gt;
&lt;li&gt;Pay-as-you-go model&lt;/li&gt;
&lt;li&gt;Enterprise plans available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strong automation capabilities&lt;/li&gt;
&lt;li&gt;Enterprise-friendly&lt;/li&gt;
&lt;li&gt;Powerful extraction workflows&lt;/li&gt;
&lt;li&gt;Good UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less developer-focused&lt;/li&gt;
&lt;li&gt;Can become expensive with volume&lt;/li&gt;
&lt;li&gt;More business-oriented than technical&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Veryfi
&lt;/h2&gt;

&lt;p&gt;Veryfi is heavily specialized in receipts, invoices, bookkeeping, and financial OCR.&lt;/p&gt;

&lt;p&gt;And honestly, that focus is a strength.&lt;/p&gt;

&lt;p&gt;Instead of trying to solve every OCR problem, they dominate a very specific niche extremely well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fintech&lt;/li&gt;
&lt;li&gt;Expense management&lt;/li&gt;
&lt;li&gt;Accounting automation&lt;/li&gt;
&lt;li&gt;Receipt scanning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receipt OCR&lt;/li&gt;
&lt;li&gt;Invoice extraction&lt;/li&gt;
&lt;li&gt;Expense categorization&lt;/li&gt;
&lt;li&gt;Fraud detection&lt;/li&gt;
&lt;li&gt;Mobile OCR&lt;/li&gt;
&lt;li&gt;Financial automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API-based pricing&lt;/li&gt;
&lt;li&gt;Enterprise-focused plans&lt;/li&gt;
&lt;li&gt;Free trial available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very accurate for receipts/invoices&lt;/li&gt;
&lt;li&gt;Strong financial workflows&lt;/li&gt;
&lt;li&gt;Good mobile support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Narrower use cases&lt;/li&gt;
&lt;li&gt;Less useful for general-purpose document parsing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Docparser
&lt;/h2&gt;

&lt;p&gt;Docparser is one of those tools you understand in 30 seconds.&lt;/p&gt;

&lt;p&gt;Upload a PDF. Extract structured data automatically. Connect it to Zapier, Make, or n8n. And remove hours of manual work.&lt;/p&gt;

&lt;p&gt;It doesn't try to be an "AI operating system." And honestly, that's part of the appeal.&lt;/p&gt;

&lt;p&gt;It's extremely focused on solving one problem well: extracting structured data from documents reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business automation&lt;/li&gt;
&lt;li&gt;Invoice extraction&lt;/li&gt;
&lt;li&gt;PDF workflows&lt;/li&gt;
&lt;li&gt;No-code automation&lt;/li&gt;
&lt;li&gt;Operations teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OCR + PDF parsing&lt;/li&gt;
&lt;li&gt;Table extraction&lt;/li&gt;
&lt;li&gt;Template-based parsing&lt;/li&gt;
&lt;li&gt;Zapier integrations&lt;/li&gt;
&lt;li&gt;Email parsing&lt;/li&gt;
&lt;li&gt;API access&lt;/li&gt;
&lt;li&gt;Export to Excel/CSV/JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starter plan around $39/month&lt;/li&gt;
&lt;li&gt;Professional plans available&lt;/li&gt;
&lt;li&gt;Free trial included&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very easy to use&lt;/li&gt;
&lt;li&gt;Great for automations&lt;/li&gt;
&lt;li&gt;Fast setup&lt;/li&gt;
&lt;li&gt;Strong integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less AI-native than LlamaParse&lt;/li&gt;
&lt;li&gt;Complex documents may require setup&lt;/li&gt;
&lt;li&gt;More template-driven&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;AI-Native&lt;/th&gt;
&lt;th&gt;Pricing Model&lt;/th&gt;
&lt;th&gt;Developer-Friendly&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LlamaParse&lt;/td&gt;
&lt;td&gt;RAG / LLM pipelines&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Credits&lt;/td&gt;
&lt;td&gt;✅ High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mindee&lt;/td&gt;
&lt;td&gt;Invoice / receipt OCR&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Per page&lt;/td&gt;
&lt;td&gt;✅ Very High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nanonets&lt;/td&gt;
&lt;td&gt;Business automation&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Pay-as-you-go&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Veryfi&lt;/td&gt;
&lt;td&gt;Fintech / expenses&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;API-based&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docparser&lt;/td&gt;
&lt;td&gt;No-code automation&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;Monthly plan&lt;/td&gt;
&lt;td&gt;✅ High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The OCR market is no longer just about extracting text.&lt;/p&gt;

&lt;p&gt;The real opportunity now is building systems that &lt;strong&gt;understand&lt;/strong&gt; documents.&lt;/p&gt;

&lt;p&gt;And the companies that solve this layer well will become critical infrastructure for AI agents, automation, RAG systems, fintech, and enterprise AI workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the best OCR API for developers?&lt;/strong&gt;&lt;br&gt;
Mindee is probably the best balance between ease of use, pricing, documentation, and developer experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which OCR tool is best for RAG systems?&lt;/strong&gt;&lt;br&gt;
LlamaParse and Unstructured are currently among the strongest options for AI-native document pipelines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which OCR API is best for invoices and receipts?&lt;/strong&gt;&lt;br&gt;
Veryfi, Mindee, and Nanonets are excellent for financial documents and expense automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are OCR APIs expensive?&lt;/strong&gt;&lt;br&gt;
Most platforms now offer free tiers, pay-as-you-go pricing, or credit systems. Costs mainly depend on document volume and complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can OCR APIs work with Python?&lt;/strong&gt;&lt;br&gt;
Yes. All the platforms mentioned here provide APIs and Python integrations.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>automation</category>
      <category>tooling</category>
    </item>
    <item>
      <title>You're Probably Calculating Your Returns Wrong: The Math Behind True Portfolio Performance</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Thu, 21 May 2026 12:27:44 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/youre-probably-calculating-your-returns-wrong-the-math-behind-true-portfolio-performance-1od8</link>
      <guid>https://dev.to/kevin_menesesgonzlez/youre-probably-calculating-your-returns-wrong-the-math-behind-true-portfolio-performance-1od8</guid>
      <description>&lt;p&gt;My broker told me I was up 12% last year.&lt;/p&gt;

&lt;p&gt;The real number, once I accounted for currency conversion losses and the timing of my capital additions, was closer to 7%.&lt;/p&gt;

&lt;p&gt;That's not a rounding error. That's a 5-point gap that changes how you evaluate every decision you made that year.&lt;/p&gt;

&lt;p&gt;If you invest across multiple brokers, hold assets in different currencies, or move capital in and out of positions throughout the year, the return number your broker shows you is almost certainly wrong. Not maliciously. Just structurally. Broker dashboards are not built to calculate true portfolio performance. They're built to show you activity on their platform.&lt;/p&gt;

&lt;p&gt;There's a difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Broker Return Numbers Are Misleading
&lt;/h2&gt;

&lt;p&gt;Every broker calculates returns differently. And most of them use the simplest possible method: they compare your current value to your starting value and call it a return.&lt;/p&gt;

&lt;p&gt;That works fine if you invested a lump sum on January 1st and never touched it.&lt;/p&gt;

&lt;p&gt;It breaks immediately the moment you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add capital mid-year&lt;/li&gt;
&lt;li&gt;Withdraw funds at any point&lt;/li&gt;
&lt;li&gt;Hold positions in a different currency than your base&lt;/li&gt;
&lt;li&gt;Pay transaction fees, custody fees, or conversion spreads&lt;/li&gt;
&lt;li&gt;Split your portfolio across multiple platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is to say: it breaks for almost every real investor.&lt;/p&gt;




&lt;h2&gt;
  
  
  TWR vs MWR: The Two Numbers You Need to Understand
&lt;/h2&gt;

&lt;p&gt;There are two ways to measure portfolio return properly. Most investors have never heard of either.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time-Weighted Return (TWR)
&lt;/h3&gt;

&lt;p&gt;TWR eliminates the effect of external cash flows — deposits and withdrawals — so you can evaluate the performance of your investment strategy independently of when you added or removed money.&lt;/p&gt;

&lt;p&gt;It answers the question: how well did my portfolio perform, regardless of my timing decisions?&lt;/p&gt;

&lt;p&gt;TWR is the standard used by professional fund managers. It's the number that lets you compare your strategy against a benchmark fairly.&lt;/p&gt;

&lt;p&gt;Calculating it manually requires breaking your portfolio into sub-periods every time cash flows in or out, computing the return for each sub-period, and chain-linking them multiplicatively. For a portfolio with monthly contributions across four brokers, that's dozens of calculations per year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Money-Weighted Return (MWR)
&lt;/h3&gt;

&lt;p&gt;MWR — also called IRR at the portfolio level — accounts for the size and timing of your cash flows. It answers a different question: how well did my money actually perform, given when I deployed it?&lt;/p&gt;

&lt;p&gt;If you added a large amount right before a market drop, your MWR will be lower than your TWR. If you happened to invest heavily before a rally, it'll be higher. MWR reflects the reality of your specific decisions.&lt;/p&gt;

&lt;p&gt;Neither metric is "better." They answer different questions. The problem is that most brokers show you neither — they show you a simplified gain/loss percentage that conflates both and accounts for neither properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Currency Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;If you hold USD-denominated assets and your base currency is EUR, your broker's return figure is almost certainly calculated in USD.&lt;/p&gt;

&lt;p&gt;That matters more than most investors realize.&lt;/p&gt;

&lt;p&gt;A position up 15% in USD terms might be up only 7% in EUR terms if the dollar weakened during your holding period. Or it might show 20% if the dollar strengthened. The currency movement is not a minor adjustment — in volatile years it can be larger than the underlying asset's return.&lt;/p&gt;

&lt;p&gt;My own experience: a 5–10% gap between what the broker showed and what I actually had after converting back to euros. Not because the broker was wrong in their own terms. Because their terms weren't my terms.&lt;/p&gt;

&lt;p&gt;A true return calculation has to be done in your base currency. Every position, every dividend, every fee — converted at the rate applicable on the date of the transaction.&lt;/p&gt;

&lt;p&gt;No broker does this automatically across multiple platforms. No spreadsheet maintains this accurately over time without constant manual intervention.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Costs That Erode Real Returns
&lt;/h2&gt;

&lt;p&gt;Currency conversion fees and spreads are the most underestimated drag on retail investor returns.&lt;/p&gt;

&lt;p&gt;On Degiro, currency conversion carries a fee that applies every time you buy or sell a non-EUR asset. It's small per transaction. Across a year of activity, it compounds.&lt;/p&gt;

&lt;p&gt;Neither of these shows up in the return figure your broker displays. They're already baked into your prices, invisible unless you calculate them explicitly.&lt;/p&gt;

&lt;p&gt;Add custody fees, inactivity fees, and any platform-specific charges, and the gap between headline return and true return widens further.&lt;/p&gt;

&lt;p&gt;The math isn't complicated. But doing it manually, across four platforms, in multiple currencies, for every transaction in a year — that's the problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  What True Return Calculation Looks Like by Hand
&lt;/h2&gt;

&lt;p&gt;Let's make the complexity concrete. Suppose you want to calculate your MWR for the year across your portfolio.&lt;/p&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The starting value of your portfolio on January 1st&lt;/li&gt;
&lt;li&gt;Every cash inflow (deposits, dividends received) with exact dates&lt;/li&gt;
&lt;li&gt;Every cash outflow (withdrawals, fees paid) with exact dates&lt;/li&gt;
&lt;li&gt;The ending value on December 31st&lt;/li&gt;
&lt;li&gt;All of the above converted to your base currency at the exchange rate on each transaction date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you solve for the rate &lt;code&gt;r&lt;/code&gt; in this equation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ending Value = Starting Value × (1+r)^t 
               + CF₁ × (1+r)^(t-t₁) 
               + CF₂ × (1+r)^(t-t₂) 
               + ... CFₙ × (1+r)^(t-tₙ)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Where each &lt;code&gt;CF&lt;/code&gt; is a cash flow and each &lt;code&gt;t&lt;/code&gt; is the fraction of the year remaining at the time of that cash flow.&lt;/p&gt;

&lt;p&gt;This requires numerical iteration to solve — there's no closed-form algebraic answer. In Excel it's the &lt;code&gt;XIRR&lt;/code&gt; function. By hand it's trial and error.&lt;/p&gt;

&lt;p&gt;Now multiply that by four brokers, twelve months of dividends, currency conversions at different rates on different dates, and exchange-specific fees.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09lu0bulshga5cjp9fnm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09lu0bulshga5cjp9fnm.png" alt=" " width="720" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a calculation problem you solve with a better spreadsheet. It's an integration problem — you need software that connects to your accounts, ingests transaction data automatically, applies the correct exchange rates, and computes the result continuously.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Snowball Shows You Instead
&lt;/h2&gt;

&lt;p&gt;Snowball Analytics does this automatically.&lt;/p&gt;

&lt;p&gt;Every position across your connected brokers is tracked in your base currency. Returns are calculated using proper methodology — accounting for cash flow timing, currency movements, and fees. The number you see is your actual return, not your broker's simplified approximation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4zy5uucfaf2snqris9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4zy5uucfaf2snqris9b.png" alt=" " width="720" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference isn't cosmetic. For an investor with a multi-currency, multi-broker portfolio, the gap between a broker's headline number and a properly calculated return can be 5–10 percentage points. That's the difference between thinking your strategy is working and knowing whether it actually is.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://snowball-analytics.com" rel="noopener noreferrer"&gt;See your true portfolio return with Snowball Analytics&lt;/a&gt;&lt;/strong&gt; — Multi-broker, multi-currency portfolio tracking with proper TWR/MWR methodology.&lt;br&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why This Matters for Every Decision You Make
&lt;/h2&gt;

&lt;p&gt;Return calculation isn't academic. It drives every allocation decision you make.&lt;/p&gt;

&lt;p&gt;If you think a strategy is returning 12% when it's actually returning 7%, you'll keep deploying capital into it. You'll benchmark it against alternatives incorrectly. You'll attribute performance to skill that was actually currency tailwind — or miss underperformance that was hidden by currency movement.&lt;/p&gt;

&lt;p&gt;Conversely, a strategy that looks like 6% in your broker app might actually be 11% once you account for dividend reinvestment timing and a favorable exchange rate. That position deserves more capital, not a review.&lt;/p&gt;

&lt;p&gt;The numbers your broker shows you are not wrong. They're just incomplete. And in investing, incomplete information and wrong information produce the same outcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Benchmark Question
&lt;/h2&gt;

&lt;p&gt;Once you have a true return number, the next question is: compared to what?&lt;/p&gt;

&lt;p&gt;A 9% return sounds good. Against the S&amp;amp;P 500 returning 15% in the same period, it's underperformance. Against a bond portfolio returning 4%, it's strong outperformance. Against a passive ETF with lower risk and zero time cost, it might not justify the complexity.&lt;/p&gt;

&lt;p&gt;You can't answer this question with a broker's simplified return figure. You need TWR — the methodology that strips out your cash flow timing and gives you a clean strategy-level number comparable to any benchmark.&lt;/p&gt;

&lt;p&gt;That's the number that tells you whether your active decisions are adding value, or whether you'd be better off in a simple index fund and spending those 10 hours a month on something else.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>stocks</category>
      <category>investing</category>
      <category>data</category>
      <category>finance</category>
    </item>
    <item>
      <title>I Built an AI Hedge Fund Analyst Using Claude + EODHD APIs</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Tue, 19 May 2026 08:01:51 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/i-built-an-ai-hedge-fund-analyst-using-claude-eodhd-apis-4b34</link>
      <guid>https://dev.to/kevin_menesesgonzlez/i-built-an-ai-hedge-fund-analyst-using-claude-eodhd-apis-4b34</guid>
      <description>&lt;p&gt;Most people use AI for finance the wrong way.&lt;/p&gt;

&lt;p&gt;They open ChatGPT.&lt;/p&gt;

&lt;p&gt;They ask: &lt;em&gt;"Should I buy Nvidia?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And then they expect a useful answer.&lt;/p&gt;

&lt;p&gt;But there is one big problem:&lt;/p&gt;

&lt;p&gt;AI does not magically know what is happening in the market right now.&lt;/p&gt;

&lt;p&gt;It can sound confident. It can write a beautiful explanation. It can even give you a clean bullish or bearish thesis.&lt;/p&gt;

&lt;p&gt;But without real financial data, it is mostly guessing.&lt;/p&gt;

&lt;p&gt;And guessing is not analysis.&lt;/p&gt;

&lt;p&gt;That is why I wanted to build something different.&lt;/p&gt;

&lt;p&gt;Not another chatbot. Not another "AI stock picker." Not a toy project.&lt;/p&gt;

&lt;p&gt;I wanted to build a small version of what a hedge fund analyst might use every morning: an AI system that can read financial data, analyze news, review fundamentals, detect risks, and generate a useful market summary.&lt;/p&gt;

&lt;p&gt;So I built an AI hedge fund analyst using Claude and EODHD APIs.&lt;/p&gt;

&lt;p&gt;Here is the step-by-step process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Understand the Real Problem
&lt;/h2&gt;

&lt;p&gt;The problem is not that AI is bad at finance.&lt;/p&gt;

&lt;p&gt;The problem is that most AI tools are disconnected from real financial data.&lt;/p&gt;

&lt;p&gt;A normal chatbot does not automatically know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the latest price&lt;/li&gt;
&lt;li&gt;recent volume changes&lt;/li&gt;
&lt;li&gt;current market news&lt;/li&gt;
&lt;li&gt;earnings surprises&lt;/li&gt;
&lt;li&gt;insider transactions&lt;/li&gt;
&lt;li&gt;valuation metrics&lt;/li&gt;
&lt;li&gt;revenue growth&lt;/li&gt;
&lt;li&gt;dividend history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in finance, outdated data is dangerous. A stock can look attractive based on old numbers. A company can look safe before earnings collapse. A bullish thesis can break after one bad guidance call.&lt;/p&gt;

&lt;p&gt;This is the key idea: &lt;strong&gt;AI is only as good as the data you give it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That became the foundation of the project. The goal was simple: connect Claude to real financial data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Define What the AI Analyst Should Do
&lt;/h2&gt;

&lt;p&gt;Before writing code, I defined the role of the system.&lt;/p&gt;

&lt;p&gt;I did not want a generic assistant. I wanted something closer to a junior hedge fund analyst.&lt;/p&gt;

&lt;p&gt;Its job would be to analyze a stock from multiple angles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Price action&lt;/li&gt;
&lt;li&gt;Fundamentals&lt;/li&gt;
&lt;li&gt;Recent news&lt;/li&gt;
&lt;li&gt;Earnings&lt;/li&gt;
&lt;li&gt;Risk factors&lt;/li&gt;
&lt;li&gt;Market sentiment&lt;/li&gt;
&lt;li&gt;Final summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output should not be: &lt;em&gt;"This stock looks good."&lt;/em&gt; That is useless.&lt;/p&gt;

&lt;p&gt;The output should be structured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bullish signals&lt;/li&gt;
&lt;li&gt;Bearish signals&lt;/li&gt;
&lt;li&gt;Key risks&lt;/li&gt;
&lt;li&gt;Data-backed observations&lt;/li&gt;
&lt;li&gt;Final analyst-style summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good AI financial analyst should not only give answers. It should show its reasoning based on data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Choose the Data Source
&lt;/h2&gt;

&lt;p&gt;This is where EODHD APIs became useful.&lt;/p&gt;

&lt;p&gt;For this type of project, I needed access to different types of financial data from one place.&lt;/p&gt;

&lt;p&gt;EODHD gives access to data like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;historical prices&lt;/li&gt;
&lt;li&gt;real-time and end-of-day market data&lt;/li&gt;
&lt;li&gt;fundamentals&lt;/li&gt;
&lt;li&gt;news&lt;/li&gt;
&lt;li&gt;earnings&lt;/li&gt;
&lt;li&gt;dividends&lt;/li&gt;
&lt;li&gt;splits&lt;/li&gt;
&lt;li&gt;insider transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters because an AI finance system becomes much more powerful when it can combine multiple signals.&lt;/p&gt;

&lt;p&gt;Price data alone is not enough. News alone is not enough. Fundamentals alone are not enough.&lt;/p&gt;

&lt;p&gt;The value comes from connecting everything. That is when the AI starts to behave less like a chatbot and more like an analyst.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
📊 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=i-built-an-ai-hedge-fund-analyst-using-claude-eodhd-apis-f912b0cf946a&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Try EODHD APIs free&lt;/a&gt;&lt;/strong&gt; — One API for historical prices, fundamentals, news, earnings, insider transactions, and more. Everything in this project runs on it.&lt;br&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Step 4: Build the Basic Architecture
&lt;/h2&gt;

&lt;p&gt;The architecture was simple. I did not want to overcomplicate it.&lt;/p&gt;

&lt;p&gt;The system had four main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User enters a ticker&lt;/li&gt;
&lt;li&gt;Python fetches financial data from EODHD APIs&lt;/li&gt;
&lt;li&gt;Claude analyzes the structured data&lt;/li&gt;
&lt;li&gt;The result is displayed in a dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftniqu20vy0t0a4ngvnl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftniqu20vy0t0a4ngvnl5.png" alt=" " width="720" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can make this more advanced later with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streamlit dashboard&lt;/li&gt;
&lt;li&gt;Telegram alerts&lt;/li&gt;
&lt;li&gt;Scheduled reports&lt;/li&gt;
&lt;li&gt;Database storage&lt;/li&gt;
&lt;li&gt;MCP server&lt;/li&gt;
&lt;li&gt;Email summaries&lt;/li&gt;
&lt;li&gt;Portfolio tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the first version should be simple. &lt;strong&gt;Simple systems get finished. Overcomplicated systems die in Notion.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Fetch Market Data
&lt;/h2&gt;

&lt;p&gt;The first signal is price action.&lt;/p&gt;

&lt;p&gt;For each ticker, I wanted to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current price&lt;/li&gt;
&lt;li&gt;recent performance&lt;/li&gt;
&lt;li&gt;volatility&lt;/li&gt;
&lt;li&gt;trend&lt;/li&gt;
&lt;li&gt;volume changes&lt;/li&gt;
&lt;li&gt;important price movements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives Claude context. Instead of asking: &lt;em&gt;"Analyze Apple stock."&lt;/em&gt; — you are giving it something more useful: &lt;em&gt;"Analyze Apple stock using this recent market data."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That small difference changes everything. The AI stops hallucinating and starts interpreting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Add Fundamentals
&lt;/h2&gt;

&lt;p&gt;Price tells you what the market is doing. Fundamentals tell you what the business is doing.&lt;/p&gt;

&lt;p&gt;So the next step was to collect company fundamentals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;revenue&lt;/li&gt;
&lt;li&gt;earnings&lt;/li&gt;
&lt;li&gt;profit margins&lt;/li&gt;
&lt;li&gt;debt&lt;/li&gt;
&lt;li&gt;valuation ratios&lt;/li&gt;
&lt;li&gt;cash flow&lt;/li&gt;
&lt;li&gt;dividend data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where the analysis becomes more serious. For example, Claude can compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;revenue growth vs valuation&lt;/li&gt;
&lt;li&gt;margins vs debt&lt;/li&gt;
&lt;li&gt;dividend yield vs payout ratio&lt;/li&gt;
&lt;li&gt;earnings growth vs stock performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is much better than a generic AI opinion. Now the model has actual business data to work with.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Add News Sentiment
&lt;/h2&gt;

&lt;p&gt;Markets move because of stories.&lt;/p&gt;

&lt;p&gt;Earnings matter. Interest rates matter. Regulation matters. Product launches matter. Management changes matter.&lt;/p&gt;

&lt;p&gt;So I added recent news data. This allows the AI analyst to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the current market narrative?&lt;/li&gt;
&lt;li&gt;Are recent headlines positive or negative?&lt;/li&gt;
&lt;li&gt;Is the stock moving because of news or technical momentum?&lt;/li&gt;
&lt;li&gt;Are there hidden risks in recent articles?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the most useful parts of the system. Because investors often look at the chart — but forget to ask: &lt;em&gt;"Why is this moving?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;News gives the AI the missing context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Add Earnings Data
&lt;/h2&gt;

&lt;p&gt;Earnings are where reality punches narratives in the face.&lt;/p&gt;

&lt;p&gt;A company can have a beautiful story. But if earnings disappoint, the market reacts.&lt;/p&gt;

&lt;p&gt;So I added earnings-related data. The AI analyst can now review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EPS trends&lt;/li&gt;
&lt;li&gt;earnings surprises&lt;/li&gt;
&lt;li&gt;revenue expectations&lt;/li&gt;
&lt;li&gt;past earnings reactions&lt;/li&gt;
&lt;li&gt;future earnings dates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates much better summaries. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The stock has strong momentum, but the next earnings report is a major risk because recent EPS growth has slowed."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the type of insight you want. Not perfect. Not financial advice. But useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: Add Insider Transactions
&lt;/h2&gt;

&lt;p&gt;This is one of the most interesting signals.&lt;/p&gt;

&lt;p&gt;Most retail investors ignore insider activity. But it can be valuable context.&lt;/p&gt;

&lt;p&gt;If executives are buying shares, that may signal confidence. If insiders are selling heavily, it does not always mean something bad — but it is worth noticing.&lt;/p&gt;

&lt;p&gt;The AI can summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recent insider buys&lt;/li&gt;
&lt;li&gt;recent insider sells&lt;/li&gt;
&lt;li&gt;transaction size&lt;/li&gt;
&lt;li&gt;patterns over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the analysis feel much more professional. Because now the system is not only looking at charts. It is looking at behavior. And behavior often says more than words.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Create the Claude Prompt
&lt;/h2&gt;

&lt;p&gt;This is where everything comes together. The prompt is the brain of the system.&lt;/p&gt;

&lt;p&gt;Here is a simple version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
You are an AI hedge fund analyst. Analyze the following stock using the data provided.

Ticker:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Market Data:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;market_data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Fundamentals:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fundamentals&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Recent News:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;news&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Earnings:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Insider Transactions:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;insider_transactions&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Return the analysis in this structure:
1. Executive Summary
2. Bullish Signals
3. Bearish Signals
4. Key Risks
5. News Sentiment
6. Fundamental Analysis
7. Final Analyst View

Important:
- Do not make up data.
- Only use the information provided.
- Be clear and concise.
- Mention uncertainty when data is incomplete.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is important: &lt;strong&gt;you must tell the model not to invent data.&lt;/strong&gt; Finance is not the place for creative writing. Unless you enjoy losing money with poetry.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
📊 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=i-built-an-ai-hedge-fund-analyst-using-claude-eodhd-apis-f912b0cf946a&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Try EODHD APIs free&lt;/a&gt;&lt;/strong&gt; — One API for historical prices, fundamentals, news, earnings, insider transactions, and more. Everything in this project runs on it.
&lt;h2&gt;
  
  
  
&lt;/h2&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 11: Generate the Analyst Report
&lt;/h2&gt;

&lt;p&gt;Once Claude receives the structured data, it can generate a report like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Executive Summary:
Apple shows stable fundamentals, but recent revenue growth appears limited
compared to its valuation.

Bullish Signals:
- Strong margins
- Consistent cash flow
- Positive recent news sentiment
- Stable long-term trend

Bearish Signals:
- High valuation
- Slower growth
- Potential earnings risk
- Insider selling activity

Final View:
The stock remains high quality, but the current valuation requires strong
future execution.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is much more useful than: &lt;em&gt;"Apple is a strong company."&lt;/em&gt; Everyone knows that.&lt;/p&gt;

&lt;p&gt;The goal is not to state the obvious. The goal is to connect signals.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 12: Build a Simple Dashboard
&lt;/h2&gt;

&lt;p&gt;The next step is visual. A good dashboard makes the project feel real.&lt;/p&gt;

&lt;p&gt;You can build it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streamlit&lt;/li&gt;
&lt;li&gt;Plotly&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;EODHD APIs&lt;/li&gt;
&lt;li&gt;Claude API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basic dashboard sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ticker input&lt;/li&gt;
&lt;li&gt;Price chart&lt;/li&gt;
&lt;li&gt;Key metrics&lt;/li&gt;
&lt;li&gt;News summary&lt;/li&gt;
&lt;li&gt;AI analyst report&lt;/li&gt;
&lt;li&gt;Risk score&lt;/li&gt;
&lt;li&gt;Final summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the article much stronger visually. Readers love seeing the actual system — not just theory. Screenshots are your best friend here.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 13: Automate the Workflow
&lt;/h2&gt;

&lt;p&gt;Once the system works manually, you can automate it.&lt;/p&gt;

&lt;p&gt;For example, every morning the system can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check your watchlist&lt;/li&gt;
&lt;li&gt;Fetch fresh market data&lt;/li&gt;
&lt;li&gt;Analyze news&lt;/li&gt;
&lt;li&gt;Detect unusual movements&lt;/li&gt;
&lt;li&gt;Generate an AI summary&lt;/li&gt;
&lt;li&gt;Send the report by email or Telegram&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns the project from "cool demo" into "real productivity tool."&lt;/p&gt;

&lt;p&gt;And that is where the article becomes more powerful. Because the reader thinks: &lt;em&gt;"I could actually use this."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is the sweet spot.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 14: The Big Lesson
&lt;/h2&gt;

&lt;p&gt;The most important lesson was not about Claude. It was not about Python. It was not even about finance.&lt;/p&gt;

&lt;p&gt;The real lesson was this: &lt;strong&gt;AI becomes useful when you connect it to the right data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without data, AI gives opinions. With data, AI can generate analysis. That is the difference.&lt;/p&gt;

&lt;p&gt;Most people are still using AI like a smarter Google search. But the real opportunity is building systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Systems that collect data&lt;/li&gt;
&lt;li&gt;Systems that analyze information&lt;/li&gt;
&lt;li&gt;Systems that summarize complexity&lt;/li&gt;
&lt;li&gt;Systems that help you make better decisions&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project changed how I think about AI in finance.&lt;/p&gt;

&lt;p&gt;The future is not just asking a chatbot: &lt;em&gt;"What stock should I buy?"&lt;/em&gt; That is too simple.&lt;/p&gt;

&lt;p&gt;The future is building AI systems that monitor markets, analyze data, detect signals, and help humans think better. Not replace thinking — improve it.&lt;/p&gt;

&lt;p&gt;And for that, you need two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A strong AI model&lt;/li&gt;
&lt;li&gt;Reliable financial data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude gives you the reasoning layer. EODHD APIs give you the financial data layer.&lt;/p&gt;

&lt;p&gt;Together, they allow you to build something much more interesting than another stock dashboard. You can build your own AI financial analyst.&lt;/p&gt;

&lt;p&gt;Not perfect. Not magic. But useful.&lt;/p&gt;

&lt;p&gt;And in a world full of noisy financial content, useful is already a massive advantage.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
📊 &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=i-built-an-ai-hedge-fund-analyst-using-claude-eodhd-apis-f912b0cf946a&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Try EODHD APIs free&lt;/a&gt;&lt;/strong&gt; — One API for historical prices, fundamentals, news, earnings, insider transactions, and more. Everything in this project runs on it.&lt;br&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>finance</category>
      <category>api</category>
      <category>stocks</category>
    </item>
    <item>
      <title>The Exact Framework I Use to Forecast My Dividends (And Why My Broker Can't Do This)</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Mon, 18 May 2026 14:06:40 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/the-exact-framework-i-use-to-forecast-my-dividends-and-why-my-broker-cant-do-this-372b</link>
      <guid>https://dev.to/kevin_menesesgonzlez/the-exact-framework-i-use-to-forecast-my-dividends-and-why-my-broker-cant-do-this-372b</guid>
      <description>&lt;p&gt;My goal with dividends is simple: build an income stream that runs without me.&lt;/p&gt;

&lt;p&gt;No checking prices every morning. No deciding whether to add more capital this month. Just positions that pay, compound, and grow — while I focus on other things.&lt;/p&gt;

&lt;p&gt;Between €500 and €1,000 a month in dividend income is the kind of number that changes how you think about money. It doesn't replace a salary. But it changes the math on every decision you make.&lt;/p&gt;

&lt;p&gt;The problem: getting to that number — and staying there — requires forecasting. And forecasting dividends across multiple brokers, in multiple currencies, with positions paying on different schedules, is exactly the kind of thing a spreadsheet cannot do reliably.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building a dividend income strategy across multiple accounts,&lt;/li&gt;
&lt;li&gt;trying to project future cash flow, not just track past payments,&lt;/li&gt;
&lt;li&gt;or tired of visiting 20 different websites to piece together what you'll earn next quarter,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Broker Dashboards Fail Dividend Investors
&lt;/h2&gt;

&lt;p&gt;Every broker shows you a yield. That's the easy part.&lt;/p&gt;

&lt;p&gt;What they don't show you: whether that yield is growing, shrinking, or about to be cut. Whether your income is concentrated in one sector. Whether your portfolio will generate more or less next year than it does today.&lt;/p&gt;

&lt;p&gt;Degiro shows me what JEPI paid last month. Interactive Brokers shows me Chevron's yield.&lt;/p&gt;

&lt;p&gt;None of them shows me a consolidated view of what my entire portfolio will generate over the next 12 months. None of them tells me the dividend streak of each holding — how many consecutive years a company has kept paying without interruption. None of them gives me a quality rating to compare positions across sectors at a glance.&lt;/p&gt;

&lt;p&gt;That's not a minor gap. That's the entire point of a dividend strategy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 20-Tab Problem
&lt;/h2&gt;

&lt;p&gt;Before I had a proper system, forecasting dividends looked like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open each broker app separately&lt;/li&gt;
&lt;li&gt;Note down the payments received manually&lt;/li&gt;
&lt;li&gt;Search each ticker on a financial data site for ex-dividend dates&lt;/li&gt;
&lt;li&gt;Cross-reference with a dividend calendar on another website&lt;/li&gt;
&lt;li&gt;Copy everything into a Google Sheet&lt;/li&gt;
&lt;li&gt;Pray the formulas didn't break when I added a new position&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That process took hours. And it was always out of date by the time I finished.&lt;/p&gt;

&lt;p&gt;The worst part: I was spending all that time on data collection, not on analysis. I knew roughly what I'd earned. I had no real visibility on what I'd earn.&lt;/p&gt;

&lt;p&gt;There's a difference between tracking dividends and forecasting them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Metrics That Actually Matter
&lt;/h2&gt;

&lt;p&gt;Most investors focus on dividend yield. It's the number brokers show you. It's also the least useful metric for building a sustainable income strategy.&lt;/p&gt;

&lt;p&gt;Here's the framework I use now — and the metrics Snowball surfaces automatically:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Dividend Yield
&lt;/h3&gt;

&lt;p&gt;The baseline. What percentage of your invested capital comes back as income annually. Useful for comparison, but incomplete on its own. A high yield can signal a struggling company as easily as a generous one.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Dividend Growth (5-Year)
&lt;/h3&gt;

&lt;p&gt;This is the metric that changes everything. A stock yielding 3.52% today but growing its dividend at 6.16% annually — like Chevron — compounds your effective income without adding a single euro of new capital. Target, at just 2.64% yield, is growing at 11.38% annually. In 7 years, that position pays more than most high-yield plays do today.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dividend Streak
&lt;/h3&gt;

&lt;p&gt;How many consecutive years a company has paid dividends without cutting. Johnson &amp;amp; Johnson: 38 years. Coca-Cola: 38 years. Aflac: 35 years. This number tells you more about dividend reliability than yield ever will.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Dividend Growth Streak
&lt;/h3&gt;

&lt;p&gt;Not just paying — but increasing the payment every single year. A company that has raised its dividend for 35+ consecutive years has done so through recessions, rate cycles, and market crashes. That's the kind of compounding you can plan around.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. IRR (Internal Rate of Return)
&lt;/h3&gt;

&lt;p&gt;The metric brokers almost never show you. IRR accounts for when you invested and when you received income — giving you the true annualized return on each position, not just the price gain. A position that's flat on paper might have an IRR of 20%+ once dividends are factored in. That's a completely different picture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Looks Like in Practice: The Stock Screener
&lt;/h2&gt;

&lt;p&gt;Snowball's dividend screener puts all of this in one table. Not per broker — for any stock you want to evaluate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrececkpzgfki52e5qk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrececkpzgfki52e5qk0.png" alt=" " width="720" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at what that table tells you in seconds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chevron (CVX):&lt;/strong&gt; 3.52% yield, 6.16% 5Y growth, 38-year streak. A dividend aristocrat with momentum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exxon (XOM):&lt;/strong&gt; 3.08% yield, but only 20-year growth streak vs. 37-year payment streak — growing, but more recently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Target (TGT):&lt;/strong&gt; the lowest yield in the table at 2.64%, but 11.38% annual growth and a 38-year growth streak. The compounder hiding behind a modest number.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your broker shows you none of this side-by-side. You'd need five separate tabs to assemble it.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://snowball-analytics.com" rel="noopener noreferrer"&gt;Screen dividend stocks with Snowball Analytics&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Dividend Calendar: Forecasting Made Visual
&lt;/h2&gt;

&lt;p&gt;Knowing your positions is one thing. Knowing when they pay — and projecting forward — is where most investors lose visibility.&lt;/p&gt;

&lt;p&gt;This is where Snowball's dividend calendar changes the game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt7y36gkuer71rawnypm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt7y36gkuer71rawnypm.png" alt=" " width="720" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you see immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Annual income:&lt;/strong&gt; $5,419.67 — not a rough estimate, a projection based on declared and estimated payments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly average:&lt;/strong&gt; $451.64 — your baseline income number&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily:&lt;/strong&gt; $14.85 — the number that makes the strategy feel real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yet to receive:&lt;/strong&gt; $291.77 — what's already declared and arriving this month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below that, every payment is broken down by position: JEPI pays monthly on April 6, Merck quarterly on April 10, Realty Income monthly on April 14, and Cisco quarterly on April 26. Each entry shows the exact amount per share, the ex-dividend date, and whether the payment is declared or estimated.&lt;/p&gt;

&lt;p&gt;That's a 12-month income roadmap. No spreadsheet builds this automatically. No broker shows you this across all your accounts at once.&lt;/p&gt;

&lt;p&gt;The income smoothing tip becomes actionable here too: you can see at a glance which months are heavy ($624 in June, $631 in September) and which are light ($323 in February, $327 in May) — and decide whether to add a position that pays in the gap months before you deploy the next round of capital.&lt;/p&gt;




&lt;h2&gt;
  
  
  Forecasting vs. Tracking: The Actual Difference
&lt;/h2&gt;

&lt;p&gt;Tracking tells you what happened. Forecasting tells you what to do next.&lt;/p&gt;

&lt;p&gt;Most tools — including spreadsheets — are built for tracking. You log a payment, update a cell, move on. The data is historical.&lt;/p&gt;

&lt;p&gt;Forecasting requires knowing ex-dividend dates, payment schedules, growth rates, and how changes to one position affect your total income projection. That's the kind of calculation that breaks spreadsheets and sends you back to 20 different tabs.&lt;/p&gt;

&lt;p&gt;Having that data consolidated and updated automatically isn't a convenience feature. For a dividend investor, it's the difference between building a strategy and just hoping the payments keep coming.&lt;/p&gt;




&lt;h2&gt;
  
  
  5 Tips for Investors Already Building Dividend Income
&lt;/h2&gt;

&lt;p&gt;If you already have positions paying dividends and you're trying to optimize — not just collect — here's what actually moves the needle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Stop optimizing for yield. Start optimizing for yield growth.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A 9% yield that stays flat is worth less over time than a 3% yield growing at 10% annually. In 8 years, that 3% position is yielding more on your cost basis than the static 9% — and the underlying company is almost certainly healthier. Look at the 5-year dividend growth column before you look at current yield.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Track income concentration, not just portfolio allocation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You might have a well-diversified portfolio by sector — but 60% of your dividend income coming from one or two positions is a completely different kind of risk. Map your income sources separately from your capital allocation. A single dividend cut can destroy a month's projections if you haven't done this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Use IRR to compare positions fairly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two positions with similar yields can have very different IRRs depending on when you bought, how much you've received in dividends, and how the price has moved. IRR is the only metric that accounts for all of this. It's the number that tells you whether a position is actually working for you — or just looking good on paper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Reinvest selectively, not automatically.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DRIP (Dividend Reinvestment Plan) is convenient, but it reinvests into whatever you already own — regardless of whether that's still your best opportunity. A better approach: collect dividends as cash, review your allocation quarterly, and deploy capital into whichever position is most underweight relative to your targets. More work, better results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Build for income smoothing across months.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most dividend portfolios are lumpy — heavy payments in certain months, nothing in others. Before adding a new position, check when it pays. A portfolio that generates consistent monthly income is easier to plan around than one that pays €2,000 in March and €80 in August. The dividend calendar makes this immediately obvious.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal Isn't Yield. It's Predictability.
&lt;/h2&gt;

&lt;p&gt;€500–€1,000 a month in dividend income is not a number you hit by chasing the highest yields.&lt;/p&gt;

&lt;p&gt;It's a number you build toward by selecting positions with growing payouts, understanding your income concentration, and reinvesting deliberately.&lt;/p&gt;

&lt;p&gt;You can't do that with a broker dashboard. You can't do it reliably with a spreadsheet.&lt;/p&gt;

&lt;p&gt;You need a single view that shows you not just what your portfolio is worth — but what it will pay you, when it will pay you, and whether that number is growing.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://snowball-analytics.com" rel="noopener noreferrer"&gt;Start forecasting your dividend income with Snowball Analytics&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stop Staring at Spreadsheets: How a Proper Portfolio Visualizer Kept Me From Panic-Selling</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Thu, 14 May 2026 11:21:16 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/stop-staring-at-spreadsheets-how-a-proper-portfolio-visualizer-kept-me-from-panic-selling-27f3</link>
      <guid>https://dev.to/kevin_menesesgonzlez/stop-staring-at-spreadsheets-how-a-proper-portfolio-visualizer-kept-me-from-panic-selling-27f3</guid>
      <description>&lt;p&gt;In March 2020, I sold positions I should have held for years.&lt;/p&gt;

&lt;p&gt;The market was collapsing. My broker app was a wall of red. My spreadsheet, half-updated as always, showed numbers I didn't trust. And without a clear picture of what I actually owned and what it was generating, I did what most retail investors do under pressure: I reacted.&lt;/p&gt;

&lt;p&gt;Some of those positions recovered 80%, 100%, more. I wasn't there for it.&lt;/p&gt;

&lt;p&gt;I made the same mistake again in early 2025 — different correction, same psychology, same incomplete information driving the decision.&lt;/p&gt;

&lt;p&gt;The problem wasn't discipline. The problem was what I was looking at.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Red/Green Trap
&lt;/h2&gt;

&lt;p&gt;Broker apps are designed around price movement. Every interface puts the daily change front and center — green when you're up, red when you're down. The number that dominates your screen is the one most likely to trigger an emotional response.&lt;/p&gt;

&lt;p&gt;That's not an accident. Engagement and activity are good for brokers. Calm, long-term holding is not.&lt;/p&gt;

&lt;p&gt;When markets fall, every broker app in your pocket is screaming the same thing: &lt;em&gt;your money is disappearing&lt;/em&gt;. And if that's the only signal you have — if you have no visibility on income, no view of long-term trajectory, no sense of what your portfolio actually generates — your brain fills in the rest with anxiety.&lt;/p&gt;

&lt;p&gt;Staring at a spreadsheet during a correction is worse. The numbers are stale, the formulas are fragile, and there's no context. Just a column of values declining in real time with no counterweight.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Sold in 2020 (And What It Cost Me)
&lt;/h2&gt;

&lt;p&gt;March 2020 was a 34% drawdown in 33 days. The fastest crash in market history.&lt;/p&gt;

&lt;p&gt;I had positions across Degiro and Interactive Brokers. I had no consolidated view — just four separate apps showing four separate catastrophes with no way to see the full picture.&lt;/p&gt;

&lt;p&gt;I sold. Not everything. But enough.&lt;/p&gt;

&lt;p&gt;The positions I sold weren't bad positions. They were sound companies, held at reasonable valuations, paying dividends. But I couldn't see that in the moment. All I could see was red.&lt;/p&gt;

&lt;p&gt;Some of those positions doubled in the 18 months that followed. The cost of that panic wasn't just the loss on the sale — it was missing the entire recovery.&lt;/p&gt;

&lt;p&gt;In early 2025, another correction. This time I had more context, more visibility. I still felt the pull. But I also added to some positions instead of exiting. Not because my discipline had improved. Because what I was looking at had changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Shift: From Capital Value to Cash Flow
&lt;/h2&gt;

&lt;p&gt;The single most useful reframe for a long-term investor is this: &lt;strong&gt;your portfolio's job is not to be worth more tomorrow. It's to generate income that grows over time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Price is volatile. Income is sticky.&lt;/p&gt;

&lt;p&gt;A stock down 20% in a correction is still paying its dividend. If it's a company with a 30-year streak of increasing payments, the correction doesn't change the income thesis at all. The price will recover. The dividend, in most cases, keeps coming.&lt;/p&gt;

&lt;p&gt;But you can only hold that perspective if you can &lt;em&gt;see&lt;/em&gt; it. If your primary view is a red/green price chart, every correction feels like destruction. If your primary view is a dividend calendar showing $451 arriving this month regardless of what the market does — the emotional equation changes.&lt;/p&gt;

&lt;p&gt;This is the behavioral shift that proper portfolio visualization enables. Not motivation. Not discipline. Just better information, presented in a way that maps to your actual strategy.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a Portfolio Visualizer Actually Shows You
&lt;/h2&gt;

&lt;p&gt;The difference between a broker dashboard and a proper portfolio visualizer isn't cosmetic. It's structural.&lt;/p&gt;

&lt;p&gt;A broker dashboard shows you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Today's price vs. yesterday's price&lt;/li&gt;
&lt;li&gt;Your position's gain/loss since purchase&lt;/li&gt;
&lt;li&gt;Account value (on their platform only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A portfolio visualizer shows you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total net worth across all accounts, updated automatically&lt;/li&gt;
&lt;li&gt;Asset allocation across every broker simultaneously&lt;/li&gt;
&lt;li&gt;Income generated — actual dividends received and projected forward&lt;/li&gt;
&lt;li&gt;Cash flow by month — what arrives when, declared vs. estimated&lt;/li&gt;
&lt;li&gt;Performance in your base currency, adjusted for exchange rate movements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;[Screenshot: Snowball Analytics portfolio overview — allocation donut chart across Funds, Stocks, Cash, Commodities]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The first view makes you feel exposed during corrections. The second gives you the global vision to stay in control.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Dividend Calendar During a Correction
&lt;/h2&gt;

&lt;p&gt;The most powerful view during a market downturn is not your portfolio value. It's your income schedule.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73v97ubuf6sadzmxsx4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73v97ubuf6sadzmxsx4k.png" alt=" " width="682" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When prices are falling, this view answers the question that actually matters for a dividend investor: &lt;em&gt;is my income stream intact?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhb9u2ig0b41ukqarxc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhb9u2ig0b41ukqarxc3.png" alt=" " width="682" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$3,455.20 in projected annual income. $287.93 arriving every month. $9.47 every single day — whether the market is up, down, or sideways.&lt;/p&gt;

&lt;p&gt;Look at the bar chart: June $405, August $311, September $404, December $406. The income pattern is visible a full year ahead. Not estimated loosely — projected from declared and scheduled payments, month by month.&lt;/p&gt;

&lt;p&gt;None of that changes because the S&amp;amp;P dropped 8% this week.&lt;/p&gt;

&lt;p&gt;Seeing that — really seeing it, with a 12-month forward view and specific monthly amounts — is what separates a strategic hold from a panic sell. The income calendar makes the abstract concept of "long-term investing" concrete and visible in a way that a price chart never can.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Sense of Control vs. Reacting to Noise
&lt;/h2&gt;

&lt;p&gt;There's a reason experienced investors talk about "sleeping well at night" as a portfolio objective. It's not a metaphor. It's a literal description of what good information architecture does for your decision-making.&lt;/p&gt;

&lt;p&gt;When I have a global view of my full portfolio — allocation, performance, income, projections — I have a sense of control that no single broker app can provide. Not because the numbers are always good. But because I can see the full picture clearly enough to distinguish signal from noise.&lt;/p&gt;

&lt;p&gt;A 5% correction in one position feels different when you can see it represents 2% of your total allocation and its dividend income is unaffected&lt;/p&gt;

&lt;p&gt;Context doesn't eliminate volatility. But it eliminates the feeling that volatility is the whole story.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Practical Test: What Are You Looking at When Markets Drop?
&lt;/h2&gt;

&lt;p&gt;If the answer is your broker app — you're looking at the worst possible information for making a long-term decision. Designed for short-term reaction, updated in real time, stripped of all income context.&lt;/p&gt;

&lt;p&gt;If the answer is a spreadsheet — you're looking at stale data you don't fully trust, with no income projection and no global allocation view.&lt;/p&gt;

&lt;p&gt;If the answer is a consolidated portfolio view that shows your full allocation, your projected income for the next 12 months, and your performance in your actual base currency — you have what you need to make a rational decision under pressure.&lt;/p&gt;

&lt;p&gt;The goal isn't to feel nothing during a correction. The goal is to have enough context that your response is strategic rather than reflexive.&lt;/p&gt;

&lt;p&gt;That's what a proper portfolio visualizer does. Not motivation. Not courage. Just the right information, in one place, when you need it.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://snowball-analytics.com/?utm_source=medium&amp;amp;utm_medium=article&amp;amp;utm_campaign=kevin&amp;amp;utm_content=portfolio-visualizer-panic-selling" rel="noopener noreferrer"&gt;Get a full view of your portfolio with Snowball Analytics&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  One Last Thing
&lt;/h2&gt;

&lt;p&gt;I still think about those positions I sold in March 2020.&lt;/p&gt;

&lt;p&gt;Not with regret — the decisions made sense given what I could see at the time. That's the point. The problem wasn't fear. The problem was incomplete information making fear the dominant input.&lt;/p&gt;

&lt;p&gt;If I'd had a consolidated view showing my full allocation, a dividend calendar showing income arriving regardless of price, and a performance number I actually trusted — I might have held. I might have bought more.&lt;/p&gt;

&lt;p&gt;You can't change past decisions. But you can change what you look at before you make the next one.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://snowball-analytics.com/?utm_source=medium&amp;amp;utm_medium=article&amp;amp;utm_campaign=kevin&amp;amp;utm_content=portfolio-visualizer-panic-selling" rel="noopener noreferrer"&gt;Start visualizing your portfolio the right way&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>stocks</category>
      <category>data</category>
      <category>trading</category>
      <category>learning</category>
    </item>
    <item>
      <title>Why I Stopped Relying on My Broker's App to Track My Wealth</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Wed, 13 May 2026 14:49:26 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/why-i-stopped-relying-on-my-brokers-app-to-track-my-wealth-28lb</link>
      <guid>https://dev.to/kevin_menesesgonzlez/why-i-stopped-relying-on-my-brokers-app-to-track-my-wealth-28lb</guid>
      <description>&lt;p&gt;Most investors think their broker's app is enough.&lt;/p&gt;

&lt;p&gt;It's not.&lt;/p&gt;

&lt;p&gt;And I have a very specific date to prove it: Wednesday, February 25, 2026.&lt;/p&gt;

&lt;p&gt;That morning I bought 35 shares of NVIDIA. Not because I had a clear thesis. Not because I'd reviewed my full allocation. But because Degiro showed me cash available, the stock looked like a dip worth catching, and I hadn't updated my consolidated spreadsheet in two weeks.&lt;/p&gt;

&lt;p&gt;What I didn't see: I was already overexposed to tech across my other accounts.&lt;/p&gt;

&lt;p&gt;I had to sell at a loss days later to rebalance.&lt;/p&gt;

&lt;p&gt;That wasn't bad luck. That was a visibility problem.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;splitting your portfolio across multiple brokers,&lt;/li&gt;
&lt;li&gt;holding crypto alongside traditional assets,&lt;/li&gt;
&lt;li&gt;or making decisions without seeing your full picture first,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Broker Blind Spot Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;I invest across four platforms: Degiro, Interactive Brokers, Binance, and MyInvestor.&lt;/p&gt;

&lt;p&gt;Each one shows me exactly what I hold &lt;em&gt;with them&lt;/em&gt;. Clean charts. Green numbers. A polished interface designed to make me feel good about staying on their platform.&lt;/p&gt;

&lt;p&gt;What none of them show me is the full picture.&lt;/p&gt;

&lt;p&gt;Degiro doesn't know what's sitting in my Interactive Brokers account. Binance has no idea about my index funds at MyInvestor. And none of them — not a single one — can tell me my consolidated net worth at any given moment.&lt;/p&gt;

&lt;p&gt;That's not a bug. That's a feature. Brokers are designed to keep you inside their ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Spreadsheet Trap
&lt;/h2&gt;

&lt;p&gt;So I did what every investor eventually does: I built a spreadsheet.&lt;/p&gt;

&lt;p&gt;It started simple. Two columns. Asset and value. Then it grew. Exchange rates. Manual updates every Sunday. Formulas that broke when a column shifted. A tab for crypto, a tab for stocks, a tab I stopped updating because it was taking too long.&lt;/p&gt;

&lt;p&gt;The plan was to update it every week. The reality: I'd forget, skip a Sunday, then skip another, and suddenly two weeks had passed and the numbers were stale enough to be useless.&lt;/p&gt;

&lt;p&gt;At peak complexity, maintaining that spreadsheet was costing me over 10 hours a month.&lt;/p&gt;

&lt;p&gt;Not 10 hours of analysis. 10 hours of &lt;em&gt;data entry&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And the worst part wasn't the time. It was what happened when the data was out of date: I made decisions anyway. By intuition. By gut feel. With incomplete information dressed up as a spreadsheet.&lt;/p&gt;

&lt;p&gt;That's how you end up buying 35 shares of a stock you're already overweight in.&lt;/p&gt;

&lt;p&gt;The stress wasn't from the market. It was from never really knowing where I stood.&lt;/p&gt;

&lt;p&gt;There's a difference between investing with conviction and investing with anxiety. One comes from clarity. The other comes from flying blind.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Cost Nobody Calculates
&lt;/h2&gt;

&lt;p&gt;Ten hours a month sounds manageable until you run the real math.&lt;/p&gt;

&lt;p&gt;That's 120 hours a year spent on data entry, not analysis. But the actual cost isn't the time — it's the decisions you make while the data is stale.&lt;/p&gt;

&lt;p&gt;A bad trade made with incomplete information doesn't show up as "spreadsheet maintenance cost" in your portfolio. It shows up as a loss you didn't need to take.&lt;/p&gt;

&lt;p&gt;Impulsive buys when you can't see your true exposure. Panic sells when you can't see your actual gain across accounts. Missed rebalancing because the picture was never complete enough to act on.&lt;/p&gt;

&lt;p&gt;That's the real opportunity cost of the DIY approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem Isn't Data. It's Fragmentation.
&lt;/h2&gt;

&lt;p&gt;Every broker gives you data. The problem is that the data lives in silos — and no single broker has any incentive to fix that.&lt;/p&gt;

&lt;p&gt;What you end up with is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance metrics that only reflect one slice of your portfolio&lt;/li&gt;
&lt;li&gt;No way to see cross-asset allocation in one view&lt;/li&gt;
&lt;li&gt;Return calculations that ignore currency fluctuations between accounts&lt;/li&gt;
&lt;li&gt;Zero visibility on your actual net worth across all positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're not missing information. You're missing &lt;em&gt;integration&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed When I Tried Snowball Analytics
&lt;/h2&gt;

&lt;p&gt;I wasn't looking for another app. I was looking for a way to stop wasting time.&lt;/p&gt;

&lt;p&gt;What I found was a portfolio tracker that actually understands how modern investors invest — across multiple brokers, multiple asset classes, multiple currencies.&lt;/p&gt;

&lt;p&gt;The setup is straightforward. You connect your accounts, and Snowball pulls everything into a single dashboard. Degiro. Interactive Brokers. Binance. MyInvestor. All of it, in one place.&lt;/p&gt;

&lt;p&gt;No more spreadsheets. No more Sunday night rituals.&lt;/p&gt;

&lt;p&gt;What made the difference wasn't just the consolidation — it was the interface. Clean, intuitive, and built around the questions investors actually ask: What do I own? How is it performing? Where am I overexposed?&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://snowball-analytics.com/?utm_source=medium&amp;amp;utm_medium=article&amp;amp;utm_campaign=kevin&amp;amp;utm_content=why-i-stopped-relying-on-my-brokers-app" rel="noopener noreferrer"&gt;Try Snowball Analytics here&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What a Proper Portfolio Tracker Actually Shows You
&lt;/h2&gt;

&lt;p&gt;The portfolio tracker is where I spend most of my time in Snowball.&lt;/p&gt;

&lt;p&gt;Not because it's flashy — but because it finally shows me what I couldn't see before.&lt;/p&gt;

&lt;p&gt;The first view that changed everything: a single donut chart showing my full allocation across Funds, Stocks, Cash, Commodities — with the exact value invested, current gain, and target allocation side by side. Not per broker. For everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5evihzp6wshlhmfhpam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5evihzp6wshlhmfhpam.png" alt=" " width="720" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That alone replaced three tabs I used to keep open simultaneously.&lt;/p&gt;

&lt;p&gt;But the view I check most is the holdings table. Every position, in one place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost basis vs. current value&lt;/strong&gt; — so I always know what I actually paid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dividends received&lt;/strong&gt; — total and per share, updated automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dividend yield and 5-year growth&lt;/strong&gt; — not just what a stock pays now, but whether it's growing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total profit and IRR&lt;/strong&gt; — the real return number, not the one that looks good on a broker dashboard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share in portfolio&lt;/strong&gt; — so I can see concentration risk at a glance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdcyz4wy0dz30cv1c7bn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdcyz4wy0dz30cv1c7bn.png" alt=" " width="720" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before Snowball, I had pieces of this scattered across platforms and a spreadsheet that was always one bad formula away from being useless.&lt;/p&gt;

&lt;p&gt;Now I open one tab and I know exactly where I stand.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Broker's App Is Not a Wealth Tracker
&lt;/h2&gt;

&lt;p&gt;Broker apps are trading interfaces with dashboards bolted on.&lt;/p&gt;

&lt;p&gt;They're optimized for executing orders, not for giving you a complete picture of your financial life. That distinction matters more as your portfolio grows and spreads across multiple platforms.&lt;/p&gt;

&lt;p&gt;A dedicated portfolio tracker isn't a luxury for institutional investors. It's the baseline infrastructure any serious retail investor needs to make decisions with confidence.&lt;/p&gt;

&lt;p&gt;Most investors don't need more data. They need to see all their data in one place.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://snowball-analytics.com/?utm_source=medium&amp;amp;utm_medium=article&amp;amp;utm_campaign=kevin&amp;amp;utm_content=why-i-stopped-relying-on-my-brokers-app" rel="noopener noreferrer"&gt;Start tracking your full portfolio with Snowball Analytics&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>finance</category>
      <category>trading</category>
      <category>stocks</category>
      <category>analytics</category>
    </item>
    <item>
      <title>I Replaced Yahoo Finance with EODHD — Here's What Changed</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Mon, 11 May 2026 10:22:34 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/i-replaced-yahoo-finance-with-eodhd-heres-what-changed-1c8k</link>
      <guid>https://dev.to/kevin_menesesgonzlez/i-replaced-yahoo-finance-with-eodhd-heres-what-changed-1c8k</guid>
      <description>&lt;p&gt;Your script ran fine yesterday. Today it throws:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$AAPL: possibly delisted; no price data found (1d 2024-03-02 -&amp;gt; 2025-03-02)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing changed in your code. Nothing changed on your machine. Yet the data is gone.&lt;/p&gt;

&lt;p&gt;If you've been building with &lt;code&gt;yfinance&lt;/code&gt;, you know this moment.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;running a backtesting system,&lt;/li&gt;
&lt;li&gt;building a portfolio tracker,&lt;/li&gt;
&lt;li&gt;or automating any kind of financial analysis in Python,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters more than you think.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Isn't Your Code
&lt;/h2&gt;

&lt;p&gt;In early 2025, Yahoo Finance quietly restricted historical data downloads to paid subscribers — Gold tier, $50/month or $500/year.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;yfinance&lt;/code&gt; GitHub repository filled up with hundreds of issue reports overnight. The error messages were misleading: tickers marked as "possibly delisted" that were actively trading. Scripts that had worked for years suddenly returning empty DataFrames.&lt;/p&gt;

&lt;p&gt;But even before the paywall, the cracks were already visible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting that blacklisted IPs without warning&lt;/li&gt;
&lt;li&gt;HTML parsing that broke whenever Yahoo updated their frontend&lt;/li&gt;
&lt;li&gt;No official support — when it breaks, you're on your own&lt;/li&gt;
&lt;li&gt;Data gaps that only surface mid-analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real problem isn't that &lt;code&gt;yfinance&lt;/code&gt; had a bad release. It's that &lt;code&gt;yfinance&lt;/code&gt; was never designed for production. It's a scraper that happens to return financial data.&lt;/p&gt;

&lt;p&gt;At some point, the gap between what you need and what Yahoo Finance can provide becomes impossible to ignore.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Switched To — and Why EODHD
&lt;/h2&gt;

&lt;p&gt;After testing several alternatives, I migrated to &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=yahoo-finance-alternative-eodhd-python&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;EODHD APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;EODHD (EOD Historical Data) is a financial data provider with coverage across 70+ global exchanges, 30+ years of historical data, and a REST API that's been running in production for actual financial products — not hobbyist wrappers.&lt;/p&gt;

&lt;p&gt;What you get access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-of-day stock prices (global: US, EU, Asia, LatAm)&lt;/li&gt;
&lt;li&gt;Intraday and real-time feeds&lt;/li&gt;
&lt;li&gt;Fundamental data (income statements, balance sheets, cash flow)&lt;/li&gt;
&lt;li&gt;Dividends and splits history&lt;/li&gt;
&lt;li&gt;Economic calendar and macro indicators&lt;/li&gt;
&lt;li&gt;Technical indicators via API&lt;/li&gt;
&lt;li&gt;WebSocket streaming for live quotes&lt;/li&gt;
&lt;li&gt;Excel and Google Sheets add-ons (no code required)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One API key. One provider. No scraping, no workarounds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=yahoo-finance-alternative-eodhd-python&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Get started with EODHD here&lt;/a&gt; — free tier available to test endpoints before committing.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Migration in Python
&lt;/h2&gt;

&lt;p&gt;Let's go through the three most common &lt;code&gt;yfinance&lt;/code&gt; use cases and their EODHD equivalents. No SDK required — raw HTTP calls, clean and explicit.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Historical Price Data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before — yfinance:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;

&lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ticker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;history&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2024-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;High&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Volume&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works until it doesn't. No guaranteed uptime, no SLA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After — EODHD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_eodhd_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL.US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/eod/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2024-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fmt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;volume&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;            &lt;span class="k"&gt;open&lt;/span&gt;    &lt;span class="k"&gt;high&lt;/span&gt;     &lt;span class="k"&gt;low&lt;/span&gt;   &lt;span class="k"&gt;close&lt;/span&gt;      &lt;span class="k"&gt;volume&lt;/span&gt;
&lt;span class="k"&gt;date&lt;/span&gt;
&lt;span class="ld"&gt;2023-01-03&lt;/span&gt;  &lt;span class="mf"&gt;130.28&lt;/span&gt;  &lt;span class="mf"&gt;130.90&lt;/span&gt;  &lt;span class="mf"&gt;124.17&lt;/span&gt;  &lt;span class="mf"&gt;125.07&lt;/span&gt;  &lt;span class="mf"&gt;112117500&lt;/span&gt;
&lt;span class="ld"&gt;2023-01-04&lt;/span&gt;  &lt;span class="mf"&gt;126.89&lt;/span&gt;  &lt;span class="mf"&gt;128.66&lt;/span&gt;  &lt;span class="mf"&gt;125.08&lt;/span&gt;  &lt;span class="mf"&gt;126.36&lt;/span&gt;   &lt;span class="mf"&gt;89113600&lt;/span&gt;
&lt;span class="ld"&gt;2023-01-05&lt;/span&gt;  &lt;span class="mf"&gt;127.13&lt;/span&gt;  &lt;span class="mf"&gt;127.77&lt;/span&gt;  &lt;span class="mf"&gt;124.76&lt;/span&gt;  &lt;span class="mf"&gt;125.02&lt;/span&gt;   &lt;span class="mf"&gt;80962700&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean, predictable, JSON-native.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Fundamental Data (Balance Sheet / Income Statement)
&lt;/h3&gt;

&lt;p&gt;This is where &lt;code&gt;yfinance&lt;/code&gt; often fails silently — returning empty dictionaries or malformed tables when Yahoo updates their HTML structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After — EODHD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/fundamentals/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;filter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Financials::Income_Statement::annual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fmt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;income_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Extract last 3 years of annual revenue
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;income_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: Revenue = $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;totalRevenue&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2023-09-30: Revenue = $383,285,000,000
2022-09-24: Revenue = $394,328,000,000
2021-09-25: Revenue = $365,817,000,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Structured, typed, consistent across updates.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Dividend History
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before — yfinance:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ticker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dividends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dividends&lt;/span&gt;  &lt;span class="c1"&gt;# Often breaks or returns partial data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After — EODHD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/div/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2020-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fmt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dividends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dividends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csvs"&gt;&lt;code&gt;         &lt;span class="k"&gt;date&lt;/span&gt;  &lt;span class="k"&gt;value&lt;/span&gt;  &lt;span class="k"&gt;unadjustedValue&lt;/span&gt;  &lt;span class="k"&gt;currency&lt;/span&gt;
&lt;span class="ld"&gt;2022-08-05&lt;/span&gt;  &lt;span class="mf"&gt;0.23&lt;/span&gt;             &lt;span class="mf"&gt;0.23&lt;/span&gt;       &lt;span class="k"&gt;USD&lt;/span&gt;
&lt;span class="ld"&gt;2022-11-04&lt;/span&gt;  &lt;span class="mf"&gt;0.23&lt;/span&gt;             &lt;span class="mf"&gt;0.23&lt;/span&gt;       &lt;span class="k"&gt;USD&lt;/span&gt;
&lt;span class="ld"&gt;2023-02-10&lt;/span&gt;  &lt;span class="mf"&gt;0.23&lt;/span&gt;             &lt;span class="mf"&gt;0.23&lt;/span&gt;       &lt;span class="k"&gt;USD&lt;/span&gt;
&lt;span class="ld"&gt;2023-05-12&lt;/span&gt;  &lt;span class="mf"&gt;0.24&lt;/span&gt;             &lt;span class="mf"&gt;0.24&lt;/span&gt;       &lt;span class="k"&gt;USD&lt;/span&gt;
&lt;span class="ld"&gt;2023-08-11&lt;/span&gt;  &lt;span class="mf"&gt;0.24&lt;/span&gt;             &lt;span class="mf"&gt;0.24&lt;/span&gt;       &lt;span class="k"&gt;USD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dividend income projections&lt;/li&gt;
&lt;li&gt;yield-on-cost calculators&lt;/li&gt;
&lt;li&gt;automated reinvestment models&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Actually Changed After the Migration
&lt;/h2&gt;

&lt;p&gt;Let me break this down across the dimensions that actually matter in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Coverage
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;yfinance&lt;/code&gt; was always US-centric. Outside of the major indices and NYSE/NASDAQ, coverage was inconsistent — tickers from European or Asian exchanges would return data sometimes, nothing other times, with no clear explanation.&lt;/p&gt;

&lt;p&gt;EODHD covers 70+ exchanges out of the box. LSE, Euronext, XETRA, TSX, ASX, B3, NSE — same API, same endpoint structure, same response format. If you're tracking a portfolio that isn't 100% US equities, this alone justifies the switch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Historical Depth
&lt;/h3&gt;

&lt;p&gt;Yahoo Finance paywalled historical data downloads in 2025. Gold tier: $50/month. Without it, &lt;code&gt;yfinance&lt;/code&gt; returns empty DataFrames for date ranges older than a rolling window — and the error messages don't tell you why.&lt;/p&gt;

&lt;p&gt;EODHD includes 30+ years of historical data on paid plans. For backtesting, that's not a feature. It's the baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reliability vs. Scraping
&lt;/h3&gt;

&lt;p&gt;This is the core difference. &lt;code&gt;yfinance&lt;/code&gt; works by mimicking browser requests to Yahoo's servers — it scrapes, parses HTML, and hopes the page structure hasn't changed. Any frontend update on Yahoo's side can silently break it. IP bans happen without warning. Rate limits have no documented threshold.&lt;/p&gt;

&lt;p&gt;EODHD is an official REST API. You authenticate with a key, you hit an endpoint, you get JSON back. There's no HTML parsing layer, no scraping, no fragile dependencies on a third-party website's layout decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Endpoint Depth
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;yfinance&lt;/code&gt; gives you prices, basic fundamentals, and dividends — and even those break periodically. EODHD exposes endpoints that don't exist in the yfinance ecosystem at all:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technical indicators calculated server-side (RSI, MACD, Bollinger Bands via &lt;code&gt;/api/technical/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Economic calendar with macro events by country&lt;/li&gt;
&lt;li&gt;News and sentiment feeds per ticker&lt;/li&gt;
&lt;li&gt;WebSocket streaming for real-time quotes&lt;/li&gt;
&lt;li&gt;Options chains and CBOE data&lt;/li&gt;
&lt;li&gt;Bulk exchange downloads (entire market snapshot in one call)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Full Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;yfinance&lt;/th&gt;
&lt;th&gt;EODHD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scraper (unofficial)&lt;/td&gt;
&lt;td&gt;Official REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Uptime guarantee&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;99.9%+ SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Historical depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Paywalled ($50/mo on Yahoo)&lt;/td&gt;
&lt;td&gt;30+ years included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global exchanges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~25, inconsistent&lt;/td&gt;
&lt;td&gt;70+, structured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fundamental data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scraped, breaks often&lt;/td&gt;
&lt;td&gt;Typed JSON, stable schema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dividends &amp;amp; splits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Partial, unreliable&lt;/td&gt;
&lt;td&gt;Full history, clean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Technical indicators&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Via API (&lt;code&gt;/api/technical/&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-time / intraday&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very limited&lt;/td&gt;
&lt;td&gt;Available (delayed + live)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WebSocket streaming&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Available on paid plans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Economic calendar&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Yes, by country&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;News &amp;amp; sentiment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Yes, per ticker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Options data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic, via scrape&lt;/td&gt;
&lt;td&gt;CBOE + options chains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bulk downloads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Full exchange snapshot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rate limits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IP bans, undocumented&lt;/td&gt;
&lt;td&gt;Defined per plan tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Official support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Community only&lt;/td&gt;
&lt;td&gt;24/7 live support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Excel / Sheets add-on&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python SDK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is the SDK&lt;/td&gt;
&lt;td&gt;Official library on GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free (unreliable)&lt;/td&gt;
&lt;td&gt;Free tier, defined limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Entry paid plan&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;~$19.99/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Cost Question
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;yfinance&lt;/code&gt; is free — but that math changes when you factor in the hours spent debugging silent failures, the instability that's leaked into production pipelines, and now Yahoo's own $50/month paywall for the historical data that made it useful in the first place.&lt;/p&gt;

&lt;p&gt;EODHD's entry plan is ~$19.99/month. For that you get end-of-day data across all supported exchanges, fundamentals, and the full historical archive.&lt;/p&gt;

&lt;p&gt;For anyone running anything beyond a personal prototype, that trade-off is straightforward.&lt;/p&gt;

&lt;p&gt;The biggest shift wasn't the data quality. It was the reliability.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;yfinance&lt;/code&gt; breaks, you spend hours debugging something you didn't break. With EODHD, the contract is clear: you send a request, you get data back.&lt;/p&gt;

&lt;p&gt;That's worth more than free.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Yahoo Finance paywalled historical data in 2025 — &lt;code&gt;yfinance&lt;/code&gt; is no longer a viable production option&lt;/li&gt;
&lt;li&gt;EODHD covers the same use cases (prices, fundamentals, dividends) with a stable REST API and global exchange coverage&lt;/li&gt;
&lt;li&gt;The migration is straightforward: same data, same pandas workflow, raw HTTP instead of a scraping wrapper&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;❓ &lt;strong&gt;Is EODHD free to use?&lt;/strong&gt;&lt;br&gt;
✅ Yes, EODHD has a free tier that covers end-of-day data for a limited number of tickers — enough to test your integration and validate the API before upgrading. Paid plans start at around $19.99/month.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Does EODHD work with pandas?&lt;/strong&gt;&lt;br&gt;
✅ Directly. The API returns JSON arrays that load into DataFrames in one line. No additional parsing library needed.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Can I migrate my existing yfinance scripts without rewriting everything?&lt;/strong&gt;&lt;br&gt;
✅ Mostly yes. The data fields map 1:1 (open, high, low, close, volume). The main change is replacing &lt;code&gt;yf.Ticker()&lt;/code&gt; calls with &lt;code&gt;requests.get()&lt;/code&gt; calls to EODHD endpoints. Most scripts migrate in under an hour.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Does EODHD cover non-US markets?&lt;/strong&gt;&lt;br&gt;
✅ Yes — 70+ exchanges including LSE, Euronext, TSX, ASX, and most major Asian markets. This is one of the biggest advantages over yfinance, which has inconsistent non-US coverage.&lt;/p&gt;




&lt;p&gt;Most developers don't switch financial data providers because of a feature list.&lt;/p&gt;

&lt;p&gt;They switch because their script broke on a Sunday night, and they decided not to fix it the same way again.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>finance</category>
      <category>stock</category>
      <category>yahoofinance</category>
    </item>
    <item>
      <title>How I Automated My Investing Workflow with EODHD and Claude Cowork</title>
      <dc:creator>Kevin Meneses González</dc:creator>
      <pubDate>Sat, 09 May 2026 10:26:57 +0000</pubDate>
      <link>https://dev.to/kevin_menesesgonzlez/how-i-automated-my-investing-workflow-with-eodhd-and-claude-cowork-94i</link>
      <guid>https://dev.to/kevin_menesesgonzlez/how-i-automated-my-investing-workflow-with-eodhd-and-claude-cowork-94i</guid>
      <description>&lt;p&gt;I had trade history files from three different brokers.&lt;/p&gt;

&lt;p&gt;None of them used the same format.&lt;br&gt;
None of them included fundamentals.&lt;br&gt;
And none of them talked to each other.&lt;/p&gt;

&lt;p&gt;If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tracking a portfolio across multiple brokers,&lt;/li&gt;
&lt;li&gt;trying to analyze dividend income and position performance in one place,&lt;/li&gt;
&lt;li&gt;or building a personal finance dashboard without a data engineering team,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;this matters.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem With Manual Portfolio Tracking
&lt;/h2&gt;

&lt;p&gt;Every month, the process looked the same.&lt;/p&gt;

&lt;p&gt;Export a CSV from Degiro. Download the transaction history from Interactive Brokers. Pull the trade log from Binance. Open three different spreadsheets, each with different column names, different date formats, different ticker conventions.&lt;/p&gt;

&lt;p&gt;Then start cleaning.&lt;/p&gt;

&lt;p&gt;Rename columns. Fix date formats. Remove duplicate headers. Reconcile tickers that one platform calls &lt;code&gt;AAPL&lt;/code&gt; and another calls &lt;code&gt;AAPL.US&lt;/code&gt;. Add a column for cost basis. Calculate unrealized P&amp;amp;L manually.&lt;/p&gt;

&lt;p&gt;Two hours later, the data was usable — but already outdated.&lt;/p&gt;

&lt;p&gt;And fundamental data? P/E ratio, dividend yield, EPS, earnings dates? The broker exports never included any of it. That required a separate lookup, one ticker at a time.&lt;/p&gt;

&lt;p&gt;The data was never the problem.&lt;/p&gt;

&lt;p&gt;The system connecting it was.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Stack: Two Tools, One Workflow
&lt;/h2&gt;

&lt;p&gt;I stopped trying to fix the spreadsheet. Instead, I rebuilt the workflow around two tools that handle the parts I was doing manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Cowork&lt;/strong&gt; handles the messy human layer — the files, the formats, the logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EODHD API&lt;/strong&gt; handles the data layer — prices, fundamentals, historical records.&lt;/p&gt;

&lt;p&gt;Here's how each one fits in.&lt;/p&gt;
&lt;h3&gt;
  
  
  Claude Cowork: From Chaos to Clean Data
&lt;/h3&gt;

&lt;p&gt;Claude Cowork is Anthropic's desktop agent. It can read files on your machine, understand their structure, write code, and execute it — all in a single session.&lt;/p&gt;

&lt;p&gt;I drop my broker export files into a folder. Cowork reads all three, identifies the schema of each one, normalizes column names, standardizes ticker formats, and merges everything into a single unified dataset. It also categorizes each operation by type: buy, sell, dividend, or fee.&lt;/p&gt;

&lt;p&gt;No manual cleaning. No scripting beforehand. I describe what I want, and Cowork figures out how to get there — including writing and running the Python script that does the actual transformation.&lt;/p&gt;

&lt;p&gt;What used to take two hours now takes under five minutes.&lt;/p&gt;
&lt;h3&gt;
  
  
  EODHD API: Enriching Every Position
&lt;/h3&gt;

&lt;p&gt;Once the positions are clean, the script calls the EODHD API to enrich each holding with data the broker exports never provide.&lt;/p&gt;

&lt;p&gt;For each ticker in the portfolio, the script pulls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-of-day price and historical performance&lt;/li&gt;
&lt;li&gt;Fundamental data: P/E ratio, EPS, dividend yield, payout ratio&lt;/li&gt;
&lt;li&gt;Company metadata: sector, market cap, exchange&lt;/li&gt;
&lt;li&gt;Upcoming dividend dates and amounts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EODHD covers 70+ exchanges and 150,000+ tickers, with consistent JSON responses that integrate cleanly into Python. One API key, one endpoint structure, everything you need.&lt;/p&gt;

&lt;p&gt;👉  &lt;strong&gt;&lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=automate-investing-workflow-eodhd-claude-cowork&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Start with EODHD here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Implementation: Step by Step
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1 — Drop Files Into Cowork
&lt;/h3&gt;

&lt;p&gt;I place the raw broker exports in a local folder: &lt;code&gt;degiro_trades.csv&lt;/code&gt;, &lt;code&gt;ibkr_history.csv&lt;/code&gt;, &lt;code&gt;binance_transactions.csv&lt;/code&gt;. Then I open Claude Cowork and describe the task:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I have three broker export files with different formats. Normalize them into a single DataFrame with columns: date, ticker, operation, quantity, price, broker. Then save the result as unified_portfolio.csv."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cowork reads each file, identifies the column structure, maps the fields, and generates the script. It runs it. If something breaks — a date parsing error, a ticker format mismatch — it fixes it on the spot.&lt;/p&gt;

&lt;p&gt;The output is a clean, unified CSV with every trade I've ever made, across every broker, in one consistent format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42p0blab0ytt7c3w8y94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42p0blab0ytt7c3w8y94.png" alt=" " width="698" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 — Enrich With EODHD
&lt;/h3&gt;

&lt;p&gt;The next part of the script calls the EODHD API for each unique ticker in the portfolio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_eodhd_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_fundamentals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://eodhd.com/api/fundamentals/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;?api_token=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;fmt=json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;highlights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Highlights&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pe_ratio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;highlights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PERatio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eps&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;highlights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EarningsShare&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dividend_yield&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;highlights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DividendYield&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;market_cap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;highlights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MarketCapitalization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;General&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Load unified portfolio
&lt;/span&gt;&lt;span class="n"&gt;portfolio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unified_portfolio.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tickers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;portfolio&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch fundamentals for each position
&lt;/span&gt;&lt;span class="n"&gt;fundamentals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;get_fundamentals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tickers&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;enriched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;portfolio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fundamentals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ticker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;enriched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enriched_portfolio.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can extend the script to pull:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Historical price series for performance attribution&lt;/li&gt;
&lt;li&gt;Dividend payment history and forecast&lt;/li&gt;
&lt;li&gt;Earnings dates for upcoming calendar alerts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3 — Update the Dashboard
&lt;/h3&gt;

&lt;p&gt;The enriched CSV feeds a local dashboard — built in Python with Plotly or any tool that reads a CSV. Every time I run the workflow, the dashboard reflects the current state of the portfolio with up-to-date fundamentals and prices.&lt;/p&gt;

&lt;p&gt;No manual input. No open tabs. No Sunday night cleanup.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Dashboard Shows
&lt;/h2&gt;

&lt;p&gt;Monday morning. One tab open.&lt;/p&gt;

&lt;p&gt;Every position across Degiro, Interactive Brokers, and Binance — unified. Current price and daily change from EODHD. P/E ratio and dividend yield per holding. Cost basis versus current value. Unrealized P&amp;amp;L by position and by broker.&lt;/p&gt;

&lt;p&gt;The kind of view that used to require a Bloomberg terminal or three hours of spreadsheet work.&lt;/p&gt;

&lt;p&gt;Now it runs in minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Cowork handles the messy layer&lt;/strong&gt; — different file formats, inconsistent schemas, logic that changes every time a broker updates their export. You don't write that script yourself. Cowork does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EODHD handles the data layer&lt;/strong&gt; — clean, consistent, production-grade financial data across every asset class, accessible through a single REST API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Together they eliminate every manual step&lt;/strong&gt; — the transformation, the enrichment, the update. The workflow runs without you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most investors don't need better instincts.&lt;/p&gt;

&lt;p&gt;They need a better system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started With EODHD
&lt;/h2&gt;

&lt;p&gt;If you want to build something similar, EODHD is where I'd start. The free tier gives you access to end-of-day data for US equities — enough to prototype the full workflow before committing to a paid plan.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://eodhd.com/?via=kmg&amp;amp;ref1=Meneses&amp;amp;utm_source=medium&amp;amp;utm_medium=post&amp;amp;utm_campaign=automate-investing-workflow-eodhd-claude-cowork&amp;amp;utm_content=Meneses" rel="noopener noreferrer"&gt;Start with EODHD here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll get access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-of-day prices for 70+ exchanges and 150,000+ tickers&lt;/li&gt;
&lt;li&gt;Full fundamental data: P/E, EPS, dividends, market cap, sector&lt;/li&gt;
&lt;li&gt;Historical data going back 30+ years, delivered via clean JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API is straightforward. The documentation is solid. And unlike scraping or unofficial endpoints, it doesn't break.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;❓ &lt;strong&gt;Do I need coding experience to use this workflow?&lt;/strong&gt;&lt;br&gt;
✅ Claude Cowork writes and runs the Python script for you. Basic familiarity with Python helps when customizing the output, but you don't need to write the script from scratch.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;What brokers does this work with?&lt;/strong&gt;&lt;br&gt;
✅ Any broker that lets you export a CSV transaction history. Degiro, Interactive Brokers, Binance, and most major European and US brokers support this. Cowork handles the format differences automatically.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Is the EODHD free tier enough to get started?&lt;/strong&gt;&lt;br&gt;
✅ Yes. The free tier includes end-of-day data for US equities, which is sufficient to build and test the full pipeline. Upgrading unlocks real-time data, international exchanges, and extended fundamentals.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Can I use this with crypto positions?&lt;/strong&gt;&lt;br&gt;
✅ EODHD covers major crypto pairs. Binance exports can be normalized by Cowork using the same workflow — the ticker format just needs to be mapped to EODHD's convention (e.g. &lt;code&gt;BTC-USD&lt;/code&gt;).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for technical content for your company? I can help — &lt;a href="https://www.linkedin.com/in/kevin-meneses-gonzalez/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="mailto:kevinmenesesgonzalez@gmail.com"&gt;kevinmenesesgonzalez@gmail.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>investing</category>
      <category>claude</category>
      <category>data</category>
      <category>api</category>
    </item>
  </channel>
</rss>
