How I Made Smarter Trades Tracking Insider Activity with Python + EODHD API

How I Made Smarter Trades Tracking Insider Activity with Python + EODHD API


He who lives by the golden rule makes the golden rules.” — Ray Dalio


The Hidden Signals You’re Probably Ignoring

If you’re like most retail traders, you spend hours scanning charts, looking for technical setups, or reading market news. But there’s one signal that rarely makes it to the mainstream: insider transactions.

When a CEO, CFO, or even a U.S. Congress member buys or sells shares of a company, they’re acting on information you and I don’t see yet. And as Ray Dalio said, “He who lives by the golden rule makes the golden rules.” These insiders make the rules — and following their moves can be a powerful edge.

But here’s the problem:

  • SEC Form 4 filings are buried in ugly XML files.
  • There’s no simple dashboard to spot unusual trades at a glance.
  • Most investors don’t even know where to start.


How I Turned Insider Data into Profits 

In 2024, I was holding shares of a mid-cap tech company. The fundamentals were solid, but the stock was stagnant. One night, I decided to test EODHD’s Insider Transactions API out of curiosity.

To my surprise, I found that multiple senior executives had been quietly buying shares at prices close to where it was trading. This wasn’t a one-off — it was a pattern.

That gave me the conviction to increase my position. A month later, the company announced a game-changing partnership, and the stock rallied more than 18%. That trade alone covered my annual data tools budget.

Since then, tracking insider transactions has been part of my trading playbook — and it’s been worth every minute.


Step 1: Testing the API (Getting the Raw Data)

Before building dashboards, we need to see what data we can extract. EODHD provides an endpoint for Insider Transactions (Form 4).

API Endpoint:

https://eodhd.com/api/insider-transactions?api_token=YOUR_API_KEY&code=TICKER        

You get a JSON similar to

[
  {
    "code": "MSFT",
    "exchange": "US",
    "date": "2025-06-27",
    "reportDate": "2025-07-01",
    "ownerCik": null,
    "ownerName": "Michael T. McCaul",
    "ownerRelationship": null,
    "ownerTitle": "U.S. Congress Member <small>(R-TX)</small>",
    "transactionDate": "2025-06-27",
    "transactionCode": "S",
    "transactionAmount": null,
    "transactionPrice": 495.94,
    "transactionAcquiredDisposed": "D",
    "postTransactionAmount": null,
    "link": null
  },
  {
    "code": "MSFT",
    "exchange": "US",
    "date": "2025-06-25",
    "reportDate": "2025-06-27",
    "ownerCik": null,
    "ownerName": "Cleo Fields",
    "ownerRelationship": null,
    "ownerTitle": "U.S. Congress Member <small>(D-LA)</small>",
    "transactionDate": "2025-06-25",
    "transactionCode": "P",
    "transactionAmount": null,
    "transactionPrice": 492.27,
    "transactionAcquiredDisposed": "A",
    "postTransactionAmount": null,
    "link": null
  },
  {
    "code": "MSFT",
    "exchange": "US",
    "date": "2025-06-23",
    "reportDate": "2025-06-25",
    "ownerCik": null,
    "ownerName": "Ro Khanna",
    "ownerRelationship": null,
    "ownerTitle": "U.S. Congress Member <small>(D-CA)</small>",
    "transactionDate": "2025-06-23",
    "transactionCode": "P",
    "transactionAmount": null,
    "transactionPrice": 486,
    "transactionAcquiredDisposed": "A",
    "postTransactionAmount": null,
    "link": null
  }
]        

This gives you:

  • Insider’s name & title (e.g., CEO, Congress Member).
  • Transaction date & price.
  • Number of shares traded.
  • Relationship (if available).

Testing Script

import requests
import pandas as pd
import json

API_KEY = "YOUR_API_KEY"
TICKER = "MSFT"

url = f"https://eodhd.com/api/insider-transactions?api_token={API_KEY}&code={TICKER}"
response = requests.get(url)

