Files
Place-Order-Trading-Bot/TradingBot_V1.1.ipynb
T
2025-09-03 23:17:02 +02:00

86 KiB
Raw Blame History

Import Libaries

In [1]:
#!pip install ta_lib-0.6.5-cp311-cp311-win_amd64.whl
In [2]:
#%pip install talib
In [3]:
#!pip install ta
from ta.trend import ADXIndicator, EMAIndicator
from ta.momentum import RSIIndicator
from talib import CDLHAMMER, CDLSHOOTINGSTAR
In [4]:
import pandas as pd
import matplotlib.pyplot as plt
import mplfinance as mpf
import keyring as kr
import MetaTrader5 as mt
import requests
import re
from time import sleep
import sqlite3 as db
#import matplotlib.pyplot as plt
import pandas_ta as ta
import numpy as np

from sklearn.linear_model import LinearRegression
from scipy.signal import savgol_filter
from scipy.signal import find_peaks


Login

In [5]:
# login to your Trading Account - sign up in the description
mt.initialize()
    
login = 10800246
server = 'VantageInternational-Demo'
password = kr.get_password(server, str(login))


mt.login(login, password, server)
Out [5]:
True
In [6]:
project = "trading-" + server[-4::1]
project = project.lower()
project
Out [6]:
'trading-demo'

Set symbol and volume

In [7]:
pause_trading = 0
In [8]:
symbols = ['XAUUSD']
#symbols = ['BTCUSD']

#'BTCUSD', 'ETHUSD', 
            #'XRPUSD', , 'EURNZD', 'EURUSD'
In [9]:
volume_dict = {
    'BTCUSD' : 0.1,
    'BTCUSD_short' : 0.1,

    'ETHUSD' : 1.0,
    'ETHUSD_short' : 1.0,
    
    'XRPUSD': 0.1,
    'XRPUSD_short': 0.1,

    'XAUUSD': 0.1,
    'XAUUSD_short': 0.1,

    'EURUSD': 0.1,
    'EURUSD_short': 0.1,

    'EURNZD': 0.1,
    'EURNZD_short': 0.1,

}
In [10]:
periods_dict = {
    'BTCUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],
    
    'ETHUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],

    
    'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
    
    'XAUUSD':  [ 'm15'],

    
    'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],


    'EURNZD': ['m5', 'm2', 'm1'],

}
In [11]:
def get_symbol():
    global symbols, pause_trading, periods_dict
    pricemovement = {}

    for s in symbols:
        items = mt.symbol_info(s)
        pricemovement[s] = round(items.price_change,2)
        #print(s, round(items.price_change,2))

    #percentage = pricemovement[max(pricemovement, key=pricemovement.get)]
    #symbol = max(pricemovement, key=pricemovement.get)
    #volume = volume_dict[symbol]

    sorted_pricemovement = sorted(pricemovement.items(), key=lambda x:x[1], reverse=True)
    converted_dict = dict(sorted_pricemovement)

    print(converted_dict)

    percentage = converted_dict[max(converted_dict, key=converted_dict.get)]
    symbol = max(converted_dict, key=converted_dict.get)
    volume = volume_dict[symbol]


    print(symbol, percentage, volume)
    # if percentage > 0: # and percentage < 0.8:
    #    periods_dict[symbol] =  ['m15', 'm5', 'm2', 'm1']
    # elif percentage > 0.8:
    #     periods_dict[symbol] = ['h1', 'm30', 'm15', 'm5', 'm1']

    #

    #print(periods_dict)

    # if percentage > 0 and mt.positions_total() == 0:
    #     pause_trading = 0 #0 no puase
    #     return symbol, percentage, volume, periods_dict
    # elif percentage < 0.1 and mt.positions_total() == 0:
    #     print("aktuell kein neues Symbol, pause Trading")
    #     pause_trading = 1 #1 pause
    #     return None

    return symbol, percentage, volume, periods_dict
