#!/bin/bash # # MT5 im Container – Variante mit Broker-Terminal (PU Prime) und 64-Bit-Python. # Gründe: # - Das MetaTrader5-Python-Paket gibt es für 32-Bit-Python nur bis 5.0.37 (2022). # Das hängt bei aktuellen Terminal-Builds in initialize(). 64-Bit-Python bekommt # das aktuelle Paket. # - Das Broker-Terminal bringt die PU-Prime-Server vorkonfiguriert mit. # Configuration variables WINEPREFIX='/config/.wine' WINEDEBUG='-all' wine_executable="wine" mt5server_port="8001" MT5_CMD_OPTIONS="${MT5_CMD_OPTIONS:-}" mono_url="https://dl.winehq.org/wine/wine-mono/10.3.0/wine-mono-10.3.0-x86.msi" python_url="https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe" # Broker-Installer wird mit ins Image kopiert (Metatrader/puprime5setup.exe). # Fehlt er, wird das generische MetaQuotes-Terminal installiert. broker_setup="/Metatrader/puprime5setup.exe" mt5setup_url="https://download.mql5.com/cdn/web/metaquotes.software.corp/mt5/mt5setup.exe" program_files="/config/.wine/drive_c/Program Files" # Function to display a graphical message show_message() { echo "$1" } # Function to check if a dependency is installed check_dependency() { if ! command -v $1 &> /dev/null; then echo "$1 is not installed. Please install it to continue." exit 1 fi } # pip show statt pkg_resources (in neueren Pythons nicht mehr zuverlässig vorhanden) is_python_package_installed() { python3 -m pip show "$1" >/dev/null 2>&1 } is_wine_python_package_installed() { $wine_executable python -m pip show "$1" >/dev/null 2>&1 } # Terminal suchen – Broker-Installer legen es unter eigenem Ordnernamen ab find_terminal() { find "$program_files" -maxdepth 2 -iname terminal64.exe 2>/dev/null | head -1 } # Ist das Python in Wine ein 64-Bit-Python? wine_python_is_64bit() { $wine_executable python -c "import struct,sys; sys.exit(struct.calcsize('P') != 8)" 2>/dev/null } # Check for necessary dependencies check_dependency "curl" check_dependency "$wine_executable" # Install Mono if not present if [ ! -e "/config/.wine/drive_c/windows/mono" ]; then show_message "[1/7] Downloading and installing Mono..." curl -o /config/.wine/drive_c/mono.msi $mono_url WINEDLLOVERRIDES=mscoree=d $wine_executable msiexec /i /config/.wine/drive_c/mono.msi /qn rm /config/.wine/drive_c/mono.msi show_message "[1/7] Mono installed." else show_message "[1/7] Mono is already installed." fi # Check if MetaTrader 5 is already installed mt5file="$(find_terminal)" if [ -n "$mt5file" ]; then show_message "[2/7] Terminal found: $mt5file" else show_message "[2/7] No MT5 terminal installed. Installing..." # Set Windows 10 mode in Wine $wine_executable reg add "HKEY_CURRENT_USER\\Software\\Wine" /v Version /t REG_SZ /d "win10" /f if [ -f "$broker_setup" ]; then show_message "[3/7] Using broker installer $broker_setup" cp "$broker_setup" /config/.wine/drive_c/mt5setup.exe else show_message "[3/7] Downloading generic MT5 installer..." curl -o /config/.wine/drive_c/mt5setup.exe $mt5setup_url fi show_message "[3/7] Installing MetaTrader 5..." $wine_executable "/config/.wine/drive_c/mt5setup.exe" "/auto" & wait rm -f /config/.wine/drive_c/mt5setup.exe # Manche Installer beenden sich, bevor der Download fertig ist – kurz warten for i in $(seq 1 60); do mt5file="$(find_terminal)" [ -n "$mt5file" ] && break sleep 5 done fi # Recheck if MetaTrader 5 is installed if [ -n "$mt5file" ] && [ -e "$mt5file" ]; then show_message "[4/7] Terminal installed: $mt5file. Running MT5..." $wine_executable "$mt5file" $MT5_CMD_OPTIONS & else show_message "[4/7] No terminal64.exe found under $program_files. MT5 cannot be run." fi # Install 64-bit Python in Wine if not present if wine_python_is_64bit; then show_message "[5/7] 64-bit Python is already installed in Wine: $($wine_executable python --version 2>&1)" else if $wine_executable python --version >/dev/null 2>&1; then show_message "[5/7] WARNING: Wine Python is 32-bit – installing 64-bit Python in addition." show_message "[5/7] For a clean setup, delete ./config and start again." fi show_message "[5/7] Installing 64-bit Python in Wine..." curl -L $python_url -o /tmp/python-installer.exe $wine_executable /tmp/python-installer.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 rm /tmp/python-installer.exe show_message "[5/7] Python installed in Wine: $($wine_executable python --version 2>&1)" fi # Upgrade pip and install required packages show_message "[6/7] Installing Python libraries" $wine_executable python -m pip install --upgrade --no-cache-dir pip # MetaTrader5: current release (supports current terminal builds and numpy 2) show_message "[6/7] Installing MetaTrader5 library in Windows" if ! is_wine_python_package_installed "MetaTrader5"; then $wine_executable python -m pip install --no-cache-dir MetaTrader5 fi # RPyC server in Wine: mt5linux 0.1.9 (old CLI with -w), its own dependencies # are ancient pins -> --no-deps, rpyc/plumbum installed explicitly show_message "[6/7] Checking and installing mt5linux library in Windows if necessary" if ! is_wine_python_package_installed "mt5linux"; then $wine_executable python -m pip install --no-cache-dir --no-deps "mt5linux==0.1.9" fi if ! is_wine_python_package_installed "rpyc"; then $wine_executable python -m pip install --no-cache-dir "rpyc>=6,<7" plumbum fi # Install python-dateutil if needed (datetime is built-in, but dateutil adds features) if ! is_wine_python_package_installed "python-dateutil"; then show_message "[6/7] Installing python-dateutil library in Windows" $wine_executable python -m pip install --no-cache-dir python-dateutil fi # Install mt5linux library in Linux if not installed show_message "[6/7] Checking and installing mt5linux library in Linux if necessary" if ! is_python_package_installed "mt5linux"; then pip install --break-system-packages --no-cache-dir --no-deps mt5linux==0.1.9 && \ pip install --break-system-packages --no-cache-dir "rpyc>=6,<7" plumbum numpy fi # Install pyxdg library in Linux if not installed show_message "[6/7] Checking and installing pyxdg library in Linux if necessary" if ! is_python_package_installed "pyxdg"; then pip install --break-system-packages --no-cache-dir pyxdg fi # Start the MT5 server on Linux (runs the RPyC classic server inside Wine Python) show_message "[7/7] Starting the mt5linux server..." python3 -m mt5linux --host 0.0.0.0 -p $mt5server_port -w $wine_executable python.exe & # Give the server some time to start sleep 5 # Check if the server is running if ss -tuln | grep ":$mt5server_port" > /dev/null; then show_message "[7/7] The mt5linux server is running on port $mt5server_port." else show_message "[7/7] Failed to start the mt5linux server on port $mt5server_port." fi