if response.status_code == 200:
    data = response.json()
    print("\nRaw JSON sample:")
    print(json.dumps(data[:3], indent=2))  # Show first 3 records

    df = pd.DataFrame(data)
    print("\nColumns available:")
    print(df.columns.tolist())
else:
    print("Error fetching data:", response.text)        

What we get:

Running this returns a clean JSON with the fields:

  • ownerName → Insider’s name
  • ownerTitle → Their role
  • transactionDate → Date of the transaction
  • transactionPrice → Price per share
  • transactionAmount → Number of shares
  • ownerRelationship → Insider’s relationship (if any)

👉 Pro Tip: Use this script whenever you’re testing a new endpoint. It’s the fastest way to understand the data structure.


Step 2: Building the Insider Transactions Dashboard

Now that we know what data we can pull, let’s build a Streamlit dashboard to make it actionable.


Features:

  • Company Ticker Input — Analyze any company (e.g., AAPL, MSFT).
  • Date Range Filter — Focus on recent transactions.
  • Interactive Charts — See transaction price trends & distributions.
  • Dynamic Table — Only the fields that matter (ownerName, ownerTitle, transactionDate, transactionPrice, transactionAmount).
  • Quick Metrics — Average transaction price, total shares traded, total transactions.

Full Python Code:

import requests
import pandas as pd
import streamlit as st
import plotly.express as px

# --------- FUNCTIONS ---------
def fetch_insider_data(ticker, api_key):
    url = f"https://eodhd.com/api/insider-transactions?api_token={api_key}&code={ticker}"
    response = requests.get(url)
    if response.status_code == 200:
        df = pd.DataFrame(response.json())
        if not df.empty and 'transactionDate' in df.columns:
            df['transactionDate'] = pd.to_datetime(df['transactionDate'])
        return df
    else:
        st.error("Error fetching data. Check your API key or ticker.")
        return pd.DataFrame()

# --------- STREAMLIT APP ---------
st.set_page_config(page_title="Insider Transactions Dashboard", layout="wide")

st.title("📊 Insider Transactions Dashboard")
st.markdown("Track **insider trades** (SEC Form 4) using [EODHD API](https://eodhd.com/pricing-special-10?via=kmg&ref1=Meneses).")

# --- API KEY & TICKER INPUT ---
api_key = st.text_input("Enter your EODHD API Key:", type="password")
ticker = st.text_input("Enter a company ticker (e.g., AAPL, MSFT):", value="MSFT").upper()

if api_key and ticker:
    df = fetch_insider_data(ticker, api_key)

    if df.empty:
        st.warning("No data found for this ticker.")
    else:
        # --- Keep only relevant columns ---
        columns_needed = ['ownerName', 'ownerTitle', 'ownerRelationship', 'transactionDate', 'transactionPrice', 'transactionAmount']
        df = df[[c for c in columns_needed if c in df.columns]]

        # --- Date Filter ---
        if 'transactionDate' in df.columns:
            min_date, max_date = df['transactionDate'].min(), df['transactionDate'].max()
            date_range = st.sidebar.date_input("Filter by date range:", [min_date, max_date])
            if len(date_range) == 2:
                df = df[(df['transactionDate'] >= pd.to_datetime(date_range[0])) & (df['transactionDate'] <= pd.to_datetime(date_range[1]))]

        # --- Layout: Metrics + Charts ---
        st.subheader(f"Insider Transactions for {ticker}")
        col1, col2 = st.columns(2)
        with col1:
            st.metric("Total Transactions", len(df))
            avg_price = df['transactionPrice'].mean() if 'transactionPrice' in df.columns else 0
            st.metric("Average Transaction Price", f"${avg_price:,.2f}")
        with col2:
            total_amount = df['transactionAmount'].sum() if 'transactionAmount' in df.columns else 0
            st.metric("Total Shares Traded", f"{total_amount:,.0f}")

        # --- Charts ---
        st.subheader("Visual Analysis")
        if 'transactionDate' in df.columns and 'transactionPrice' in df.columns:
            fig_timeline = px.scatter(
                df,
                x='transactionDate',
                y='transactionPrice',
                hover_data=['ownerName', 'ownerTitle'],
                title="Transaction Price Over Time",
                labels={'transactionDate': 'Date', 'transactionPrice': 'Price ($)'},
                template="plotly_white"
            )
            st.plotly_chart(fig_timeline, use_container_width=True)

        if 'transactionPrice' in df.columns:
            fig_hist = px.histogram(
                df,
                x='transactionPrice',
                nbins=30,
                title="Distribution of Transaction Prices",
                labels={'transactionPrice': 'Price ($)'},
                template="plotly_white"
            )
            st.plotly_chart(fig_hist, use_container_width=True)

        # --- Data Table ---
        st.subheader("Detailed Transactions")
        st.dataframe(df.sort_values(by='transactionDate', ascending=False))
