Hallo & erstmal Danke für eure Antworten!
Ich will mein Vorhaben mal etwas detaillierter beschreiben:
Ich möchte aus meiner Handelsstatistik (Bild Excel 1 ,2 ,3) folgende Daten per Mausklick in ein Word Dokument übertragen:
1: Tag und Uhrzeit (soll ausgelesen werden)
2: Handelsinstrument (immer gleich )
3: Kontraktanzahl ( immer 2 MNQ Kontrakte)
4 Entry: (soll ausgelesen werden)
5 Exit: (soll ausgelesen werden)
6 Gewinn/Verlust (soll ausgelesen werden)
7 Screenshot ( es soll ein .png aus einem "Screenshot Ordner" eingefügt werden zb. nur in diesem Format : 09.09.205 Trade 1
dann kommt ein Word dokument für persönliche Notizen, da schreibe ich details zum Trade rein.
Bild( Word 1 + 2)
Das ganze läuft dann für 3 Trades an einem Tag- das Ganze also mal 3.
Die letzten Probleme waren:
-die Kontrakte immer falsch berechnet wurden. ( die Preise bei "Entry " sind manchmal unterschiedlich)
-die Screenshots konnten nicht gefunden werden trotz richtiger Schreibweise /Pfadeingabe etc.
-meine persönlichen Notizen wurden immer bei starten des "Tradematchers" überschrieben.
Ich hab dann ein paar Fixe mit Powershell gemacht aber kein stabiles Ergebnis mit Chat-gpt erreicht.
Hier sind die Bilder:
https://imgur.com/a/vKdFjGF
Für Hilfe jeglicher Art bei meinem Projekt wäre ich dankbar.
Hier ist der Phyton Code des tradematchers,den ich über eine .bat starte :
# -*- coding: utf-8 -*-
"""
TradeMatcher_Clean.py
Voraussetzungen (einmalig):
    pip install pandas python-docx openpyxl
"""
import os, re, glob, unicodedata, datetime as dt
import pandas as pd
from docx import Document
from docx.shared import Pt, Inches
# ======= KONFIG =======
DESKTOP      = os.path.normpath(os.path.join(os.environ.get("USERPROFILE",""), "Desktop"))
ATAS_GLOB    = os.path.join(DESKTOP, "ATAS_statistics_realtime*.xlsx")  # neueste Datei wird genommen
EXPORT_DIR   = os.path.join(DESKTOP, "Trade Archiv")
SCREEN_DIR   = os.path.join(DESKTOP, "Trades_Phyton")                    # Screenshot-Ordner (ohne Umlaut)
SECONDS_GROUP = 120   # ±2 Min zu einem Trade zusammenfassen
# ======================
def log(x): print(str(x), flush=True)
def ensure_dir(p): os.makedirs(p, exist_ok=True); return p
# ---- ATAS laden ----
def find_latest_atas(pattern: str) -> str:
    files = sorted(glob.glob(pattern), key=os.path.getmtime, reverse=True)
    if not files:
        raise FileNotFoundError(f"Keine ATAS-Datei gefunden (Muster: {pattern})")
    return files[0]
def load_journal(xlsx_path: str) -> pd.DataFrame:
    xl = pd.ExcelFile(xlsx_path)
    sheet = next((n for n in xl.sheet_names if "ournal" in n.lower()), xl.sheet_names[0])
    df = xl.parse(sheet)
    for c in ("Open time","Close time"):
        if c in df.columns:
            df[c] = pd.to_datetime(df[c], errors="coerce")
    return df
# ---- Trades gruppieren ----
def coalesce_trades(df: pd.DataFrame, seconds: int = SECONDS_GROUP) -> pd.DataFrame:
    if df is None or df.empty: return df
    need = ["Instrument","Open time"]
    for c in need:
        if c not in df.columns:
            raise ValueError(f"Spalte fehlt im Journal: {c}")
    df = df.sort_values("Open time").reset_index(drop=True)
    tol = pd.Timedelta(seconds=seconds)
    used=set(); groups=[]
    for i,row in df.iterrows():
        if i in used: continue
        cur=
; used.add(i)
        for j in range(i+1, len(df)):
            if j in used: continue
            r2 = df.iloc[j]
            if str(row["Instrument"]) != str(r2["Instrument"]): continue
            t1, t2 = row["Open time"], r2["Open time"]
            if pd.notna(t1) and pd.notna(t2) and abs(t2 - t1) <= tol:
                cur.append(j); used.add(j)
            else:
                if pd.notna(t1) and pd.notna(t2) and (t2 - t1) > tol:
                    break
        groups.append(cur)
    rows=[]
    for idxs in groups:
        g = df.iloc[idxs]
        base = {}
        base["Open time"]  = pd.to_datetime(g["Open time"]).min()
        base["Close time"] = pd.to_datetime(g["Close time"], errors="coerce").max() if "Close time" in g.columns else pd.NaT
        base["Instrument"] = str(g["Instrument"].iloc[0])
        base["Open price"] = pd.to_numeric(g["Open price"], errors="coerce").iloc[0] if "Open price" in g.columns else pd.NA
        base["Close price"]= pd.to_numeric(g["Close price"],errors="coerce").iloc[-1] if "Close price" in g.columns else pd.NA
        # KONTRAKTE = MAX(abs(Open volume))
        if "Open volume" in g.columns:
            contracts = pd.to_numeric(g["Open volume"], errors="coerce").abs().max()
        else:
            contracts = pd.NA
        base["__contracts"] = float(contracts) if (contracts is not pd.NA and pd.notna(contracts)) else pd.NA
        # PnL / Ticks summieren
        if "PnL" in g.columns:
            base["PnL"] = pd.to_numeric(g["PnL"], errors="coerce").fillna(0).sum()
        if "Profit (ticks)" in g.columns:
            base["Profit (ticks)"] = pd.to_numeric(g["Profit (ticks)"], errors="coerce").fillna(0).sum()
        rows.append(base)
    out = pd.DataFrame(rows).sort_values("Open time").reset_index(drop=True)
    return out
# ---- Screenshot-Finder (rekursiv, Mehrfach-Zuordnung) ----
def _norm(s:str)->str:
    s = unicodedata.normalize("NFC", s or "")
    return re.sub(r"\s+", " ", s.strip())
def find_screens_for_day(day: dt.date, root: str) -> dict:
    """
    Map {trade_nr -> path}. Akzeptiert:
      DD.MM, DD.MM.YYYY, YYYY-MM-DD  +  'Trade N'
      Mehrfach: 'Trade 1 (2 +3)' -> gilt für 1,2,3
    """
    mapping={}
    if not os.path.isdir(root):
        log(f"[SHOT] Ordner fehlt: {root}")
        return mapping
    dd,mm,yy = day.day, day.month, day.year
    pat_date = re.compile(rf"(?:{yy}-{mm:02d}-{dd:02d}|0?{dd}[.\-_/]\s*0?{mm}(?:[.\-_/]\s*{yy})?)", re.I)
    pat_ext  = re.compile(r"\.(?:png|jpg|jpeg)$", re.I)
    pat_main = re.compile(r"trade\s*(\d+)", re.I)
    pat_extra= re.compile(r"\(([^)]*)\)")
    for dirpath, dirnames, filenames in os.walk(root):
        for name in filenames:
            if not pat_ext.search(name): continue
            n=_norm(name)
            if not pat_date.search(n): continue
            m=pat_main.search(n)
            if not m: continue
            nums=[int(m.group(1))]
            m2=pat_extra.search(n)
            if m2:
                for part in re.split(r"[,+\s]+", m2.group(1)):
                    part=part.strip()
                    if part.isdigit():
                        nums.append(int(part))
            fpath=os.path.join(dirpath, name)
            for no in nums:
                mapping.setdefault(no, fpath)
    log(f"[SHOT] Zuordnung {day}: {mapping}")
    return mapping
# ---- Word-Helfer ----
def add_bold_line(doc, label, value):
    p = doc.add_paragraph()
    r = p.add_run(f"{label}: ")
    r.bold = True
    if value is None or (isinstance(value,float) and pd.isna(value)):
        p.add_run("–")
    else:
        p.add_run(str(value))
def add_notes_page_for_trade(doc, trade_nr):
    # neue Seite
    doc.add_page_break()
    # Überschrift
    h = doc.add_paragraph()
    r = h.add_run(f"Notizen zu Trade {trade_nr}")
    r.bold = True
    r.font.size = Pt(16)
    # Allgemeine Überschrift
    p0 = doc.add_paragraph()
    r0 = p0.add_run("Erwartungen loslassen")
    r0.bold = True
    r0.font.size = Pt(12)
    doc.add_paragraph()  # Leerzeile
    def block(label, empty_lines=6):
        p = doc.add_paragraph()
        rb = p.add_run(f"{label}:")
        rb.bold = True
        for _ in range(empty_lines):
            doc.add_paragraph("")
    block("Setup")
    block("Struktur/Kontext")
    block("Kommentar mit Trademanagement")
    block("Emotionaler Stop? Wenn ja warum")
def write_day(doc, df_day: pd.DataFrame, day: dt.date, shots: dict):
    section = doc.sections[0]
    mg = Pt(24)
    section.top_margin = section.bottom_margin = section.left_margin = section.right_margin = mg
    doc.add_heading(f"Trade Übersicht – {day.strftime('%Y-%m-%d')}", level=1)
    EMU=914400
    usable = (section.page_width - section.left_margin - section.right_margin)/EMU
    for i,row in df_day.reset_index(drop=True).iterrows():
        trade_nr = i+1
        doc.add_heading(f"Trade {trade_nr}", level=2)
        t = row.get("Open time")
        zeit = pd.to_datetime(t).strftime("%d.%m.%Y %H:%M:%S") if pd.notna(t) else "–"
        add_bold_line(doc, " Tag + Uhrzeit", zeit)
 Tag + Uhrzeit", zeit)
        add_bold_line(doc, " Handelsinstrument", row.get("Instrument","–"))
 Handelsinstrument", row.get("Instrument","–"))
        add_bold_line(doc, " Kontraktanzahl", row.get("__contracts","–"))
 Kontraktanzahl", row.get("__contracts","–"))
        add_bold_line(doc, " Entry", row.get("Open price","–"))
 Entry", row.get("Open price","–"))
        add_bold_line(doc, " Exit",  row.get("Close price","–"))
 Exit",  row.get("Close price","–"))
        pnl = row.get("PnL","–"); ticks = row.get("Profit (ticks)","–")
        add_bold_line(doc, " Gewinn/Verlust", f"{pnl} $ ({ticks} Ticks)")
 Gewinn/Verlust", f"{pnl} $ ({ticks} Ticks)")
        label = f"{day.day:02d}.{day.month:02d} Trade {trade_nr}"
        add_bold_line(doc, " Screenshot", label)
 Screenshot", label)
        path = shots.get(trade_nr)
        if path and os.path.exists(path):
            try:
                doc.add_picture(path, width=Inches(usable*0.98))
            except Exception as e:
                doc.add_paragraph(f"(Fehler beim Einfügen des Screenshots: {e})")
        else:
            doc.add_paragraph("(Kein Screenshot gefunden)")
        # direkt danach Notizseite
        add_notes_page_for_trade(doc, trade_nr)
def export_day(df_day, day: dt.date, shots: dict) -> str:
    doc = Document()
    write_day(doc, df_day, day, shots)
    ensure_dir(EXPORT_DIR)
    out = os.path.join(EXPORT_DIR, f"Trade_Übersicht_{day.strftime('%Y-%m-%d')}.docx")
    doc.save(out)
    log(f"[OK] {out}")
    return out
def main():
    ensure_dir(EXPORT_DIR)
    ensure_dir(SCREEN_DIR)
    xlsx = find_latest_atas(ATAS_GLOB)
    log(f"[ATAS] Datei: {xlsx}")
    df  = load_journal(xlsx)
    dfg = coalesce_trades(df, seconds=SECONDS_GROUP)
    if dfg.empty:
        log("[FAIL] Keine Trades gefunden."); return
    dfg["__date__"] = pd.to_datetime(dfg["Open time"]).dt.date
    days = sorted([d for d in dfg["__date__"].dropna().unique()])
    results=[]
    for d in days:
        d = d if isinstance(d, dt.date) else d.to_pydatetime().date()
        df_day = dfg[dfg["__date__"]==d].copy().reset_index(drop=True)
        shots = find_screens_for_day(d, SCREEN_DIR)
        results.append(export_day(df_day, d, shots))
    log("Fertig.")
    for r in results: log(" - " + r)
if __name__ == "__main__":
    main()