Compare commits
1 Commits
dev-windows
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 843b97e3b5 |
@@ -1,59 +0,0 @@
|
|||||||
#import <ZmqMql4Connector.mqh>
|
|
||||||
|
|
||||||
// Define the ZeroMQ server endpoint
|
|
||||||
#define ZMQ_SERVER_ENDPOINT "tcp://*:5900"
|
|
||||||
// Replace 'metatrader-port' with the port number you want to use for communication
|
|
||||||
|
|
||||||
// Define the ZeroMQ socket and context
|
|
||||||
CZmqMql4Server g_server;
|
|
||||||
CZmqContext g_context;
|
|
||||||
|
|
||||||
// Define a function to handle incoming messages
|
|
||||||
void OnMessageReceived(string message)
|
|
||||||
{
|
|
||||||
// Process the received message and perform necessary actions
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// Send a response message (if needed)
|
|
||||||
string responseMessage = "Response from MetaTrader";
|
|
||||||
g_server.Send(responseMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The start function that is called when the EA/script is initialized
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
// Initialize the ZeroMQ server
|
|
||||||
if (!g_server.Initialize(ZMQ_SERVER_ENDPOINT, g_context, OnMessageReceived))
|
|
||||||
{
|
|
||||||
Print("Failed to initialize ZeroMQ server");
|
|
||||||
return INIT_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the ZeroMQ server
|
|
||||||
if (!g_server.Start())
|
|
||||||
{
|
|
||||||
Print("Failed to start ZeroMQ server");
|
|
||||||
return INIT_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The main function that is called on each tick
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
// The deinitialization function that is called when the EA/script is stopped
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
// Stop the ZeroMQ server
|
|
||||||
g_server.Stop();
|
|
||||||
|
|
||||||
// Deinitialize the ZeroMQ server and context
|
|
||||||
g_server.Deinitialize();
|
|
||||||
g_context.Terminalize();
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
// ZmqMql4Connector.mqh
|
|
||||||
|
|
||||||
// Define the ZMQ message callback function type
|
|
||||||
typedef void OnZmqMessageReceived(string message);
|
|
||||||
|
|
||||||
class CZmqMql4Server
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
string m_endpoint; // ZeroMQ server endpoint
|
|
||||||
int m_socket; // ZeroMQ socket
|
|
||||||
int m_context; // ZeroMQ context
|
|
||||||
OnZmqMessageReceived @m_callback; // Message callback function
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
CZmqMql4Server()
|
|
||||||
{
|
|
||||||
m_socket = -1;
|
|
||||||
m_context = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~CZmqMql4Server()
|
|
||||||
{
|
|
||||||
Deinitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the ZeroMQ server
|
|
||||||
bool Initialize(string endpoint, OnZmqMessageReceived @callback)
|
|
||||||
{
|
|
||||||
m_endpoint = endpoint;
|
|
||||||
m_callback = @callback;
|
|
||||||
|
|
||||||
m_context = zmq_init(1);
|
|
||||||
if (m_context == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_socket = zmq_socket(m_context, ZMQ_REP);
|
|
||||||
if (m_socket == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int bindResult = zmq_bind(m_socket, m_endpoint);
|
|
||||||
if (bindResult == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the ZeroMQ server
|
|
||||||
bool Start()
|
|
||||||
{
|
|
||||||
if (m_socket == -1 || m_context == -1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
string message = Receive();
|
|
||||||
if (message != "")
|
|
||||||
m_callback(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the ZeroMQ server
|
|
||||||
void Stop()
|
|
||||||
{
|
|
||||||
if (m_socket != -1)
|
|
||||||
zmq_close(m_socket);
|
|
||||||
m_socket = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a message from the server
|
|
||||||
void Send(string message)
|
|
||||||
{
|
|
||||||
if (m_socket != -1)
|
|
||||||
zmq_send(m_socket, message, StringLen(message), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive a message in the server
|
|
||||||
string Receive()
|
|
||||||
{
|
|
||||||
if (m_socket != -1)
|
|
||||||
{
|
|
||||||
string message;
|
|
||||||
int receivedBytes = zmq_recv(m_socket, message, 4096, 0);
|
|
||||||
if (receivedBytes > 0)
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deinitialize the ZeroMQ server
|
|
||||||
void Deinitialize()
|
|
||||||
{
|
|
||||||
if (m_socket != -1)
|
|
||||||
zmq_close(m_socket);
|
|
||||||
if (m_context != -1)
|
|
||||||
zmq_term(m_context);
|
|
||||||
|
|
||||||
m_socket = -1;
|
|
||||||
m_context = -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+108
-59
@@ -1,6 +1,7 @@
|
|||||||
from keras.optimizers import Adam
|
from keras.optimizers import Adam
|
||||||
from keras.layers import Dense, Dropout
|
from keras.layers import Dense, Dropout
|
||||||
from keras.models import Sequential
|
from keras.models import Sequential
|
||||||
|
import pymt5
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import talib
|
import talib
|
||||||
from sklearn.preprocessing import MinMaxScaler
|
from sklearn.preprocessing import MinMaxScaler
|
||||||
@@ -8,15 +9,62 @@ import numpy as np
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import zmq
|
|
||||||
|
|
||||||
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
|
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
|
||||||
|
|
||||||
|
|
||||||
|
def connect_to_mt5_container():
|
||||||
|
server = "localhost" # Change to the appropriate IP or hostname if necessary
|
||||||
|
port = 15555 # Change to the appropriate port if necessary
|
||||||
|
login = 123456 # Change to your MetaTrader login number if necessary
|
||||||
|
password = "your_password" # Change to your MetaTrader password if necessary
|
||||||
|
|
||||||
|
# Connect to MetaTrader 5
|
||||||
|
mt5 = pymt5.PyMT5()
|
||||||
|
mt5.onConnected = onConnected
|
||||||
|
mt5.onDisconnected = onDisconnected
|
||||||
|
mt5.onData = onData
|
||||||
|
|
||||||
|
# Wait for the connection to be established
|
||||||
|
while not onConnected:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Send login request
|
||||||
|
login_request = {
|
||||||
|
'ver': '3',
|
||||||
|
'type': '1',
|
||||||
|
'login': str(login),
|
||||||
|
'password': password,
|
||||||
|
'res': '0'
|
||||||
|
}
|
||||||
|
mt5.broadcast(login_request)
|
||||||
|
|
||||||
|
# Wait for the login response
|
||||||
|
while not onConnected:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Check if login was successful
|
||||||
|
if onConnected:
|
||||||
|
print(f"Connected to MetaTrader 5: {onConnected}")
|
||||||
|
else:
|
||||||
|
print("Failed to connect to MetaTrader 5")
|
||||||
|
|
||||||
|
|
||||||
|
def onConnected(client_info):
|
||||||
|
print(f"Connected: {client_info}")
|
||||||
|
|
||||||
|
|
||||||
|
def onDisconnected(client_info):
|
||||||
|
print(f"Disconnected: {client_info}")
|
||||||
|
|
||||||
|
|
||||||
|
def onData(data):
|
||||||
|
print(f"Received data: {data}")
|
||||||
|
|
||||||
|
|
||||||
def start_mt5_bot():
|
def start_mt5_bot():
|
||||||
# Define the symbols and timeframes
|
# Define the symbols and timeframes
|
||||||
symbol = 'EURUSD'
|
symbol = 'EURUSD'
|
||||||
timeframe = 'H1' # H1 timeframe (1 hour)
|
timeframe = 60 # H1 timeframe (1 hour)
|
||||||
|
|
||||||
# Set up initial variables
|
# Set up initial variables
|
||||||
lot_size = 0.01
|
lot_size = 0.01
|
||||||
@@ -44,15 +92,12 @@ def start_mt5_bot():
|
|||||||
neural_network_model.compile(optimizer=Adam(
|
neural_network_model.compile(optimizer=Adam(
|
||||||
learning_rate=0.001), loss='binary_crossentropy')
|
learning_rate=0.001), loss='binary_crossentropy')
|
||||||
|
|
||||||
def get_historical_data(socket):
|
def get_historical_data():
|
||||||
# Request historical data from MetaTrader app
|
# Retrieve historical data
|
||||||
socket.send_string(
|
rates = pymt5.copy_rates_from_pos(symbol, timeframe, 0, 1000)
|
||||||
f"GET_HISTORICAL_DATA {symbol} {timeframe} 01/01/2022 31/12/2022")
|
df = pd.DataFrame(rates)
|
||||||
|
df['time'] = pd.to_datetime(df['time'], unit='s')
|
||||||
# Receive historical data from MetaTrader app
|
df.set_index('time', inplace=True)
|
||||||
response = socket.recv_string()
|
|
||||||
data = pd.read_json(response)
|
|
||||||
df = data[['open', 'high', 'low', 'close', 'tick_volume']]
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def calculate_indicators_and_detect_patterns(df):
|
def calculate_indicators_and_detect_patterns(df):
|
||||||
@@ -64,8 +109,8 @@ def start_mt5_bot():
|
|||||||
macd_fast_period = 12
|
macd_fast_period = 12
|
||||||
macd_slow_period = 26
|
macd_slow_period = 26
|
||||||
macd_signal_period = 9
|
macd_signal_period = 9
|
||||||
_, _, df['macd'] = talib.MACD(df['close'], fastperiod=macd_fast_period,
|
df['macd'], _, df['macd_signal'] = talib.MACD(df['close'], fastperiod=macd_fast_period,
|
||||||
slowperiod=macd_slow_period, signalperiod=macd_signal_period)
|
slowperiod=macd_slow_period, signalperiod=macd_signal_period)
|
||||||
|
|
||||||
# Detect divergence based on RSI and MACD
|
# Detect divergence based on RSI and MACD
|
||||||
df['rsi_divergence'] = np.where(
|
df['rsi_divergence'] = np.where(
|
||||||
@@ -84,15 +129,17 @@ def start_mt5_bot():
|
|||||||
|
|
||||||
# Detect double tops and bottoms
|
# Detect double tops and bottoms
|
||||||
df['pattern'] = 'None'
|
df['pattern'] = 'None'
|
||||||
df['top_pattern'] = np.where((df['high'].shift(1) < df['high']) & (df['high'].shift(-1) < df['high']) &
|
df['top_pattern'] = np.where(
|
||||||
(df['high'].shift(2) > df['high']) & (
|
(df['high'].shift(1) < df['high']) & (df['high'].shift(-1) < df['high']) &
|
||||||
df['high'].shift(-2) > df['high']),
|
(df['high'].shift(2) > df['high']) & (
|
||||||
'Double Top', 'None')
|
df['high'].shift(-2) > df['high']), 'Double Top', 'None'
|
||||||
|
)
|
||||||
df.loc[df['top_pattern'] != 'None', 'pattern'] = df['top_pattern']
|
df.loc[df['top_pattern'] != 'None', 'pattern'] = df['top_pattern']
|
||||||
df['bottom_pattern'] = np.where((df['low'].shift(1) > df['low']) & (df['low'].shift(-1) > df['low']) &
|
df['bottom_pattern'] = np.where(
|
||||||
(df['low'].shift(2) < df['low']) & (
|
(df['low'].shift(1) > df['low']) & (df['low'].shift(-1) > df['low']) &
|
||||||
df['low'].shift(-2) < df['low']),
|
(df['low'].shift(2) < df['low']) & (
|
||||||
'Double Bottom', 'None')
|
df['low'].shift(-2) < df['low']), 'Double Bottom', 'None'
|
||||||
|
)
|
||||||
df.loc[df['bottom_pattern'] != 'None',
|
df.loc[df['bottom_pattern'] != 'None',
|
||||||
'pattern'] = df['bottom_pattern']
|
'pattern'] = df['bottom_pattern']
|
||||||
|
|
||||||
@@ -128,9 +175,9 @@ def start_mt5_bot():
|
|||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
def execute_trade(signal, df, socket):
|
def execute_trade(signal, df):
|
||||||
# Implement risk management and trade execution logic based on the signals generated
|
# Implement risk management and trade execution logic based on the signals generated
|
||||||
# Update TensorFlow neural network model with trade outcome
|
# Update TensorFlow neural network model with trade outcome (loss or win)
|
||||||
|
|
||||||
# Calculate risk and position size based on lot size, stop loss, and take profit
|
# Calculate risk and position size based on lot size, stop loss, and take profit
|
||||||
risk = lot_size * stop_loss
|
risk = lot_size * stop_loss
|
||||||
@@ -145,17 +192,15 @@ def start_mt5_bot():
|
|||||||
try:
|
try:
|
||||||
if signal == 'Buy':
|
if signal == 'Buy':
|
||||||
# Place a buy trade
|
# Place a buy trade
|
||||||
socket.send_string(
|
result = pymt5.order_send(symbol, pymt5.OP_BUY, lot_size, 0, stop_loss, take_profit,
|
||||||
f"PLACE_TRADE {symbol} BUY {lot_size} {stop_loss} {take_profit}")
|
"Buy trade", 123456, pymt5.ORDER_TIME_GTC, 0)
|
||||||
response = socket.recv_string()
|
outcome = 'Win' if result.retcode == pymt5.TRADE_RETCODE_DONE else 'Loss'
|
||||||
outcome = 'Win' if response == 'TRADE_EXECUTED' else 'Loss'
|
|
||||||
|
|
||||||
elif signal == 'Sell':
|
elif signal == 'Sell':
|
||||||
# Place a sell trade
|
# Place a sell trade
|
||||||
socket.send_string(
|
result = pymt5.order_send(symbol, pymt5.OP_SELL, lot_size, 0, stop_loss, take_profit,
|
||||||
f"PLACE_TRADE {symbol} SELL {lot_size} {stop_loss} {take_profit}")
|
"Sell trade", 123456, pymt5.ORDER_TIME_GTC, 0)
|
||||||
response = socket.recv_string()
|
outcome = 'Win' if result.retcode == pymt5.TRADE_RETCODE_DONE else 'Loss'
|
||||||
outcome = 'Win' if response == 'TRADE_EXECUTED' else 'Loss'
|
|
||||||
|
|
||||||
# Example trade outcome information
|
# Example trade outcome information
|
||||||
trade_outcome = {
|
trade_outcome = {
|
||||||
@@ -249,41 +294,45 @@ def start_mt5_bot():
|
|||||||
plt.legend()
|
plt.legend()
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
# Connect to MetaTrader app using ZeroMQ
|
def run_trading_bot():
|
||||||
context = zmq.Context()
|
# Connect to MetaTrader 5 container
|
||||||
socket = context.socket(zmq.REQ)
|
connect_to_mt5_container()
|
||||||
socket.connect("tcp://metatrader_service:5900")
|
|
||||||
# Replace 'metatrader-container-ip' and 'metatrader-port' with the IP address and port of the MetaTrader container
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# Get historical data
|
# Get historical data
|
||||||
df = get_historical_data(socket)
|
df = get_historical_data()
|
||||||
|
|
||||||
# Calculate indicators and detect patterns
|
# Calculate indicators and detect patterns
|
||||||
df = calculate_indicators_and_detect_patterns(df)
|
df = calculate_indicators_and_detect_patterns(df)
|
||||||
|
|
||||||
# Generate trade signals
|
# Generate trade signals
|
||||||
df = generate_signals(df)
|
df = generate_signals(df)
|
||||||
|
|
||||||
# Execute trades
|
# Execute trades
|
||||||
for i in range(1, len(df)):
|
for i in range(1, len(df)):
|
||||||
signal = df['signal'].iloc[i]
|
signal = df['signal'].iloc[i]
|
||||||
if signal != 'None':
|
if signal != 'None':
|
||||||
execute_trade(signal, df, socket)
|
execute_trade(signal, df)
|
||||||
|
|
||||||
# Visualize data
|
# Visualize data
|
||||||
visualize_data(df)
|
visualize_data(df)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error running trading bot: {str(e)}")
|
print(f"Error running trading bot: {str(e)}")
|
||||||
|
|
||||||
# Wait for the next iteration
|
# Wait for the next iteration
|
||||||
time.sleep(60) # Adjust the time interval as needed
|
time.sleep(60) # Adjust the time interval as needed
|
||||||
|
|
||||||
# Disconnect from ZeroMQ socket
|
# Run the trading bot
|
||||||
socket.close()
|
run_trading_bot()
|
||||||
|
|
||||||
|
# Load TensorFlow neural network model weights
|
||||||
|
neural_network_model.load_weights('weights/model_weights.h5')
|
||||||
|
|
||||||
|
# Disconnect from MetaTrader 5
|
||||||
|
pymt5.shutdown()
|
||||||
|
|
||||||
|
|
||||||
# Start the MetaTrader bot
|
# Start the MetaTrader 5 bot
|
||||||
start_mt5_bot()
|
start_mt5_bot()
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ TA-Lib
|
|||||||
matplotlib
|
matplotlib
|
||||||
scikit-learn
|
scikit-learn
|
||||||
tensorflow
|
tensorflow
|
||||||
pyzmq
|
pymt5
|
||||||
@@ -4,7 +4,7 @@ import time
|
|||||||
# Connect to the trading bot container
|
# Connect to the trading bot container
|
||||||
sio = socketio.Client()
|
sio = socketio.Client()
|
||||||
# Replace with the appropriate URL and port of your trading bot container
|
# Replace with the appropriate URL and port of your trading bot container
|
||||||
sio.connect('tcp://trading_bot:3000')
|
sio.connect('http://trading_bot:3000')
|
||||||
|
|
||||||
# Handle events from the trading bot container
|
# Handle events from the trading bot container
|
||||||
|
|
||||||
|
|||||||
+7
-6
@@ -1,14 +1,19 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
metatrader_service:
|
metatrader_service:
|
||||||
image: ejtrader/metatrader:5
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/DockerFile.xorg
|
||||||
container_name: metatrader
|
container_name: metatrader
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- DISPLAY=$DISPLAY
|
- DISPLAY=$DISPLAY
|
||||||
privileged: true
|
privileged: true
|
||||||
volumes:
|
volumes:
|
||||||
- ejtraderMT:/data
|
- /tmp/.X11-unix:/tmp/.X11-unix
|
||||||
|
- ./mt5:/mt5
|
||||||
|
devices:
|
||||||
|
- /dev/dri:/dev/dri
|
||||||
ports:
|
ports:
|
||||||
- "5900:5900"
|
- "5900:5900"
|
||||||
- "15555:15555"
|
- "15555:15555"
|
||||||
@@ -20,7 +25,6 @@ services:
|
|||||||
|
|
||||||
trading_bot:
|
trading_bot:
|
||||||
container_name: trading_bot
|
container_name: trading_bot
|
||||||
restart: unless-stopped
|
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/DockerFile
|
dockerfile: docker/DockerFile
|
||||||
@@ -49,6 +53,3 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
trading_network:
|
trading_network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
|
||||||
ejtraderMT: {}
|
|
||||||
|
|||||||
+1
-2
@@ -21,10 +21,9 @@ RUN tar -xzf ta-lib-0.4.0-src.tar.gz && \
|
|||||||
|
|
||||||
# Install the Python dependencies
|
# Install the Python dependencies
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
RUN pip install ejtraderMT -U
|
|
||||||
|
|
||||||
# Copy the application code to the container
|
# Copy the application code to the container
|
||||||
COPY app/ .
|
COPY app/ .
|
||||||
|
|
||||||
# Run the bot script using xvfb-run
|
# Run the bot script when the container launches
|
||||||
CMD [ "python", "bot.py" ]
|
CMD [ "python", "bot.py" ]
|
||||||
|
|||||||
+37
-4
@@ -1,6 +1,39 @@
|
|||||||
FROM ejtrader/metatrader:5
|
# Base docker image.
|
||||||
|
FROM ubuntu:focal
|
||||||
|
|
||||||
# Add your custom configuration and scripts here, if needed
|
# Install Wine and necessary dependencies
|
||||||
|
RUN dpkg --add-architecture i386 && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
gnupg \
|
||||||
|
software-properties-common \
|
||||||
|
wget \
|
||||||
|
winbind \
|
||||||
|
xauth \
|
||||||
|
xvfb \
|
||||||
|
cabextract
|
||||||
|
|
||||||
# Start MetaTrader 5
|
# Download and install Wine from WineHQ repository
|
||||||
CMD ["/root/.wine/drive_c/Program Files/MetaTrader 5/terminal64.exe"]
|
RUN wget -qO- https://dl.winehq.org/wine-builds/winehq.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/winehq.gpg && \
|
||||||
|
add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --install-recommends winehq-stable winetricks
|
||||||
|
|
||||||
|
# Create a non-root user
|
||||||
|
RUN useradd -m -s /bin/bash trader
|
||||||
|
|
||||||
|
# Set the working directory
|
||||||
|
WORKDIR /home/trader
|
||||||
|
|
||||||
|
# Install X server utilities
|
||||||
|
RUN apt-get install -y x11-xserver-utils x11vnc xvfb
|
||||||
|
|
||||||
|
# Configure X server
|
||||||
|
RUN mkdir /tmp/.X11-unix && \
|
||||||
|
chown trader:trader /tmp/.X11-unix
|
||||||
|
|
||||||
|
# Set up entrypoint script
|
||||||
|
COPY mt5/entrypoint.sh /entrypoint.sh
|
||||||
|
RUN chmod +x /entrypoint.sh
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|||||||
+1
-8
@@ -8,12 +8,5 @@ export DISPLAY=:0
|
|||||||
# Install necessary dependencies using winetricks
|
# Install necessary dependencies using winetricks
|
||||||
winetricks -q corefonts
|
winetricks -q corefonts
|
||||||
|
|
||||||
# Add a small delay for X server initialization
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Run MetaTrader 5
|
# Run MetaTrader 5
|
||||||
exec su - trader -c 'wine "/home/trader/.wine/drive_c/Program Files/MetaTrader 5/terminal64.exe"'
|
su - trader -c 'wine "/home/trader/.wine/drive_c/Program Files/MetaTrader 5/terminal64.exe"'
|
||||||
|
|
||||||
# Clean up X server resources
|
|
||||||
killall Xvfb
|
|
||||||
rm -rf /tmp/.X11-unix
|
|
||||||
|
|||||||
Reference in New Issue
Block a user