else:
    st.info("Please enter your API key and a company ticker to load data.")        

How to Run It

pip install requests pandas streamlit plotly
streamlit run insider_dashboard_pro.py        

What You Get From the Dashboard (and How to Use It to Make Money)

This isn’t just a pretty dashboard — it’s a signal detector for hidden market moves.

When you load a ticker (say, MSFT or AAPL), you get:

  1. Quick Metrics

  • Total Transactions → How active insiders are in the company. A spike here often precedes major announcements.
  • Average Transaction Price → Lets you see if insiders are buying/selling at current levels or positioning ahead of the market.
  • Total Shares Traded → Helps you gauge conviction. A few hundred shares? Probably noise. Millions? That’s meaningful.

Article content

2. Interactive Timeline

  • The scatter plot shows you transaction prices over time
  • This helps you spot clusters of insider buying or selling — which can signal entry or exit points.

Article content


3. Price Distribution

  • The histogram reveals the price levels where most insider transactions occurred.
  • If insiders are buying heavily below current market price, it can indicate support levels they consider attractive.

Article content


4. Detailed Transactions Table

  • See who traded (CEO? Congress Member?), how many shares, and at what price.
  • This is actionable intelligence — the “why” behind the trade matters. A CEO buying in size? Strong bullish signal. A congress member selling before a policy vote? You might want to avoid exposure.

Article content


How to Use This to Spot Opportunities

This dashboard gives you three main edges:

  • Follow the smart money:  If executives or policymakers are buying, they’re showing confidence. Historically, insider buys have outperformed market averages.
  • Avoid value traps:  If insiders are dumping shares en masse, it could indicate bad news ahead. You can reduce your position or hedge before the market reacts.
  • Time your entries/exits:  Insider clusters (several buys around the same time) can mark inflection points. This gives you a clearer view than technical indicators alone.


A Real-World Play

Imagine you track insiders buying Microsoft at $250 while the market trades at $260. You know:

  • They see value near that level.
  • You can set your limit orders near their entry points, reducing downside risk.
  • If the cluster of insider buying grows, you can scale in with more confidence.

This is data-driven trading — no rumors, no guessing, just following the people who know the business best.


Why This Matters for Your Portfolio

Insider trading data is undervalued alpha. These trades often precede major announcements — mergers, product launches, and partnerships.  Instead of being reactive, you can position yourself early, based on signals the market hasn’t fully priced in.


Ready to Build Your Own Insider Dashboard?

You can start tracking insider trades today with EODHD.  👉 Get 10% off EODHD here.

It’s the same tool I used to build my workflow — and it’s been worth every penny.

“Pain + Reflection = Progress” — Ray Dalio

Don’t wait for the news to tell you what insiders are doing. See it first. Act smarter.

👉 Try EODHD now and take control of your data-driven investing.

To view or add a comment, sign in

Others also viewed

Explore topics