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:
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:
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:
👉 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:
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:
2. Interactive Timeline
3. Price Distribution
4. Detailed Transactions Table
How to Use This to Spot Opportunities
This dashboard gives you three main edges:
A Real-World Play
Imagine you track insiders buying Microsoft at $250 while the market trades at $260. You know:
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?
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.