Bygg en aktiescanner i Python: Kombinera Blankningsregistret & Insynsregistret

Steg-för-steg-guide till hur du kombinerar Finansinspektionens blankningsregister och insynsregister via BörsAPI i Python för att identifiera Short Squeeze-kandidater och varningsflaggor.

27 juli 20266 min läsning

Att hålla koll på blankning och insynshandel är två av de mest kraftfulla verktygen för investerare. Men den verkliga magin uppstår när man kombinerar båda datakällorna. I den här guiden visar vi hur du i Python bygger en automatiserad aktiescanner som hittar unika köp- och säljsignaler på den svenska börsen via BörsAPI.

Varför är kombinationen av insynsköp och blankning så kraftfull?

  • Bullish Signal (Potential för Short Squeeze): Ett bolag har hög blankningsgrad (≥ 3 %), men bolagets VD eller nyckelpersoner gör stora nettoköp. När insiders köper trots blankartryck tyder det på att marknaden kan ha felvärderat bolaget och att en squeeze kan ligga nära.
  • Bearish Signal (Varningsflagga): Blankningen stiger samtidigt som insiders säljer sina aktier. Detta bekräftar ofta blankarnas tes om underliggande svaghet i bolaget.

Steg 1: Installera beroenden

Vi använder de populära Python-biblioteken requests för API-anrop och pandas för tabeller och datastruktur:

pip install requests pandas

Steg 2: Vilka API-endpoints behöver vi?

För att bygga scannern använder vi två av BörsAPI:s standardiserade endpoints:

  • GET /api/v1/short-positions?min_percentage=1.0 – Returns alla noterade bolag på svenska börsen som har minst 1,0 % total blankningsgrad.
  • GET /api/v1/companies/:id/insider-statistics – Returns sammanställd nettoköpsstatistik för 30, 90 och 365 dagar samt VD-nettoköp i SEK.

Steg 3: Komplett Python-skript för scannern

Klistra in följande skript i en Python-fil (t.ex. stock_scanner.py) och ersätt fd_din_api_nyckel_här med din personliga API-nyckel:

import requests
import pandas as pd

API_KEY = "fd_din_api_nyckel_här"
BASE_URL = "https://borsapi.se/api/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Accept": "application/json"
}

def run_scanner():
    print("🔎 Hämtar mest blankade bolagen från BörsAPI...")
    
    # 1. Hämta alla bolag med minst 1.0% blankning
    short_url = f"{BASE_URL}/short-positions?min_percentage=1.0&limit=100"
    resp = requests.get(short_url, headers=HEADERS)
    
    if resp.status_code != 200:
        print(f"Fel vid hämtning av blankning: {resp.status_code} - {resp.text}")
        return

    short_companies = resp.json()
    print(f"Hittade {len(short_companies)} bolag med >= 1.0% blankning. Analyserar insynshandel...\n")

    results = []

    # 2. Analysera insynshandel för varje blankat bolag
    for comp in short_companies:
        isin = comp.get("isin")
        name = comp.get("name")
        total_short_pct = comp.get("total_short_percentage", 0.0)

        # Hämta insynsstatistik
        insider_url = f"{BASE_URL}/companies/{isin}/insider-statistics"
        insider_resp = requests.get(insider_url, headers=HEADERS)
        
        if insider_resp.status_code == 200:
            insider_data = insider_resp.json()
            stats_90d = insider_data.get("period_90d", {})
            
            net_buy_90d = stats_90d.get("net_buy_sek", 0)
            ceo_net_buy = stats_90d.get("ceo_net_buy_sek", 0)
            buy_tx_count = stats_90d.get("buy_count", 0)
            sell_tx_count = stats_90d.get("sell_count", 0)

            # 3. Klassificera signal
            signal = "NEUTRAL"
            if total_short_pct >= 3.0 and (ceo_net_buy > 0 or net_buy_90d > 500_000):
                signal = "🔥 BULLISH (Short Squeeze Candidate)"
            elif total_short_pct >= 3.0 and net_buy_90d < -1_000_000:
                signal = "⚠️ BEARISH (Insiders Selling)"

            results.append({
                "Bolag": name,
                "ISIN": isin,
                "Blankning (%)": round(total_short_pct, 2),
                "Nettoköp 90d (SEK)": net_buy_90d,
                "VD-köp (SEK)": ceo_net_buy,
                "Köp/Sälj (90d)": f"{buy_tx_count}/{sell_tx_count}",
                "Signal": signal
            })

    # 4. Skapa och sortera Pandas DataFrame
    df = pd.DataFrame(results)
    df = df.sort_values(by="Blankning (%)", ascending=False)
    
    print("--- SCANNERRAPPORT ---")
    print(df.to_string(index=False))

if __name__ == "__main__":
    run_scanner()

Steg 4: Tolka resultatet och sätt upp larm

När du kör skriptet får du en tydlig tabell sorterad efter blankningsprocent med klassificerade signaler:

  • 🔥 BULLISH (Short Squeeze Candidate): Visas när ett bolag har minst 3 % blankning och insynsköpen de senaste 90 dagarna överstiger 500 000 SEK (eller att VD varit nettoköpare). Det visar att ledningen investerar sina egna pengar i bolaget samtidigt som marknaden bettar mot det.
  • ⚠️ BEARISH (Insiders Selling): Visas när blankningen är hög och ledningen samtidigt sålt för över 1 000 000 SEK.

💡 Vidareutveckling: Telegram & Discord Larm

Du kan enkelt utöka skriptet med ett requests.post() till en Discord Webhook eller Telegram Bot API. På så sätt kan du köra koden automatiskt varje kväll kl 20:00 (när Finansinspektionen uppdaterat dagsdatan) och få en pushnotis direkt i mobilen om någon aktie triggar en köpsignal!

Kom igång med BörsAPI

För att använda dessa mallar och skript behöver du ett personligt konto och en API-nyckel. Det är helt kostnadsfritt under vår beta-period.

1. Skapa konto

Registrera dig på några sekunder via registreringssidan.

2. Generera API-nyckel

Gå till din Dashboard och klicka på "Generera API-nyckel".

3. Anslut i mallen

Ersätt placeholder-nyckeln i källkoden eller kalkylarket med din personliga nyckel.

    Bygg en aktiescanner i Python: Kombinera Blankningsregistret & Insynsregistret - BörsAPI.se