In [12]:
get_symbol()
Out [12]:
{'XAUUSD': 1.08}
XAUUSD 1.08 0.1
('XAUUSD',
 1.08,
 0.1,
 {'BTCUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'ETHUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XAUUSD': ['m15'],
  'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'EURNZD': ['m5', 'm2', 'm1']})
In [13]:
def set_symbol():
    global symbol, volume, volume_dict
    symb = get_symbol()
    if symb != None:
        symbol = symb[0]
        volume = volume_dict[symb[0]]
    

set volume manuell

In [14]:
get_symbol()
Out [14]:
{'XAUUSD': 1.08}
XAUUSD 1.08 0.1
('XAUUSD',
 1.08,
 0.1,
 {'BTCUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'ETHUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XAUUSD': ['m15'],
  'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'EURNZD': ['m5', 'm2', 'm1']})
In [15]:
set_symbol()
{'XAUUSD': 1.08}
XAUUSD 1.08 0.1
In [16]:
symbol, volume, pause_trading
Out [16]:
('XAUUSD', 0.1, 0)

Functions to place Orders on Market

In [17]:
pos = mt.positions_get()
for i in pos:
    #if i.comment == 'Retracement Bot':
    #    print(i.ticket)

    if bool(re.search('^BuyStop[0-9]{2}', i.comment)):
        print(i.ticket)

mt.positions_total()
Out [17]:
1
In [18]:
strategy_name = 'Retracement Bot'
pos = mt.positions_get()
for p in pos:
    if p.comment == strategy_name:
        print(p.comment)
print(pos)
Retracement Bot
(TradePosition(ticket=382221755, time=1756930501, time_msc=1756930501001, time_update=1756930501, time_update_msc=1756930501001, type=0, magic=30, identifier=382221755, reason=3, volume=0.1, price_open=3572.38, sl=3569.69, tp=3580.45, price_current=3572.1, swap=0.0, profit=-2.8, symbol='XAUUSD', comment='Retracement Bot', external_id=''),)

Market Order Function

In [19]:
def market_order(symbol, volume, order_type, deviation=20, magic=30, stoploss=0.0, take_profit=0.0,
                 strategy_name='Retracement Bot'):

    global project, pause_trading

    project_id_dict = {
        'trading-demo': 'a3f3ae',
        'trading-live': '747543'
    }

    order_type_dict = {
        'buy': mt.ORDER_TYPE_BUY,
        'sell': mt.ORDER_TYPE_SELL
    }

    price_dict = {
        'buy': mt.symbol_info_tick(symbol).ask,
        'sell': mt.symbol_info_tick(symbol).bid
    }

    buypos = []

    pos = mt.positions_get()
    for p in pos:
        if p.comment == strategy_name:
            buypos.append('true')
    
    activepos = buypos.count('true')

    if order_type == 'buy' and activepos == 0 and pause_trading == 0: # and mt.positions_total() == 0:
        
        request = {
            "action": mt.TRADE_ACTION_DEAL,
            "symbol": symbol,
            "volume": volume,  # FLOAT
            "type": order_type_dict[order_type],
            "price": price_dict[order_type],
            "sl":  stoploss,  # FLOAT
            "tp":  take_profit,  # FLOAT
            "deviation": deviation,  # INTERGER
            "magic": magic,  # INTERGER
            "comment": strategy_name,
            "type_time": mt.ORDER_TIME_GTC,
            "type_filling": mt.ORDER_FILLING_IOC,  # mt.ORDER_FILLING_FOK if IOC does not work
        }

        requests.post('https://api.mynotifier.app', {
            "apiKey": 'beafb52e-3cb6-477a-92ef-2f10bff50e20',
            "message": "Es wrude ein Handel eröffnet!",
            "description": "Bitte kontrolliere die Position",
            "type": "info",#"info", # info, error, warning or success
            "project": project_id_dict[project]
        })

        order_result = mt.order_send(request)
        #return (order_result)
    
    elif order_type == 'sell' and mt.positions_total() > 0:
        pos = mt.positions_get()
        for p in pos:
            if p.comment == strategy_name:
                # while schleife ?
                positions = mt.positions_get()
                ticket = p.ticket
                request = {
                    "action": mt.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,  # FLOAT
                    "type": order_type_dict[order_type],
                    "price": price_dict[order_type],
                    "position": ticket,
                    "sl": stoploss,  # FLOAT
                    "tp": take_profit,  # FLOAT
                    "deviation": deviation,  # INTERGER
                    "magic": magic,  # INTERGER
                    "comment": strategy_name,
                    "type_time": mt.ORDER_TIME_GTC,
                    "type_filling": mt.ORDER_FILLING_IOC,  # mt.ORDER_FILLING_FOK if IOC does not work
                }

                requests.post('https://api.mynotifier.app', {
                    "apiKey": 'beafb52e-3cb6-477a-92ef-2f10bff50e20',
                    "message": "Es wrude ein Handel geschlossen!",
                    "description": "Bitte prüfe die Position",
                    "type": "info",#"info", # info, error, warning or success
                    "project": project_id_dict[project]
                })

                order_result = mt.order_send(request)
                #return (order_result)
    

Trend Detection

timefame & trend dictionary

In [20]:
debug = False
In [21]:
trend_dict = {
    #'m5': '',
    #'m10': '',
    'm15': '',
    #'m30': '',
    #'h4': '',
}
In [22]:
timeframes_dict = {
    'm1': mt.TIMEFRAME_M1,
    'm2': mt.TIMEFRAME_M2,
    'm3': mt.TIMEFRAME_M3,
    'm5': mt.TIMEFRAME_M5,
    'm15': mt.TIMEFRAME_M15,
    'm20': mt.TIMEFRAME_M20,
    'm30': mt.TIMEFRAME_M30,
    'h1': mt.TIMEFRAME_H1,
    'h4': mt.TIMEFRAME_H4,
    'd1': mt.TIMEFRAME_D1,
}


# timeframes = {
#         'm1': mt.TIMEFRAME_M1,
#         'm2': mt.TIMEFRAME_M2,
#         'm3': mt.TIMEFRAME_M3,
#         'm5': mt.TIMEFRAME_M5,
#         'm15': mt.TIMEFRAME_M15,
#         'm20': mt.TIMEFRAME_M20,
#         'm30': mt.TIMEFRAME_M30,
#         'h1': mt.TIMEFRAME_H1,
#     }
In [23]:
print(trend_dict)
{'m15': ''}
In [24]:
def get_rates(periode, bars=300):
    #global symbol

    # OHLC abrufen
    ohlc = mt.copy_rates_from_pos(symbol, timeframes_dict[periode], 0, bars)
    df = pd.DataFrame(ohlc)
    df['time'] = pd.to_datetime(df['time'], unit='s')

    # Umwandeln in float
    df["open"] = df["open"].astype(float)
    df["high"] = df["high"].astype(float)
    df["low"] = df["low"].astype(float)
    df["close"] = df["close"].astype(float)

    # ATR berechnen (klassisch 14)
    df["atr"] = ta.atr(high=df["high"], low=df["low"], close=df["close"], length=14)

    # leichte Glättung (optional, um Rauschen zu reduzieren)
    df["atr"] = df["atr"].rolling(window=5).mean()

    # Index setzen
    df.set_index("time", inplace=True)

    # NaNs entfernen (anfangs durch ATR-Berechnung)
    df = df.dropna()

    return df
In [25]:
get_rates('h4', 200)
Out [25]:
open high low close tick_volume spread real_volume atr
time
2025-07-23 16:00:00 3419.98 3420.52 3381.47 3387.38 89692 19 0 13.861980
2025-07-23 20:00:00 3387.33 3395.94 3385.74 3386.78 49534 19 0 14.128410
2025-07-24 00:00:00 3388.01 3393.16 3386.48 3391.44 18496 19 0 14.305667
2025-07-24 04:00:00 3391.44 3393.36 3374.71 3382.57 56315 19 0 14.547405
2025-07-24 08:00:00 3382.56 3382.92 3365.82 3369.68 54663 19 0 14.818019
... ... ... ... ... ... ... ... ...
2025-09-03 04:00:00 3536.07 3545.89 3529.36 3536.81 59697 20 0 18.731740
2025-09-03 08:00:00 3536.82 3541.19 3526.93 3539.99 58476 20 0 19.107330
2025-09-03 12:00:00 3540.04 3551.43 3532.29 3550.56 63000 20 0 19.007235
2025-09-03 16:00:00 3550.60 3572.57 3549.38 3572.43 87375 20 0 18.985718
2025-09-03 20:00:00 3572.45 3572.98 3570.24 3572.12 4428 20 0 18.713310

182 rows × 8 columns

Parameter Wirkung
distance Wie nah beieinander Peaks liegen dürfen
width Wie breit/flach ein Peak sein muss
prominence Wie stark auffällig ein Peak sein muss
In [26]:
def get_trend(timeframe="h4", lookback=150):
    """
    Bestimme Trendrichtung per Linear Regression.
    Liefert:
      - trend: "uptrend" / "downtrend" / "sideways"
      - slope: numerischer Wert der Regression
      - atr: ATR des Zeitraums
      - slope_threshold: dynamische Schwelle für Seitwärtsbewegungen
    """
    df = get_rates(timeframe, lookback)
    if df.empty:
        return {"trend": "sideways", "slope": 0, "atr": 0, "slope_threshold": 0}

    # Linear Regression
    X = np.arange(len(df)).reshape(-1, 1)
    y = df["close"].values.reshape(-1, 1)
    slope = LinearRegression().fit(X, y).coef_[0][0]

    # ATR
    df["hl"] = df["high"] - df["low"]
    df["hc"] = (df["high"] - df["close"].shift()).abs()
    df["lc"] = (df["low"] - df["close"].shift()).abs()
    df["tr"] = df[["hl","hc","lc"]].max(axis=1)
    atr = df["tr"].rolling(14).mean().iloc[-1]

    slope_threshold = (atr / df["close"].iloc[-1]) * 1.2

    if abs(slope) < slope_threshold:
        trend = "sideways"
    else:
        trend = "uptrend" if slope > 0 else "downtrend"

    return {
        "trend": trend,
        "slope": slope,
        "atr": atr,
        "slope_threshold": slope_threshold
    }
In [27]:
def get_top_down_signal(symbol=symbol):
    """
    Top-Down Ansatz:
      - D1 / H4: Trend bestimmen
      - H1 / M30: Setup identifizieren
      - M15 / M5: Einstiege optimieren (Signale ohne Tradeausführung)
    """
    global trend_dict

    # --- Höhere Timeframes ---
    d1_trend_info = get_trend("d1", lookback=200)
    h4_trend_info = get_trend("h4", lookback=150)

    # --- Mittlere Timeframes für Setups ---
    h1_trend_info = get_trend("h1", lookback=100)
    m30_trend_info = get_trend("m30", lookback=60)

    # --- Niedrigere Timeframes für Einstiege (nur Signal, kein Trade) ---
    m15_trend_info = get_trend("m15", lookback=50)
    m5_trend_info = get_trend("m5", lookback=20)

    # --- Konsolidierte Trendanalyse ---
    top_down_trend = "sideways"
    if d1_trend_info["trend"] == h4_trend_info["trend"]:
        top_down_trend = d1_trend_info["trend"]

    # --- Setup-Bedingungen ---
    setup_ready = False
    if top_down_trend != "sideways":
        if h1_trend_info["trend"] == top_down_trend and m30_trend_info["trend"] == top_down_trend:
            setup_ready = True

    # --- Einstiegsberechnung ---
    entry_signal = 0
    if setup_ready:
        if m15_trend_info["trend"] == top_down_trend and m5_trend_info["trend"] == top_down_trend:
            entry_signal = 1 if top_down_trend == "uptrend" else -1

    # --- Speichern ---
    trend_dict["top_down"] = {
        "D1": d1_trend_info,
        "H4": h4_trend_info,
        "H1": h1_trend_info,
        "M30": m30_trend_info,
        "M15": m15_trend_info,
        "M5": m5_trend_info,
        "top_down_trend": top_down_trend,
        "setup_ready": setup_ready,
        "entry_signal": entry_signal
    }

    return trend_dict["top_down"]
In [28]:
get_trend("h1")
Out [28]:
{'trend': 'uptrend',
 'slope': 1.4477744934856227,
 'atr': 9.130714285714314,
 'slope_threshold': 0.0030673261656543383}
In [56]:
get_top_down_signal(symbol)
Out [56]:
{'D1': {'trend': 'uptrend',
  'slope': 4.621913228515892,
  'atr': 39.36499999999988,
  'slope_threshold': 0.013270331238569827},
 'H4': {'trend': 'uptrend',
  'slope': 0.8813408347377812,
  'atr': 20.499285714285698,
  'slope_threshold': 0.006910512170269389},
 'H1': {'trend': 'uptrend',
  'slope': 1.8054590176423853,
  'atr': 9.649999999999993,
  'slope_threshold': 0.0032531105411456656},
 'M30': {'trend': 'uptrend',
  'slope': 1.0648326715825298,
  'atr': 6.73500000000003,
  'slope_threshold': 0.0022704351807892403},
 'M15': {'trend': 'uptrend',
  'slope': 0.3136986803519024,
  'atr': 4.114285714285676,
  'slope_threshold': 0.0013869664483344836},
 'M5': {'trend': 'downtrend',
  'slope': -0.909999999999854,
  'atr': nan,
  'slope_threshold': nan},
 'top_down_trend': 'uptrend',
 'setup_ready': True,
 'entry_signal': 0}
In [30]:
get_trend()
Out [30]:
{'trend': 'uptrend',
 'slope': 0.8855957903085263,
 'atr': 19.30285714285713,
 'slope_threshold': 0.006484504599909453}
In [31]:
def get_trend_fast(period):
    global trend_dict, periods_dict, symbol

    df2 = get_rates(period).iloc[-200:]
    df2["close_smooth"] = savgol_filter(df2.close, 15, 5)  # kleinere Glättung

    atr = df2.atr.iloc[-1]

    # Weniger strenge Peak-Erkennung
    peaks_idx, _ = find_peaks(df2.close_smooth, distance=1, width=2, prominence=atr*0.5) #evtl kleiner 0.5
    troughs_idx, _ = find_peaks(-1*df2.close_smooth, distance=1, width=2, prominence=atr*0.5)

    # Trend über Peaks/Troughs
    if len(peaks_idx) > 0 and len(troughs_idx) > 0:
        if peaks_idx[-1] > troughs_idx[-1]:
            trend = "downtrend"
        else:
            trend = "uptrend"
    else:
        # Falls keine klaren Peaks gefunden wurden → Slope nutzen
        slope = df2.close_smooth.diff().iloc[-5:].mean()
        trend = "downtrend" if slope < 0 else "uptrend"

    trend_dict[period] = trend
    return trend
In [32]:
get_trend_fast('m15')
Out [32]:
'uptrend'
In [33]:
def set_trend():

    global pause_trading, periods_dict, trend_dict

    for k,v in trend_dict.items():
        get_trend_fast(k) 
        print(k)
    
    for k,v in reversed(trend_dict.items()):

        if v == 'uptrend':
            print(k,v)
            periods_dict[symbol] = [k]
            pause_trading = 0
            print(f"Pause Trading: {pause_trading}")
            break
        elif v == 'downtrend':
            periods_dict[symbol] = [k] #['m15']
            pause_trading = 1
            print(f"Pause Trading: {pause_trading}")
In [34]:
set_trend()
m15
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[34], line 1
----> 1 set_trend()

Cell In[33], line 6, in set_trend()
      3 global pause_trading, periods_dict, trend_dict
      5 for k,v in trend_dict.items():
----> 6     get_trend_fast(k) 
      7     print(k)
      9 for k,v in reversed(trend_dict.items()):

Cell In[31], line 4, in get_trend_fast(period)
      1 def get_trend_fast(period):
      2     global trend_dict, periods_dict, symbol
----> 4     df2 = get_rates(period).iloc[-200:]
      5     df2["close_smooth"] = savgol_filter(df2.close, 15, 5)  # kleinere Glättung
      7     atr = df2.atr.iloc[-1]

Cell In[24], line 5, in get_rates(periode, bars)
      1 def get_rates(periode, bars=300):
      2     #global symbol
      3 
      4     # OHLC abrufen
----> 5     ohlc = mt.copy_rates_from_pos(symbol, timeframes_dict[periode], 0, bars)
      6     df = pd.DataFrame(ohlc)
      7     df['time'] = pd.to_datetime(df['time'], unit='s')

KeyError: 'top_down'

Set Trend manually

In [ ]:
pause_trading, trend_dict, periods_dict, symbols[0]
(0,
 {'m15': 'uptrend',
  'top_down': {'D1': {'trend': 'uptrend',
    'slope': 4.621913228515892,
    'atr': 39.36499999999988,
    'slope_threshold': 0.013270331238569827},
   'H4': {'trend': 'uptrend',
    'slope': 0.8813408347377812,
    'atr': 20.499285714285698,
    'slope_threshold': 0.006910512170269389},
   'H1': {'trend': 'uptrend',
    'slope': 1.8054590176423853,
    'atr': 9.649999999999993,
    'slope_threshold': 0.0032531105411456656},
   'M30': {'trend': 'uptrend',
    'slope': 1.0648326715825298,
    'atr': 6.73500000000003,
    'slope_threshold': 0.0022704351807892403},
   'M15': {'trend': 'uptrend',
    'slope': 0.3136986803519024,
    'atr': 4.114285714285676,
    'slope_threshold': 0.0013869664483344836},
   'M5': {'trend': 'downtrend',
    'slope': -0.909999999999854,
    'atr': nan,
    'slope_threshold': nan},
   'top_down_trend': 'uptrend',
   'setup_ready': True,
   'entry_signal': 0},
  'm5': {'standard': 'downtrend', 'fast': 'downtrend', 'signal': -1}},
 {'BTCUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'ETHUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'XAUUSD': ['m15'],
  'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],
  'EURNZD': ['m5', 'm2', 'm1']},
 'XAUUSD')
Kein Top-Down-Setup vorhanden. Kein Trade.
In [36]:
set_trend()
m15
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[36], line 1
----> 1 set_trend()

Cell In[33], line 6, in set_trend()
      3 global pause_trading, periods_dict, trend_dict
      5 for k,v in trend_dict.items():
----> 6     get_trend_fast(k) 
      7     print(k)
      9 for k,v in reversed(trend_dict.items()):

Cell In[31], line 4, in get_trend_fast(period)
      1 def get_trend_fast(period):
      2     global trend_dict, periods_dict, symbol
----> 4     df2 = get_rates(period).iloc[-200:]
      5     df2["close_smooth"] = savgol_filter(df2.close, 15, 5)  # kleinere Glättung
      7     atr = df2.atr.iloc[-1]

Cell In[24], line 5, in get_rates(periode, bars)
      1 def get_rates(periode, bars=300):
      2     #global symbol
      3 
      4     # OHLC abrufen
----> 5     ohlc = mt.copy_rates_from_pos(symbol, timeframes_dict[periode], 0, bars)
      6     df = pd.DataFrame(ohlc)
      7     df['time'] = pd.to_datetime(df['time'], unit='s')

KeyError: 'top_down'
In [37]:
trend_dict[periods_dict[symbol][0]]
Out [37]:
'uptrend'
In [38]:
periods_dict[symbol], pause_trading
Out [38]:
(['m15'], 0)

Generate signals

In [39]:
def get_mt5_data(symbol=symbol, timeframe=mt.TIMEFRAME_M15, 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 df
In [40]:
def get_m5_trade_signal(symbol, atr_mult=1.5):
    global trend_dict, periods_dict

    # Hole die letzten M5-Daten
    df = get_rates('m5').iloc[-200:]

    # Smoothen
    df["close_smooth_std"] = savgol_filter(df.close, 25, 5)
    df["close_smooth_fast"] = savgol_filter(df.close, 15, 5)

    atr = df.atr.iloc[-1]

    # --- Standard-Trend ---
    peaks_std, _ = find_peaks(df.close_smooth_std, distance=1, width=2, prominence=atr)
    troughs_std, _ = find_peaks(-df.close_smooth_std, distance=1, width=2, prominence=atr)

    if len(peaks_std) > 0 and len(troughs_std) > 0:
        if peaks_std[-1] > troughs_std[-1]:
            trend_standard = "downtrend"
        else:
            trend_standard = "uptrend"
    else:
        trend_standard = "neutral"

    # --- Fast-Trend ---
    peaks_fast, _ = find_peaks(df.close_smooth_fast, distance=1, width=2, prominence=atr*0.5)
    troughs_fast, _ = find_peaks(-df.close_smooth_fast, distance=1, width=2, prominence=atr*0.5)

    if len(peaks_fast) > 0 and len(troughs_fast) > 0:
        if peaks_fast[-1] > troughs_fast[-1]:
            trend_fast = "downtrend"
        else:
            trend_fast = "uptrend"
    else:
        slope = df.close_smooth_fast.diff().iloc[-5:].mean()
        trend_fast = "downtrend" if slope < 0 else "uptrend"

    # --- Kombiniertes Signal ---
    signal = 0  # 0 = neutral, 1 = long, -1 = short
    stop_loss = None

    if trend_standard == "uptrend" and trend_fast == "uptrend":
        signal = 1
        stop_loss = df.close.iloc[-1] - atr_mult * atr
    elif trend_standard == "downtrend" and trend_fast == "downtrend":
        signal = -1
        stop_loss = df.close.iloc[-1] + atr_mult * atr

    # Speichern
    trend_dict['m5'] = {"standard": trend_standard, "fast": trend_fast, "signal": signal}

    return {
        "signal": signal,
        "price": df.close.iloc[-1],
        "stop_loss": stop_loss,
        "trends": trend_dict['m15']
    }
In [41]:
def generate_signal(df = get_mt5_data(symbol=symbol, timeframe=timeframes_dict['m15']), confirm_window=3):
    """
    Berechnet drei Signalarten:
    - fast_signal: schnelle, aggressive Variante
    - standard_signal: konservative Basisstrategie
    - optimized_signal: zusätzliche Filter (ATR, ADX, strengerer RSI)
    """

    # Indikatoren
    df["ema21"] = df["close"].ewm(span=3).mean()
    df["ema50"] = df["close"].ewm(span=9).mean()
    df["rsi9"] = ta.rsi(df["close"], length=9)
    df["rsi14"] = ta.rsi(df["close"], length=14)
    df["trend"] = savgol_filter(df["close"], 25, 3)

    # Zusätzliche Filterindikatoren
    df["atr"] = ta.atr(df["high"], df["low"], df["close"], length=14)
    df["adx"] = ta.adx(df["high"], df["low"], df["close"], length=14)["ADX_14"]

    # Spalten für Signale
    df["fast_signal"] = 0
    df["standard_signal"] = 0
    df["optimized_signal"] = 0

    for i in range(1, len(df)):
        # -----------------------
        # FAST SIGNAL (früh/aggressiv)
        # -----------------------
        if (
            df["ema21"].iloc[i] > df["ema50"].iloc[i]
            and df["rsi9"].iloc[i] > 30
        ):
            df.at[i, "fast_signal"] = 1
        elif (
            df["ema21"].iloc[i] < df["ema50"].iloc[i]
            and df["rsi9"].iloc[i] < 60
        ):
            df.at[i, "fast_signal"] = -1

        # -----------------------
        # STANDARD SIGNAL (konservativ, ursprüngliche Logik)
        # -----------------------
        if (
            df["ema21"].iloc[i] > df["ema50"].iloc[i]
            and df["ema21"].iloc[i - 1] <= df["ema50"].iloc[i - 1]
            and df["rsi14"].iloc[i] < 70
            and df["rsi9"].iloc[i] > 40
            and df["trend"].iloc[i] > df["trend"].iloc[i - 1]
        ):
            df.at[i, "standard_signal"] = 1
        elif (
            df["ema21"].iloc[i] < df["ema50"].iloc[i]
            and df["ema21"].iloc[i - 1] >= df["ema50"].iloc[i - 1]
            and df["rsi14"].iloc[i] > 40
            and df["rsi9"].iloc[i] < 70
            and df["trend"].iloc[i] < df["trend"].iloc[i - 1]
        ):
            df.at[i, "standard_signal"] = -1

        # -----------------------
        # OPTIMIZED SIGNAL (mit ADX + ATR + strengerem RSI)
        # -----------------------
        if (
            df["ema21"].iloc[i] > df["ema50"].iloc[i]
            and df["ema21"].iloc[i - 1] <= df["ema50"].iloc[i - 1]
            and df["rsi14"].iloc[i] < 65                          # strengerer Filter
            and df["rsi9"].iloc[i] > 45                           # Momentum klarer
            and df["adx"].iloc[i] > 20                            # Trendstärke vorhanden
            and df["atr"].iloc[i] > df["atr"].rolling(50).mean().iloc[i]  # Volatilität über Durchschnitt
        ):
            df.at[i, "optimized_signal"] = 1
        elif (
            df["ema21"].iloc[i] < df["ema50"].iloc[i]
            and df["ema21"].iloc[i - 1] >= df["ema50"].iloc[i - 1]
            and df["rsi14"].iloc[i] > 35                          # strengerer Filter unten
            and df["rsi9"].iloc[i] < 55
            and df["adx"].iloc[i] > 20
            and df["atr"].iloc[i] > df["atr"].rolling(50).mean().iloc[i]
        ):
            df.at[i, "optimized_signal"] = -1

    return df
In [42]:
generate_signal()
Out [42]:
time open high low close tick_volume spread real_volume ema21 ema50 rsi9 rsi14 trend atr adx fast_signal standard_signal optimized_signal
0 2025-08-27 07:45:00 3374.93 3375.85 3373.94 3374.93 2467 20 0 3374.930000 3374.930000 NaN NaN 3376.087631 NaN NaN 0 0 0
1 2025-08-27 08:00:00 3374.91 3376.21 3374.11 3374.74 2904 20 0 3374.803333 3374.824444 NaN NaN 3375.914101 NaN NaN 0 0 0
2 2025-08-27 08:15:00 3374.73 3377.46 3374.21 3375.77 2313 20 0 3375.355714 3375.211967 NaN NaN 3375.933879 NaN NaN 0 0 0
3 2025-08-27 08:30:00 3375.78 3378.81 3375.69 3377.69 2745 20 0 3376.600667 3376.051409 NaN NaN 3376.121647 NaN NaN 0 0 0
4 2025-08-27 08:45:00 3377.68 3378.88 3375.85 3377.23 2374 20 0 3376.925484 3376.402013 NaN NaN 3376.452085 NaN NaN 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
495 2025-09-03 19:15:00 3565.40 3568.01 3564.18 3567.83 3848 20 0 3566.195399 3562.948376 71.921940 69.332849 3568.219300 5.677877 31.169524 1 0 0
496 2025-09-03 19:30:00 3567.83 3569.42 3566.97 3569.01 3442 20 0 3567.602699 3564.160701 73.431485 70.341690 3569.360376 5.447314 32.165951 1 0 0
497 2025-09-03 19:45:00 3569.01 3572.57 3568.59 3572.43 3585 20 0 3570.016350 3565.814561 77.394221 73.103386 3570.468641 5.342506 33.517576 1 0 0
498 2025-09-03 20:00:00 3572.45 3572.98 3570.24 3572.22 3806 20 0 3571.118175 3567.095649 76.604942 72.656004 3571.539564 5.156613 34.825121 1 0 0
499 2025-09-03 20:15:00 3572.26 3572.68 3571.43 3572.06 1092 20 0 3571.589087 3568.088519 75.941120 72.292990 3572.568615 4.877569 36.039270 1 0 0

500 rows × 18 columns

In [43]:
pos = mt.positions_total()

if pos > 0:
    open_positions = mt.positions_get() 
    trail_factor = 0.5
    entry_price = open_positions[0].price_open
    tp_current = open_positions[0].tp
    current_price = open_positions[0].price_current
    profit = open_positions[0].profit

    profit = current_price - entry_price
    if profit > 0:
        new_tp = current_price - entry_price * trail_factor
    
    if profit < 0:
        new_tp = current_price - profit * trail_factor        

    if new_tp > current_price:
        #update tp from open pos
        new_tp
        print(f"Trailing +TP for BUY {symbol}: {new_tp} CP: {current_price}")
    if new_tp < current_price:
        #update tp from open pos
        new_tp
        print(f"Trailing -TP for BUY {symbol}: {new_tp} CP: {current_price}")

#open_positions
Trailing +TP for BUY XAUUSD: 3572.2200000000003 CP: 3572.06

Update TP-SL on open positions

In [44]:
def update_trailing_sl_tp(pos, atr, rrr=2.0, atr_mult=1.5, max_retries=2):
    """
    Aktualisiert SL und TP für offene Positionen:
    - ATR-basiertes Trailing
    - Gewinn-stufenweises Nachziehen
    - Dynamische Anpassung mit Validierung
    - Fallback-Mechanismus bei RETCODE 1016
    """

    symbol = pos.symbol
    info = mt.symbol_info(symbol)
    digits = info.digits
    point = info.point
    stops_level = info.trade_stops_level * point  # Mindestabstand vom Broker

    entry_price = pos.price_open
    current_tick = mt.symbol_info_tick(symbol)
    bid, ask = current_tick.bid, current_tick.ask
    current_price = bid if pos.type == 0 else ask
    pos_type = pos.type  # 0 = BUY, 1 = SELL

    # Gewinn in ATR berechnen
    if pos_type == 0:  # LONG
        profit_atr = (current_price - entry_price) / atr
        base_sl = current_price - atr_mult * atr
        new_sl = max(pos.sl or 0, base_sl)

        if profit_atr > 2:
            new_sl = max(new_sl, entry_price + 1.5 * atr)
        elif profit_atr > 1:
            new_sl = max(new_sl, entry_price + 1.0 * atr)
        elif profit_atr > 0.5:
            new_sl = max(new_sl, entry_price + 0.5 * atr)

        new_tp = entry_price + (entry_price - new_sl) * rrr

        # Validierung BUY
        if new_sl >= bid - stops_level:
            new_sl = bid - stops_level
        if new_tp <= ask + stops_level:
            new_tp = ask + stops_level

    else:  # SHORT
        profit_atr = (entry_price - current_price) / atr
        base_sl = current_price + atr_mult * atr
        new_sl = min(pos.sl or 999999, base_sl)

        if profit_atr > 2:
            new_sl = min(new_sl, entry_price - 1.5 * atr)
        elif profit_atr > 1:
            new_sl = min(new_sl, entry_price - 1.0 * atr)
        elif profit_atr > 0.5:
            new_sl = min(new_sl, entry_price - 0.5 * atr)

        new_tp = entry_price - (new_sl - entry_price) * rrr

        # Validierung SELL
        if new_sl <= ask + stops_level:
            new_sl = ask + stops_level
        if new_tp >= bid - stops_level:
            new_tp = bid - stops_level

    # Runden auf gültige Stellen
    new_sl = round(new_sl, digits)
    new_tp = round(new_tp, digits)

    # --- Nur updaten, wenn sich Werte geändert haben ---
    if (pos.sl is None or abs(new_sl - pos.sl) > point) or \
       (pos.tp is None or abs(new_tp - pos.tp) > point):

        for attempt in range(max_retries):
            request = {
                "action": mt.TRADE_ACTION_SLTP,
                "symbol": symbol,
                "sl": new_sl,
                "tp": new_tp,
                "position": pos.ticket
            }
            result = mt.order_send(request)

            if result.retcode == mt.TRADE_RETCODE_DONE:
                print(f"🔄 Updated {symbol} | SL: {new_sl:.5f} | TP: {new_tp:.5f}")
                break
            elif result.retcode == mt.TRADE_RETCODE_INVALID_STOPS:
                # Fallback: Stops korrigieren
                print(f"⚠️ RETCODE 1016 (Invalid stops)  Versuch {attempt+1}/{max_retries}")
                adjust = 2 * stops_level  # mehr Abstand
                if pos_type == 0:  # BUY
                    new_sl = bid - adjust
                    new_tp = ask + adjust
                else:  # SELL
                    new_sl = ask + adjust
                    new_tp = bid - adjust

                new_sl = round(new_sl, digits)
                new_tp = round(new_tp, digits)
                continue  # retry
            else:
                print(f"❌ SL/TP Update Fehler: {result.retcode} ({result.comment})")
                break

    return {"new_sl": new_sl, "new_tp": new_tp, "profit_atr": profit_atr}
In [45]:
def manual_update_trailing_sl_tp(atr_mult=1.5, slope_factor=1.5):
    # --- Hole die letzten M5-Daten ---
    df = get_rates('m5').iloc[-200:]

    # --- ATR Berechnung ---
    df["hl"] = df["high"] - df["low"]
    df["hc"] = (df["high"] - df["close"].shift()).abs()
    df["lc"] = (df["low"] - df["close"].shift()).abs()
    df["tr"] = df[["hl","hc","lc"]].max(axis=1)
    df["atr"] = df["tr"].rolling(14).mean()
    atr = df["atr"].iloc[-1]

    current_price = df["close"].iloc[-1]

    # --- Trendrichtung per Linear Regression ---
    def linreg_slope(series):
        X = np.arange(len(series)).reshape(-1, 1)
        y = series.values.reshape(-1, 1)
        model = LinearRegression().fit(X, y)
        return model.coef_[0][0]

    slope_long = linreg_slope(df["close"].iloc[-50:])  # 50 Balken (~4h)
    slope_short = linreg_slope(df["close"].iloc[-15:]) # 15 Balken (~1h)

    # --- Dynamischer Seitwärtsfilter ---
    slope_threshold = slope_factor * atr / df["close"].iloc[-1]

    # --- Dynamische RRR-Berechnung ---
    atr_norm = atr / current_price          # relative Volatilität
    slope_strength = abs(slope_short)       # Trendstärke aus Regression

    rrr_base = 1.2
    rrr_from_vol = atr_norm * 1500          # skaliert ATR-Einfluss
    rrr_from_slope = slope_strength / slope_threshold  # Slope-Einfluss

    rrr = rrr_base + rrr_from_vol + rrr_from_slope
    rrr = max(1.2, min(rrr, 3.0))           # Begrenzung


    open_positions = mt.positions_get(symbol=symbol)
    for pos in open_positions:
        atr_value = df["atr"].iloc[-1]
        update_trailing_sl_tp(pos, atr=atr_value, rrr=rrr, atr_mult=atr_mult)
       
In [46]:
manual_update_trailing_sl_tp()
🔄 Updated XAUUSD | SL: 3569.71000 | TP: 3580.40000

Get M5 Trade Signals

In [54]:
def get_m5_trade_signals(symbol=symbol, atr_mult=1.5, base_rrr=2.0, atr_min=0.0005, slope_factor=1.5, execute=False):
    """
    Analyse von M5-Signalen mit ATR/Trend/Seitwärtsfilter
    - execute=False -> nur Analyse
    - execute=True  -> führt Orders aus
    """

    global trend_dict, volume_dict

    df = get_rates('m5').iloc[-200:]

    # --- ATR ---
    df["hl"] = df["high"] - df["low"]
    df["hc"] = (df["high"] - df["close"].shift()).abs()
    df["lc"] = (df["low"] - df["close"].shift()).abs()
    df["tr"] = df[["hl","hc","lc"]].max(axis=1)
    df["atr"] = df["tr"].rolling(14).mean()
    atr = df["atr"].iloc[-1]

    if atr < atr_min:
        return {"signal": 0, "reason": "ATR too low → sideways"}

    # --- Trend ---
    def linreg_slope(series):
        X = np.arange(len(series)).reshape(-1, 1)
        y = series.values.reshape(-1, 1)
        model = LinearRegression().fit(X, y)
        return model.coef_[0][0]

    slope_long = linreg_slope(df["close"].iloc[-50:])
    slope_short = linreg_slope(df["close"].iloc[-15:])
    slope_threshold = slope_factor * atr / df["close"].iloc[-1]

    if abs(slope_long) < slope_threshold and abs(slope_short) < slope_threshold:
        return {"signal": 0, "reason": "Trend flat → sideways"}

    trend_standard = "uptrend" if slope_long > 0 else "downtrend"
    trend_fast = "uptrend" if slope_short > 0 else "downtrend"

    current_price = df["close"].iloc[-1]

    # --- RRR ---
    atr_norm = atr / current_price
    slope_strength = abs(slope_short)
    rrr_base = 1.2
    rrr_from_vol = atr_norm * 1500
    rrr_from_slope = slope_strength / slope_threshold
    rrr = max(1.2, min(rrr_base + rrr_from_vol + rrr_from_slope, 3.0))

    # --- Signal ---
    signal, stop_loss, takeprofit = 0, None, None
    if trend_standard == "uptrend" and trend_fast == "uptrend":
        signal = 1
        stop_loss = current_price - atr_mult * atr
        takeprofit = current_price + atr_mult * atr * rrr

        if execute:
            print(f"BUY {symbol} @ {current_price} | TP: {takeprofit} | SL: {stop_loss}")
            market_order(symbol, volume_dict[symbol], "buy", stoploss=stop_loss, take_profit=takeprofit)

    elif trend_standard == "downtrend" and trend_fast == "downtrend":
        signal = -1
        stop_loss = current_price + atr_mult * atr
        takeprofit = current_price - atr_mult * atr * rrr

        if execute:
            print(f"SELL {symbol} @ {current_price} | TP: {takeprofit} | SL: {stop_loss}")
            market_order(symbol, volume_dict[symbol], "sell", stoploss=stop_loss, take_profit=takeprofit)

    # --- speichern ---
    trend_dict['m5'] = {"standard": trend_standard, "fast": trend_fast, "signal": signal}

    return {
        "signal": signal,
        "price": current_price,
        "stop_loss": stop_loss,
        "take_profit": takeprofit,
        "Risk Reward": rrr,
        "trends": trend_dict['m5'],
        "atr": atr,
        "slope_long": slope_long,
        "slope_short": slope_short
    }
In [47]:
def execute_m5_trade(symbol=symbol, atr_mult=1.5, base_rrr=2.0):
    """
    Führt einen Trade auf M5 nur aus, wenn das Top-Down-Setup ein positives Signal liefert.
    Nutzt adaptive ATR, dynamisches RRR und SL/TP.
    """

    global trend_dict, volume_dict, pause_trading

    # --- Top-Down-Signal prüfen ---
    top_down = get_top_down_signal(symbol)

    if pause_trading == 1:
        print("⚠️ Trading pausiert. Keine Trades ausgeführt.")
        return None

    if not top_down["setup_ready"] or top_down["entry_signal"] == 0:
        print("Kein Top-Down-Setup vorhanden. Kein Trade.")
        return None

    # --- M5-Signal berechnen (nur Signal, keine automatische Order) ---
    m5_signal_info = get_m5_trade_signals(symbol=symbol, atr_mult=atr_mult, base_rrr=base_rrr)

    if m5_signal_info["signal"] == 0:
        print("M5 Signal neutral. Kein Trade.")
        return None

    # --- Trade ausführen ---
    current_price = m5_signal_info["price"]
    stop_loss = m5_signal_info["stop_loss"]
    take_profit = m5_signal_info["take_profit"]

    if m5_signal_info["signal"] == 1:
        # Long
        print(f"✅ BUY {symbol} @ {current_price} | TP: {take_profit} | SL: {stop_loss}")
        market_order(symbol, volume_dict[symbol], "buy", stoploss=stop_loss, take_profit=take_profit)
    elif m5_signal_info["signal"] == -1:
        # Short
        print(f"✅ SELL {symbol} @ {current_price} | TP: {take_profit} | SL: {stop_loss}")
        market_order(symbol, volume_dict[symbol], "sell", stoploss=stop_loss, take_profit=take_profit)

    # --- Offene Trades aktualisieren (Trailing SL/TP) ---
    open_positions = mt.positions_get(symbol=symbol)
    for pos in open_positions:
        update_trailing_sl_tp(pos, atr=m5_signal_info["atr"], rrr=m5_signal_info["Risk Reward"], atr_mult=atr_mult)

    return {
        "top_down": top_down,
        "m5_signal": m5_signal_info
    }
In [55]:
execute_m5_trade()
Kein Top-Down-Setup vorhanden. Kein Trade.
✅ BUY XAUUSD @ 3571.06 | TP: 3578.2085714285713 | SL: 3568.677142857143
✅ BUY XAUUSD @ 3571.81 | TP: 3579.604642857143 | SL: 3569.2117857142857
🔄 Updated XAUUSD | SL: 3570.03000 | TP: 3579.44000
🔄 Updated XAUUSD | SL: 3570.58000 | TP: 3577.77000
🔄 Updated XAUUSD | SL: 3573.16000 | TP: 3573.77000
✅ BUY XAUUSD @ 3573.65 | TP: 3581.7596428571433 | SL: 3570.946785714286
🔄 Updated XAUUSD | SL: 3570.95000 | TP: 3582.31000
🔄 Updated XAUUSD | SL: 3571.07000 | TP: 3581.95000
✅ BUY XAUUSD @ 3573.67 | TP: 3581.6832142857143 | SL: 3570.9989285714287
🔄 Updated XAUUSD | SL: 3571.77000 | TP: 3579.86000
🔄 Updated XAUUSD | SL: 3571.77000 | TP: 3579.85000
✅ BUY XAUUSD @ 3574.21 | TP: 3582.0914285714284 | SL: 3571.5828571428574
🔄 Updated XAUUSD | SL: 3574.66000 | TP: 3575.40000
🔄 Updated XAUUSD | SL: 3574.67000 | TP: 3575.60000
🔄 Updated XAUUSD | SL: 3574.67000 | TP: 3575.39000
🔄 Updated XAUUSD | SL: 3574.67000 | TP: 3575.63000
🔄 Updated XAUUSD | SL: 3574.67000 | TP: 3575.68000
✅ BUY XAUUSD @ 3575.28 | TP: 3582.5957142857146 | SL: 3572.841428571429
✅ BUY XAUUSD @ 3575.47 | TP: 3583.2614285714285 | SL: 3572.872857142857
🔄 Updated XAUUSD | SL: 3572.88000 | TP: 3584.11000
Kein Top-Down-Setup vorhanden. Kein Trade.
✅ BUY XAUUSD @ 3575.29 | TP: 3583.4285714285716 | SL: 3572.577142857143
🔄 Updated XAUUSD | SL: 3573.59000 | TP: 3581.99000
🔄 Updated XAUUSD | SL: 3573.90000 | TP: 3581.07000
🔄 Updated XAUUSD | SL: 3573.90000 | TP: 3581.06000
🔄 Updated XAUUSD | SL: 3576.56000 | TP: 3577.79000
✅ BUY XAUUSD @ 3577.4 | TP: 3584.628928571429 | SL: 3574.990357142857
⚠️ RETCODE 1016 (Invalid stops)  Versuch 1/2
🔄 Updated XAUUSD | SL: 3577.00000 | TP: 3578.00000
✅ BUY XAUUSD @ 3578.23 | TP: 3586.0310714285715 | SL: 3575.6296428571427
🔄 Updated XAUUSD | SL: 3575.63000 | TP: 3586.63000
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
M5 Signal neutral. Kein Trade.
M5 Signal neutral. Kein Trade.
M5 Signal neutral. Kein Trade.
M5 Signal neutral. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
M5 Signal neutral. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
M5 Signal neutral. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
M5 Signal neutral. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
M5 Signal neutral. Kein Trade.
✅ SELL XAUUSD @ 3563.72 | TP: 3551.165 | SL: 3567.9049999999997
Kein Top-Down-Setup vorhanden. Kein Trade.
✅ SELL XAUUSD @ 3563.47 | TP: 3551.0532142857146 | SL: 3567.6089285714284
✅ SELL XAUUSD @ 3563.92 | TP: 3552.6603571428577 | SL: 3567.673214285714
✅ SELL XAUUSD @ 3565.45 | TP: 3553.589285714286 | SL: 3569.403571428571
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
✅ SELL XAUUSD @ 3562.22 | TP: 3553.2489285714287 | SL: 3565.210357142857
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
Kein Top-Down-Setup vorhanden. Kein Trade.
In [51]:
from apscheduler.schedulers.background import BackgroundScheduler
import time


scheduler = BackgroundScheduler()
#scheduler.add_job(main, 'date', run_date='2025-03-07 14:29:50')

#scheduler.add_job(decide_order, 'interval', minutes=1) #intervall
#scheduler.add_job(set_symbol, 'interval', minutes=30)
#scheduler.add_job(set_trend, 'interval', minutes=1)

#scheduler.add_job(decide_order, 'interval', minutes=1)
#scheduler.add_job(decide_order, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour='0-23', minute='*') #cron
#scheduler.add_job(get_buy_sell_signal, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour='0-23', minute='*/5') #cron
#scheduler.add_job(get_m5_trade_signals, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour='0-23', minute='*/5') #cron
scheduler.add_job(execute_m5_trade, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour='0-23', minute='*/5') #cron
scheduler.add_job(manual_update_trailing_sl_tp, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour='0-23', minute='*') #cron

#scheduler.add_job(export_marketview, 'cron', year="*", month='*', day_of_week='mon, tue, wed; thu, fri', hour='8-22', minute=00)

#scheduler.add_job(pause_trading, 'cron', year="*", month="*", day_of_week="mon, tue, wed, thu, fri", hour=22, minute=00) #cron
scheduler.start()

Get Jobs

In [52]:
scheduler.get_jobs()
Out [52]:
[<Job (id=6d0f4ea790404395bdf8de6e4b08d249 name=manual_update_trailing_sl_tp)>,
 <Job (id=aaf1ad647f4d4187acd88c3bfd1a24be name=execute_m5_trade)>]

Remove all Jobs

In [ ]:
scheduler.remove_all_jobs()

Shutdown AppScheduler

In [ ]:
scheduler.shutdown()