diff --git a/puprime5setup.exe b/Metatrader/puprime5setup.exe similarity index 100% rename from puprime5setup.exe rename to Metatrader/puprime5setup.exe diff --git a/Metatrader/start.sh b/Metatrader/start.sh old mode 100644 new mode 100755 index c57c14f7..aadc7e86 --- a/Metatrader/start.sh +++ b/Metatrader/start.sh @@ -1,20 +1,29 @@ #!/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 -mt5file='/config/.wine/drive_c/Program Files/MetaTrader 5/terminal64.exe' WINEPREFIX='/config/.wine' WINEDEBUG='-all' wine_executable="wine" -metatrader_version="5.0.36" 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.9.13/python-3.9.13.exe" +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 + echo "$1" } # Function to check if a dependency is installed @@ -25,16 +34,23 @@ check_dependency() { fi } -# Function to check if a Python package is installed +# pip show statt pkg_resources (in neueren Pythons nicht mehr zuverlässig vorhanden) is_python_package_installed() { - python3 -c "import pkg_resources; exit(not pkg_resources.require('$1'))" 2>/dev/null - return $? + python3 -m pip show "$1" >/dev/null 2>&1 } -# Function to check if a Python package is installed in Wine is_wine_python_package_installed() { - $wine_executable python -c "import pkg_resources; exit(not pkg_resources.require('$1'))" 2>/dev/null - return $? + $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 @@ -53,54 +69,77 @@ else fi # Check if MetaTrader 5 is already installed -if [ -e "$mt5file" ]; then - show_message "[2/7] File $mt5file already exists." +mt5file="$(find_terminal)" +if [ -n "$mt5file" ]; then + show_message "[2/7] Terminal found: $mt5file" else - show_message "[2/7] File $mt5file is not installed. Installing..." + show_message "[2/7] No MT5 terminal installed. Installing..." - # Set Windows 10 mode in Wine and download and install MT5 + # Set Windows 10 mode in Wine $wine_executable reg add "HKEY_CURRENT_USER\\Software\\Wine" /v Version /t REG_SZ /d "win10" /f - show_message "[3/7] Downloading MT5 installer..." - curl -o /config/.wine/drive_c/mt5setup.exe $mt5setup_url + + 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 [ -e "$mt5file" ]; then - show_message "[4/7] File $mt5file is installed. Running MT5..." +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] File $mt5file is not installed. MT5 cannot be run." + show_message "[4/7] No terminal64.exe found under $program_files. MT5 cannot be run." fi - -# Install Python in Wine if not present -if ! $wine_executable python --version 2>/dev/null; then - show_message "[5/7] Installing Python in Wine..." - curl -L $python_url -o /tmp/python-installer.exe - $wine_executable /tmp/python-installer.exe /quiet InstallAllUsers=1 PrependPath=1 - rm /tmp/python-installer.exe - show_message "[5/7] Python installed in Wine." +# 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 - show_message "[5/7] Python is already installed in Wine." + 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 -# Install MetaTrader5 library in Windows if not installed + +# 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==$metatrader_version"; then - $wine_executable python -m pip install --no-cache-dir MetaTrader5==$metatrader_version +if ! is_wine_python_package_installed "MetaTrader5"; then + $wine_executable python -m pip install --no-cache-dir MetaTrader5 fi -# Install mt5linux library in Windows if not installed + +# 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 @@ -112,7 +151,7 @@ fi 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 plumbum numpy + pip install --break-system-packages --no-cache-dir "rpyc>=6,<7" plumbum numpy fi # Install pyxdg library in Linux if not installed @@ -121,7 +160,7 @@ if ! is_python_package_installed "pyxdg"; then pip install --break-system-packages --no-cache-dir pyxdg fi -# Start the MT5 server on Linux +# 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 &