29 KiB
29 KiB
In [2]:
# 📦 Imports
import MetaTrader5 as mt
import pandas as pd
import sqlite3 as db
from datetime import datetime
import time
from scipy.signal import savgol_filter
import pandas_ta as ta
import keyring as krIn [3]:
# 📊 Verbindung zu SQLite
def init_db(db_name="trading_log.db"):
conn = db.connect(db_name)
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS trade_log (
timestamp TEXT,
symbol TEXT,
order_type TEXT,
price REAL,
sl REAL,
tp REAL,
volume REAL,
signal INTEGER,
comment TEXT
)
""")
conn.commit()
return connIn [7]:
# 🔐 MT5 Login einmalig initialisieren
mt.initialize()
login = 10800246
server = "VantageInternational-Demo"
password = kr.get_password(server, str(login))
mt.login(login, password, server)Out [7]:
True
In [8]:
# 📥 MT5 Daten abrufen
def get_mt5_data(symbol="XAUUSD", timeframe=mt.TIMEFRAME_M5, n_bars=500):
rates = mt.copy_rates_from_pos(symbol, timeframe, 0, n_bars)
df = pd.DataFrame(rates)
df["time"] = pd.to_datetime(df["time"], unit="s")
return dfIn [9]:
df = get_mt5_data()In [11]:
# 🤖 Signale erzeugen
def generate_signal(df):
df["ema10"] = df["close"].ewm(span=10).mean()
df["ema30"] = df["close"].ewm(span=30).mean()
df["rsi"] = ta.rsi(df["close"], length=14)
df["trend"] = savgol_filter(df["close"], 15, 3)
df["signal"] = 0
for i in range(1, len(df)):
if (
df["ema10"].iloc[i] > df["ema30"].iloc[i]
and df["ema10"].iloc[i - 1] <= df["ema30"].iloc[i - 1]
and df["rsi"].iloc[i] < 70
and df["trend"].iloc[i] > df["trend"].iloc[i - 1]
):
df.at[i, "signal"] = 1
elif (
df["ema10"].iloc[i] < df["ema30"].iloc[i]
and df["ema10"].iloc[i - 1] >= df["ema30"].iloc[i - 1]
and df["rsi"].iloc[i] > 30
and df["trend"].iloc[i] < df["trend"].iloc[i - 1]
):
df.at[i, "signal"] = -1
return dfIn [12]:
generate_signal(df)Out [12]:
| time | open | high | low | close | tick_volume | spread | real_volume | ema10 | ema30 | rsi | trend | signal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2025-07-17 04:30:00 | 3340.74 | 3341.46 | 3337.21 | 3338.04 | 1293 | 18 | 0 | 3338.040000 | 3338.040000 | NaN | 3338.208386 | 0 |
| 1 | 2025-07-17 04:35:00 | 3338.03 | 3341.03 | 3337.72 | 3341.03 | 964 | 18 | 0 | 3339.684500 | 3339.584833 | NaN | 3340.377874 | 0 |
| 2 | 2025-07-17 04:40:00 | 3341.03 | 3341.48 | 3339.96 | 3341.26 | 944 | 18 | 0 | 3340.317841 | 3340.180848 | NaN | 3341.873882 | 0 |
| 3 | 2025-07-17 04:45:00 | 3341.27 | 3343.45 | 3341.27 | 3342.47 | 1099 | 18 | 0 | 3341.026881 | 3340.811593 | NaN | 3342.785860 | 0 |
| 4 | 2025-07-17 04:50:00 | 3342.47 | 3343.61 | 3342.20 | 3342.84 | 1070 | 18 | 0 | 3341.547378 | 3341.273104 | NaN | 3343.203260 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 495 | 2025-07-18 22:45:00 | 3349.29 | 3349.71 | 3348.47 | 3348.78 | 928 | 19 | 0 | 3350.024962 | 3351.232735 | 34.935115 | 3348.405247 | 0 |
| 496 | 2025-07-18 22:50:00 | 3348.79 | 3348.80 | 3347.62 | 3348.15 | 859 | 19 | 0 | 3349.684060 | 3351.033849 | 32.290909 | 3348.186635 | 0 |
| 497 | 2025-07-18 22:55:00 | 3348.16 | 3348.53 | 3347.65 | 3348.25 | 1028 | 19 | 0 | 3349.423322 | 3350.854245 | 33.155760 | 3348.153324 | 0 |
| 498 | 2025-07-18 23:00:00 | 3348.24 | 3348.88 | 3347.72 | 3348.06 | 599 | 19 | 0 | 3349.175445 | 3350.673972 | 32.311285 | 3348.346744 | 0 |
| 499 | 2025-07-18 23:05:00 | 3348.06 | 3349.25 | 3347.92 | 3348.88 | 450 | 19 | 0 | 3349.121728 | 3350.558231 | 39.476021 | 3348.808327 | 0 |
500 rows × 13 columns
In [14]:
mt.symbol_info('XAUUSD').pointOut [14]:
0.01
In [ ]:
# 📤 Order senden
def send_market_order(symbol, volume, order_type, signal, conn, sl_pips=20, tp_pips=40, magic=1001):
tick = mt.symbol_info_tick(symbol)
price = tick.ask if order_type == mt.ORDER_TYPE_BUY else tick.bid
point = mt.symbol_info(symbol).point
sl = price - sl_pips * point if order_type == mt.ORDER_TYPE_BUY else price + sl_pips * point
tp = price + tp_pips * point if order_type == mt.ORDER_TYPE_BUY else price - tp_pips * point
request = {
"action": mt.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": volume,
"type": order_type,
"price": price,
"sl": round(sl, 5),
"tp": round(tp, 5),
"deviation": 20,
"magic": magic,
"comment": "AutoSignalBot",
"type_time": mt.ORDER_TIME_GTC,
"type_filling": mt.ORDER_FILLING_IOC,
}
result = mt.order_send(request)
print(f"[TRADE] {symbol} - {'BUY' if order_type==0 else 'SELL'} @ {price} | SL: {sl} | TP: {tp}")
# Logging in DB
c = conn.cursor()
c.execute("""
INSERT INTO trade_log (timestamp, symbol, order_type, price, sl, tp, volume, signal, comment)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (datetime.now(), symbol, "BUY" if order_type==0 else "SELL", price, sl, tp, volume, signal, "AutoSignalBot"))
conn.commit()
return resultIn [13]:
# 🔁 Hauptfunktion
def run_live_trading(symbol="XAUUSD", interval=300, volume=0.1, db_name="trading_log.db"):
conn = init_db(db_name)
last_signal = 0
print(f"✅ Starte Auto-Trading für {symbol} – Intervall {interval}s")
while True:
df = get_mt5_data(symbol)
df = generate_signal(df)
signal = df["signal"].iloc[-1]
if signal != 0 and signal != last_signal:
order_type = mt.ORDER_TYPE_BUY if signal == 1 else mt.ORDER_TYPE_SELL
send_market_order(symbol, volume, order_type, signal, conn)
last_signal = signal
else:
print(f"[{datetime.now()}] Kein neues Signal ({signal})")
time.sleep(interval)In [22]:
# ▶️ Live-Trading starten (z. B. alle 5 Minuten)
run_live_trading("XAUUSD", interval=300, volume=0.1)✅ Starte Auto-Trading für XAUUSD – Intervall 300s
[2025-07-18 12:11:30.004688] Kein neues Signal (0)
[2025-07-18 12:16:30.083605] Kein neues Signal (0)
[2025-07-18 12:21:30.121793] Kein neues Signal (0)
[2025-07-18 12:26:30.174396] Kein neues Signal (0)
[2025-07-18 12:31:30.216996] Kein neues Signal (0)
[2025-07-18 12:36:30.258849] Kein neues Signal (0)
[2025-07-18 12:41:30.313072] Kein neues Signal (0)
[2025-07-18 12:46:30.356620] Kein neues Signal (0)
[2025-07-18 12:51:30.396600] Kein neues Signal (0)
[2025-07-18 12:56:30.442114] Kein neues Signal (0)
[2025-07-18 13:01:30.481155] Kein neues Signal (0)
[2025-07-18 13:06:30.530619] Kein neues Signal (0)
[2025-07-18 13:11:30.566248] Kein neues Signal (0)
[2025-07-18 13:16:30.606701] Kein neues Signal (0)
[2025-07-18 13:21:30.645462] Kein neues Signal (0)
[2025-07-18 13:26:30.686722] Kein neues Signal (0)
[2025-07-18 13:31:31.130100] Kein neues Signal (0)
[2025-07-18 13:36:31.193825] Kein neues Signal (0)
[2025-07-18 13:41:31.381330] Kein neues Signal (0)
[2025-07-18 13:46:31.434187] Kein neues Signal (0)
[2025-07-18 13:51:31.471695] Kein neues Signal (0)
[2025-07-18 13:56:31.507322] Kein neues Signal (0)
[2025-07-18 14:01:31.550436] Kein neues Signal (0)
[2025-07-18 14:06:31.587884] Kein neues Signal (0)
[2025-07-18 14:11:31.665002] Kein neues Signal (0)
[2025-07-18 14:16:31.704012] Kein neues Signal (0)
[2025-07-18 14:21:31.745292] Kein neues Signal (0)
[2025-07-18 14:26:31.783905] Kein neues Signal (0)
[2025-07-18 14:31:31.822325] Kein neues Signal (0)
[2025-07-18 14:36:31.873271] Kein neues Signal (0)
[2025-07-18 14:41:31.914303] Kein neues Signal (0)
[2025-07-18 14:46:31.951585] Kein neues Signal (0)
[2025-07-18 14:51:32.005271] Kein neues Signal (0)
[2025-07-18 14:56:32.046384] Kein neues Signal (0)
[2025-07-18 15:01:32.083259] Kein neues Signal (0)
[2025-07-18 15:06:32.132835] Kein neues Signal (0)
[2025-07-18 15:11:32.176714] Kein neues Signal (0)
[2025-07-18 15:16:32.221857] Kein neues Signal (0)
[2025-07-18 15:21:32.269876] Kein neues Signal (0)
[2025-07-18 15:26:32.313363] Kein neues Signal (0)
[2025-07-18 15:31:32.356954] Kein neues Signal (0)
[2025-07-18 15:36:32.403653] Kein neues Signal (0)
[2025-07-18 15:41:32.449777] Kein neues Signal (0)
[2025-07-18 15:46:32.489053] Kein neues Signal (0)
[TRADE] XAUUSD - SELL @ 3354.56 | SL: 3354.7599999999998 | TP: 3354.16
[2025-07-18 15:56:32.609729] Kein neues Signal (0)
[2025-07-18 16:01:32.650996] Kein neues Signal (0)
[TRADE] XAUUSD - BUY @ 3358.95 | SL: 3358.75 | TP: 3359.35
[2025-07-18 16:11:32.744972] Kein neues Signal (0)
[2025-07-18 16:16:32.791366] Kein neues Signal (0)
[2025-07-18 16:21:32.829930] Kein neues Signal (0)
[2025-07-18 16:26:32.871934] Kein neues Signal (0)
[2025-07-18 16:31:32.912571] Kein neues Signal (0)
[2025-07-18 16:36:32.954745] Kein neues Signal (0)
[2025-07-18 16:41:32.994281] Kein neues Signal (0)
[2025-07-18 16:46:33.048113] Kein neues Signal (0)
[2025-07-18 16:51:33.086281] Kein neues Signal (0)
[2025-07-18 16:56:33.127117] Kein neues Signal (0)
[2025-07-18 17:01:33.177813] Kein neues Signal (0)
[2025-07-18 17:06:33.219713] Kein neues Signal (0)
[2025-07-18 17:11:33.260138] Kein neues Signal (0)
[2025-07-18 17:16:33.302870] Kein neues Signal (0)
[2025-07-18 17:21:33.346259] Kein neues Signal (0)
[2025-07-18 17:26:33.390947] Kein neues Signal (0)
[2025-07-18 17:31:33.434736] Kein neues Signal (0)
[2025-07-18 17:36:33.476901] Kein neues Signal (0)
[2025-07-18 17:41:33.520435] Kein neues Signal (0)
[2025-07-18 17:46:33.575426] Kein neues Signal (0)
[2025-07-18 17:51:33.622573] Kein neues Signal (0)
[2025-07-18 17:56:33.662664] Kein neues Signal (0)
[2025-07-18 18:01:33.703019] Kein neues Signal (0)
[2025-07-18 18:06:33.748220] Kein neues Signal (0)
[2025-07-18 18:11:33.788812] Kein neues Signal (0)
[2025-07-18 18:16:33.827200] Kein neues Signal (0)
[2025-07-18 18:21:33.880825] Kein neues Signal (0)
[2025-07-18 18:26:33.931042] Kein neues Signal (0)
[2025-07-18 18:31:33.982017] Kein neues Signal (0)
[2025-07-18 18:36:34.021865] Kein neues Signal (1)
[2025-07-18 18:41:34.059505] Kein neues Signal (0)
[2025-07-18 18:46:34.100395] Kein neues Signal (0)
[2025-07-18 18:51:34.148794] Kein neues Signal (0)
[2025-07-18 18:56:34.186791] Kein neues Signal (0)
[2025-07-18 19:01:34.227630] Kein neues Signal (0)
[2025-07-18 19:06:34.272331] Kein neues Signal (0)
[2025-07-18 19:11:34.309122] Kein neues Signal (0)
[2025-07-18 19:16:34.350483] Kein neues Signal (0)
[2025-07-18 19:21:34.391638] Kein neues Signal (0)
[2025-07-18 19:26:34.430235] Kein neues Signal (0)
[2025-07-18 19:31:34.476827] Kein neues Signal (0)
[2025-07-18 19:36:34.516804] Kein neues Signal (0)
[2025-07-18 19:41:34.551478] Kein neues Signal (0)
[2025-07-18 19:46:34.600704] Kein neues Signal (0)
[2025-07-18 19:51:34.657098] Kein neues Signal (0)
[2025-07-18 19:56:34.694871] Kein neues Signal (0)
[2025-07-18 20:01:34.750662] Kein neues Signal (0)
[2025-07-18 20:06:34.786445] Kein neues Signal (0)
[2025-07-18 20:11:34.941510] Kein neues Signal (0)
[2025-07-18 20:16:34.997686] Kein neues Signal (0)
[2025-07-18 20:21:35.041835] Kein neues Signal (0)
[2025-07-18 20:26:35.082677] Kein neues Signal (0)
[2025-07-18 20:31:35.135303] Kein neues Signal (0)
[2025-07-18 20:36:35.174403] Kein neues Signal (0)
[2025-07-18 20:41:35.211876] Kein neues Signal (0)
[2025-07-18 20:46:35.254113] Kein neues Signal (0)
[2025-07-18 20:51:35.297650] Kein neues Signal (0)
[2025-07-18 20:56:35.338598] Kein neues Signal (0)
[2025-07-18 21:01:35.378704] Kein neues Signal (0)
[2025-07-18 21:06:35.421315] Kein neues Signal (0)
[2025-07-18 21:11:35.446675] Kein neues Signal (0)
[2025-07-18 21:16:35.501085] Kein neues Signal (0)
[2025-07-18 21:21:35.547489] Kein neues Signal (0)
[2025-07-18 21:26:35.600292] Kein neues Signal (0)
[2025-07-18 21:31:35.642080] Kein neues Signal (0)
[2025-07-18 21:36:35.681283] Kein neues Signal (0)
[2025-07-18 21:41:35.719258] Kein neues Signal (0)
[2025-07-18 21:46:35.756743] Kein neues Signal (0)
[2025-07-18 21:51:35.802329] Kein neues Signal (0)
[2025-07-18 21:56:35.849136] Kein neues Signal (0)
[2025-07-18 22:01:35.907573] Kein neues Signal (0)
[1;31m---------------------------------------------------------------------------[0m [1;31mKeyboardInterrupt[0m Traceback (most recent call last) Cell [1;32mIn[22], line 2[0m [0;32m 1[0m [38;5;66;03m# ▶️ Live-Trading starten (z. B. alle 5 Minuten)[39;00m [1;32m----> 2[0m run_live_trading([38;5;124m"[39m[38;5;124mXAUUSD[39m[38;5;124m"[39m, interval[38;5;241m=[39m[38;5;241m300[39m, volume[38;5;241m=[39m[38;5;241m0.1[39m) Cell [1;32mIn[13], line 19[0m, in [0;36mrun_live_trading[1;34m(symbol, interval, volume, db_name)[0m [0;32m 16[0m [38;5;28;01melse[39;00m: [0;32m 17[0m [38;5;28mprint[39m([38;5;124mf[39m[38;5;124m"[39m[38;5;124m[[39m[38;5;132;01m{[39;00mdatetime[38;5;241m.[39mnow()[38;5;132;01m}[39;00m[38;5;124m] Kein neues Signal ([39m[38;5;132;01m{[39;00msignal[38;5;132;01m}[39;00m[38;5;124m)[39m[38;5;124m"[39m) [1;32m---> 19[0m time[38;5;241m.[39msleep(interval) [1;31mKeyboardInterrupt[0m:
In [13]:
# 🧾 Optional: SQLite-Datenbank anzeigen
conn = db.connect("trading_log.db")
pd.read_sql("SELECT * FROM trade_log ORDER BY timestamp DESC LIMIT 10", conn)Out [13]:
| timestamp | symbol | order_type | price | sl | tp | volume | signal | comment | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2025-07-18 16:06:32.701648 | XAUUSD | BUY | 3358.95 | 3358.75 | 3359.35 | 0.1 | b'\x01\x00\x00\x00\x00\x00\x00\x00' | AutoSignalBot |
| 1 | 2025-07-18 15:51:32.545794 | XAUUSD | SELL | 3354.56 | 3354.76 | 3354.16 | 0.1 | b'\xff\xff\xff\xff\xff\xff\xff\xff' | AutoSignalBot |
In [ ]: