Initial commit setup with docker
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
.vscode
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# Trading Bot
|
||||||
|
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
A trading bot built using Python and TensorFlow to automate trading strategies.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [Features](#features)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The trading bot is designed to automate trading strategies using historical data, technical indicators, and machine learning. It connects to the MetaTrader 5 platform, retrieves historical data, calculates indicators, generates trade signals, executes trades, and updates a neural network model based on trade outcomes.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Retrieval of historical data from MetaTrader 5
|
||||||
|
- Calculation of technical indicators (RSI, MACD, etc.)
|
||||||
|
- Detection of double tops and bottoms patterns
|
||||||
|
- Generation of trade signals based on indicators, patterns, and trend direction
|
||||||
|
- Execution of trades with risk management
|
||||||
|
- Update of a TensorFlow neural network model based on trade outcomes
|
||||||
|
- Visualization of data and trade signals
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/your-username/trading-bot.git
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Install Docker and Docker Compose on your system.
|
||||||
|
1. Build the Docker image and start the container:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd trading-bot
|
||||||
|
docker-compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Ensure that the Docker container is running.
|
||||||
|
1. Access the running container:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker exec -it trading-bot_app_1 bash
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Inside the container, run the trading bot:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
1. The trading bot will start executing the trading strategies based on the predefined logic.
|
||||||
|
1. Monitor the bot's output and visualizations.
|
||||||
|
|
||||||
|
1. To stop the bot, use `Ctrl + C` in the terminal.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The trading bot can be customized and configured by modifying the following files:
|
||||||
|
|
||||||
|
- `main.py`: Contains the main logic for running the trading bot.
|
||||||
|
- `config.py`: Defines the configuration parameters such as symbol, timeframe, lot size, stop loss, take profit, etc.
|
||||||
|
- `indicators.py`: Defines additional technical indicators and patterns to be used.
|
||||||
|
- `preprocess.py`: Handles data preprocessing and feature engineering.
|
||||||
|
- `model.py`: Defines the structure and training of the neural network model.
|
||||||
|
- `docker-compose.yml`: Configures the Docker container for running the trading bot.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! If you encounter any issues or have suggestions for improvements, please feel free to submit a pull request or create an issue in the repository.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the [MIT Licence](https://opensource.org/license/mit/).
|
||||||
Binary file not shown.
+351
@@ -0,0 +1,351 @@
|
|||||||
|
import time
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
from sklearn.preprocessing import MinMaxScaler
|
||||||
|
import talib
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import MetaTrader5 as mt5
|
||||||
|
from keras.models import Sequential
|
||||||
|
from keras.layers import Dense, Dropout
|
||||||
|
from keras.optimizers import Adam
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
|
def start_mt5(username, password, server, path):
|
||||||
|
# Ensure that all variables are the correct type
|
||||||
|
uname = int(username) # Username must be an int
|
||||||
|
pword = str(password) # Password must be a string
|
||||||
|
trading_server = str(server) # Server must be a string
|
||||||
|
filepath = str(path) # Filepath must be a string
|
||||||
|
# Connect to MetaTrader 5
|
||||||
|
if mt5.initialize(login=uname, password=pword, server=trading_server, path=filepath):
|
||||||
|
# Login to MT5
|
||||||
|
if mt5.login(login=uname, password=pword, server=trading_server):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("Login Fail")
|
||||||
|
quit()
|
||||||
|
return PermissionError
|
||||||
|
else:
|
||||||
|
print("MT5 Initialization Failed")
|
||||||
|
quit()
|
||||||
|
return ConnectionAbortedError
|
||||||
|
|
||||||
|
|
||||||
|
def connect_to_mt5(username, password, server, path):
|
||||||
|
# Start the MetaTrader 5 instance
|
||||||
|
if start_mt5(username, password, server, path):
|
||||||
|
print("Connected to MetaTrader 5")
|
||||||
|
else:
|
||||||
|
print("Failed to connect to MetaTrader 5")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# Define the symbols and timeframes
|
||||||
|
symbol = 'EURUSD'
|
||||||
|
timeframe = mt5.TIMEFRAME_H1
|
||||||
|
|
||||||
|
# Set up initial variables
|
||||||
|
lot_size = 0.01
|
||||||
|
stop_loss = 100
|
||||||
|
take_profit = 150
|
||||||
|
|
||||||
|
# Define TensorFlow neural network model
|
||||||
|
|
||||||
|
|
||||||
|
def create_neural_network_model(input_shape):
|
||||||
|
model = Sequential()
|
||||||
|
model.add(Dense(64, activation='relu', input_shape=input_shape))
|
||||||
|
model.add(Dropout(0.2))
|
||||||
|
model.add(Dense(64, activation='relu'))
|
||||||
|
model.add(Dropout(0.2))
|
||||||
|
model.add(Dense(1, activation='sigmoid'))
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
# Define input shape for the neural network
|
||||||
|
input_shape = (10,) # Adjust the input shape based on your features and data
|
||||||
|
|
||||||
|
# Create the neural network model
|
||||||
|
neural_network_model = create_neural_network_model(input_shape)
|
||||||
|
|
||||||
|
# Compile the model
|
||||||
|
neural_network_model.compile(optimizer=Adam(
|
||||||
|
learning_rate=0.001), loss='binary_crossentropy')
|
||||||
|
|
||||||
|
|
||||||
|
def get_historical_data():
|
||||||
|
# Retrieve historical data
|
||||||
|
rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, 1000)
|
||||||
|
df = pd.DataFrame(rates)
|
||||||
|
df['time'] = pd.to_datetime(df['time'], unit='s')
|
||||||
|
df.set_index('time', inplace=True)
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_indicators_and_detect_patterns(df):
|
||||||
|
# Calculate RSI
|
||||||
|
rsi_period = 14
|
||||||
|
df['rsi'] = talib.RSI(df['close'], rsi_period)
|
||||||
|
|
||||||
|
# Calculate MACD
|
||||||
|
macd_fast_period = 12
|
||||||
|
macd_slow_period = 26
|
||||||
|
macd_signal_period = 9
|
||||||
|
df['macd'], _, df['macd_signal'] = talib.MACD(df['close'], fastperiod=macd_fast_period,
|
||||||
|
slowperiod=macd_slow_period, signalperiod=macd_signal_period)
|
||||||
|
|
||||||
|
# Detect divergence based on RSI and MACD
|
||||||
|
df['rsi_divergence'] = np.where(
|
||||||
|
df['rsi'].diff().shift(-1) * df['macd'].diff().shift(-1) < 0, True, False)
|
||||||
|
df['macd_divergence'] = np.where(
|
||||||
|
df['macd'].diff().shift(-1) * df['rsi'].diff().shift(-1) < 0, True, False)
|
||||||
|
|
||||||
|
# Detect support and resistance levels
|
||||||
|
window = 10
|
||||||
|
df['support'] = df['low'].rolling(window).min()
|
||||||
|
df['resistance'] = df['high'].rolling(window).max()
|
||||||
|
|
||||||
|
# Determine trend direction
|
||||||
|
df['trend_200'] = df['close'].rolling(window=200).mean()
|
||||||
|
df['trend_50'] = df['close'].rolling(window=50).mean()
|
||||||
|
|
||||||
|
# Detect double tops and bottoms
|
||||||
|
df['pattern'] = 'None'
|
||||||
|
df['top_pattern'] = np.where(
|
||||||
|
(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.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['low'].shift(2) < df['low']) & (
|
||||||
|
df['low'].shift(-2) < df['low']), 'Double Bottom', 'None'
|
||||||
|
)
|
||||||
|
df.loc[df['bottom_pattern'] != 'None', 'pattern'] = df['bottom_pattern']
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def generate_signals(df):
|
||||||
|
# Determine trade signals based on divergences, patterns, and trend direction
|
||||||
|
df['signal'] = 'None'
|
||||||
|
df['divergence_signal'] = np.where((df['rsi_divergence'] == True) & (df['pattern'] != 'None'), 'Both',
|
||||||
|
np.where(df['rsi_divergence'] == True, 'RSI', 'Pattern'))
|
||||||
|
df['strongest_divergence_signal'] = df[[
|
||||||
|
'divergence_signal', 'macd_divergence']].max(axis=1)
|
||||||
|
df['support_resistance_signal'] = np.where(df['close'] > df['resistance'], 'Resistance',
|
||||||
|
np.where(df['close'] < df['support'], 'Support', 'None'))
|
||||||
|
df['trend_signal'] = np.where(df['close'] > df['trend_200'], 'Uptrend',
|
||||||
|
np.where(df['close'] < df['trend_200'], 'Downtrend', 'None'))
|
||||||
|
for i in range(1, len(df)):
|
||||||
|
prev_divergence_signal = df['divergence_signal'].iloc[i - 1]
|
||||||
|
curr_divergence_signal = df['divergence_signal'].iloc[i]
|
||||||
|
strongest_divergence_signal = df['strongest_divergence_signal'].iloc[i]
|
||||||
|
support_resistance_signal = df['support_resistance_signal'].iloc[i]
|
||||||
|
trend_signal = df['trend_signal'].iloc[i]
|
||||||
|
|
||||||
|
if strongest_divergence_signal != 'None':
|
||||||
|
df['signal'].iloc[i] = strongest_divergence_signal
|
||||||
|
elif prev_divergence_signal == curr_divergence_signal and curr_divergence_signal != 'None':
|
||||||
|
df['signal'].iloc[i] = curr_divergence_signal
|
||||||
|
else:
|
||||||
|
df['signal'].iloc[i] = support_resistance_signal
|
||||||
|
|
||||||
|
if trend_signal != 'None' and df['signal'].iloc[i] != 'None':
|
||||||
|
df['signal'].iloc[i] = trend_signal
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def execute_trade(signal, df):
|
||||||
|
# Implement risk management and trade execution logic based on the signals generated
|
||||||
|
# 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
|
||||||
|
risk = lot_size * stop_loss
|
||||||
|
strongest_divergence_signal = df['strongest_divergence_signal'].iloc[-1]
|
||||||
|
if strongest_divergence_signal == 'RSI':
|
||||||
|
risk *= 1.2 # Increase risk by 20% if RSI divergence is the strongest
|
||||||
|
elif strongest_divergence_signal == 'Pattern':
|
||||||
|
risk *= 1.5 # Increase risk by 50% if pattern divergence is the strongest
|
||||||
|
|
||||||
|
position_size = risk / (take_profit - stop_loss)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if signal == 'Buy':
|
||||||
|
# Place a buy trade
|
||||||
|
result = mt5.ORDER_RESULT_FAIL
|
||||||
|
request = {
|
||||||
|
"action": mt5.TRADE_ACTION_DEAL,
|
||||||
|
"symbol": symbol,
|
||||||
|
"volume": lot_size,
|
||||||
|
"type": mt5.ORDER_TYPE_BUY,
|
||||||
|
"price": mt5.symbol_info_tick(symbol).ask,
|
||||||
|
"sl": mt5.symbol_info_tick(symbol).ask - stop_loss * mt5.symbol_info(symbol).point,
|
||||||
|
"tp": mt5.symbol_info_tick(symbol).ask + take_profit * mt5.symbol_info(symbol).point,
|
||||||
|
"deviation": 20,
|
||||||
|
"magic": 123456,
|
||||||
|
"comment": "Buy trade",
|
||||||
|
"type_time": mt5.ORDER_TIME_GTC,
|
||||||
|
"type_filling": mt5.ORDER_FILLING_RETURN,
|
||||||
|
}
|
||||||
|
result = mt5.order_send(request)
|
||||||
|
outcome = 'Win' if result.retcode == mt5.TRADE_RETCODE_DONE else 'Loss'
|
||||||
|
|
||||||
|
elif signal == 'Sell':
|
||||||
|
# Place a sell trade
|
||||||
|
result = mt5.ORDER_RESULT_FAIL
|
||||||
|
request = {
|
||||||
|
"action": mt5.TRADE_ACTION_DEAL,
|
||||||
|
"symbol": symbol,
|
||||||
|
"volume": lot_size,
|
||||||
|
"type": mt5.ORDER_TYPE_SELL,
|
||||||
|
"price": mt5.symbol_info_tick(symbol).bid,
|
||||||
|
"sl": mt5.symbol_info_tick(symbol).bid + stop_loss * mt5.symbol_info(symbol).point,
|
||||||
|
"tp": mt5.symbol_info_tick(symbol).bid - take_profit * mt5.symbol_info(symbol).point,
|
||||||
|
"deviation": 20,
|
||||||
|
"magic": 123456,
|
||||||
|
"comment": "Sell trade",
|
||||||
|
"type_time": mt5.ORDER_TIME_GTC,
|
||||||
|
"type_filling": mt5.ORDER_FILLING_RETURN,
|
||||||
|
}
|
||||||
|
result = mt5.order_send(request)
|
||||||
|
outcome = 'Win' if result.retcode == mt5.TRADE_RETCODE_DONE else 'Loss'
|
||||||
|
|
||||||
|
# Example trade outcome information
|
||||||
|
trade_outcome = {
|
||||||
|
'pattern': df['pattern'].iloc[-1],
|
||||||
|
'divergence_strength': strongest_divergence_signal,
|
||||||
|
'time': df.index[-1],
|
||||||
|
'trend_direction': df['trend_signal'].iloc[-1],
|
||||||
|
'indicator_used': strongest_divergence_signal,
|
||||||
|
'outcome': outcome
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update TensorFlow neural network model with trade outcome
|
||||||
|
update_neural_network_model(trade_outcome)
|
||||||
|
|
||||||
|
# Example print statements for debugging
|
||||||
|
print(f"Executed {signal} trade with position size: {position_size}")
|
||||||
|
print(f"Trade outcome: {trade_outcome}")
|
||||||
|
|
||||||
|
# Additional logic for trade management, monitoring, etc.
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error executing trade: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
def update_neural_network_model(trade_outcome):
|
||||||
|
# Implement code to update the neural network model based on trade outcome
|
||||||
|
pattern = trade_outcome['pattern']
|
||||||
|
divergence_strength = trade_outcome['divergence_strength']
|
||||||
|
time = trade_outcome['time']
|
||||||
|
trend_direction = trade_outcome['trend_direction']
|
||||||
|
indicator_used = trade_outcome['indicator_used']
|
||||||
|
outcome = trade_outcome['outcome']
|
||||||
|
|
||||||
|
# Example update code: Append trade outcome information to a dataset for future training
|
||||||
|
trade_data = pd.DataFrame({
|
||||||
|
'pattern': [pattern],
|
||||||
|
'divergence_strength': [divergence_strength],
|
||||||
|
'time': [time],
|
||||||
|
'trend_direction': [trend_direction],
|
||||||
|
'indicator_used': [indicator_used],
|
||||||
|
'outcome': [outcome]
|
||||||
|
})
|
||||||
|
# Append the trade data to the dataset for future training
|
||||||
|
dataset = pd.read_csv('trade_dataset.csv') # Load existing dataset
|
||||||
|
updated_dataset = pd.concat([dataset, trade_data], ignore_index=True)
|
||||||
|
# Save updated dataset
|
||||||
|
updated_dataset.to_csv('trade_dataset.csv', index=False)
|
||||||
|
|
||||||
|
# Example retraining code: Retrain the neural network model with the updated dataset
|
||||||
|
# Preprocess data as per your requirements
|
||||||
|
X_train, y_train = preprocess_data(updated_dataset)
|
||||||
|
# Example retraining step
|
||||||
|
neural_network_model.fit(X_train, y_train, epochs=10, batch_size=32)
|
||||||
|
|
||||||
|
# Save the updated model weights
|
||||||
|
neural_network_model.save_weights('model_weights.h5')
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess_data(dataset):
|
||||||
|
# Define the numerical features (if any)
|
||||||
|
numerical_features = [] # Update with the actual numerical feature column names
|
||||||
|
|
||||||
|
# Define the input features
|
||||||
|
input_features = dataset[[
|
||||||
|
'pattern', 'divergence_strength', 'trend_direction', 'indicator_used']]
|
||||||
|
|
||||||
|
# Convert categorical features to one-hot encoding
|
||||||
|
input_features = pd.get_dummies(input_features)
|
||||||
|
|
||||||
|
# Normalize numerical features (if any)
|
||||||
|
if numerical_features:
|
||||||
|
scaler = MinMaxScaler()
|
||||||
|
input_features[numerical_features] = scaler.fit_transform(
|
||||||
|
input_features[numerical_features])
|
||||||
|
|
||||||
|
# Extract target labels from the dataset
|
||||||
|
target_labels = dataset['outcome']
|
||||||
|
|
||||||
|
# Convert target labels to numerical representation (0s and 1s)
|
||||||
|
target_labels = target_labels.map({'Loss': 0, 'Win': 1})
|
||||||
|
|
||||||
|
# Return the preprocessed input features and target labels
|
||||||
|
return input_features, target_labels
|
||||||
|
|
||||||
|
|
||||||
|
def visualize_data(df):
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
plt.plot(df.index, df['close'], label='Close')
|
||||||
|
# Add visualizations for other indicators, levels, and patterns
|
||||||
|
plt.scatter(df[df['pattern'] == 'Double Top'].index, df[df['pattern'] == 'Double Top']['high'],
|
||||||
|
color='red', marker='v', label='Double Top')
|
||||||
|
plt.scatter(df[df['pattern'] == 'Double Bottom'].index, df[df['pattern'] == 'Double Bottom']['low'],
|
||||||
|
color='green', marker='^', label='Double Bottom')
|
||||||
|
plt.legend()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def run_trading_bot():
|
||||||
|
# Connect to MetaTrader 5
|
||||||
|
connect_to_mt5(username='your_username', password='your_password',
|
||||||
|
server='your_server', path='your_mt5_installation_path')
|
||||||
|
|
||||||
|
# Load TensorFlow neural network model weights
|
||||||
|
neural_network_model.load_weights('model_weights.h5')
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# Get historical data
|
||||||
|
df = get_historical_data()
|
||||||
|
|
||||||
|
# Calculate indicators and detect patterns
|
||||||
|
df = calculate_indicators_and_detect_patterns(df)
|
||||||
|
|
||||||
|
# Generate trade signals
|
||||||
|
df = generate_signals(df)
|
||||||
|
|
||||||
|
# Execute trades
|
||||||
|
for i in range(1, len(df)):
|
||||||
|
signal = df['signal'].iloc[i]
|
||||||
|
if signal != 'None':
|
||||||
|
execute_trade(signal, df)
|
||||||
|
|
||||||
|
# Visualize data
|
||||||
|
visualize_data(df)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error running trading bot: {str(e)}")
|
||||||
|
|
||||||
|
# Wait for the next iteration
|
||||||
|
time.sleep(60) # Adjust the time interval as needed
|
||||||
|
|
||||||
|
|
||||||
|
# Run the trading bot
|
||||||
|
run_trading_bot()
|
||||||
|
|
||||||
|
# Disconnect from MetaTrader 5
|
||||||
|
mt5.shutdown()
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
numpy
|
||||||
|
pandas
|
||||||
|
TA-Lib
|
||||||
|
matplotlib
|
||||||
|
scikit-learn
|
||||||
|
tensorflow
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import socketio
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Connect to the trading bot container
|
||||||
|
sio = socketio.Client()
|
||||||
|
# Replace with the appropriate URL and port of your trading bot container
|
||||||
|
sio.connect('http://trading_bot:8000')
|
||||||
|
|
||||||
|
# Handle events from the trading bot container
|
||||||
|
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def connect():
|
||||||
|
print('Connected to trading bot container')
|
||||||
|
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def disconnect():
|
||||||
|
print('Disconnected from trading bot container')
|
||||||
|
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def send_trade_signal(signal):
|
||||||
|
print(f'Received trade signal: {signal}')
|
||||||
|
# Process the trade signal and execute trades through MetaTrader 5
|
||||||
|
|
||||||
|
|
||||||
|
# Main loop to keep the script running
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
metatrader_service:
|
||||||
|
container_name: metatrader
|
||||||
|
image: ejtrader/metatrader:5
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5900:5900"
|
||||||
|
- "15555:15555"
|
||||||
|
- "15556:15556"
|
||||||
|
- "15557:15557"
|
||||||
|
- "15558:15558"
|
||||||
|
volumes:
|
||||||
|
- ejtraderMT:/data
|
||||||
|
|
||||||
|
trading_bot:
|
||||||
|
container_name: trading_bot
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/DockerFile
|
||||||
|
volumes:
|
||||||
|
- ./app:/app
|
||||||
|
depends_on:
|
||||||
|
- metatrader_service
|
||||||
|
|
||||||
|
mt5_bridge:
|
||||||
|
container_name: mt5_bridge
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/DockerFile.mt5_bridge
|
||||||
|
volumes: -./bridge:/bridge
|
||||||
|
depends_on:
|
||||||
|
- metatrader_service
|
||||||
|
- trading_bot
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
ejtraderMT: {}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Use an official Python runtime as the base image
|
||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
# Set the working directory in the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the requirements file to the working directory
|
||||||
|
COPY app/requirements.txt .
|
||||||
|
|
||||||
|
# Copy the Tab-Lib dependencies to the working directory
|
||||||
|
COPY app/Tab-Lib-deps/ta-lib-0.4.0-src.tar.gz .
|
||||||
|
|
||||||
|
# Extract and install Tab-Lib
|
||||||
|
RUN tar -xzf ta-lib-0.4.0-src.tar.gz && \
|
||||||
|
rm ta-lib-0.4.0-src.tar.gz && \
|
||||||
|
cd ta-lib && \
|
||||||
|
./configure --prefix=/usr && \
|
||||||
|
make && \
|
||||||
|
make install && \
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Install the Python dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy the application code to the container
|
||||||
|
COPY app/ .
|
||||||
|
|
||||||
|
# Run the bot script when the container launches
|
||||||
|
CMD [ "python", "bot.py" ]
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
# Set the working directory in the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the bridge script to the container
|
||||||
|
COPY bridge/mt5_bridge.py .
|
||||||
|
|
||||||
|
# Install any dependencies required by the bridge script
|
||||||
|
RUN pip install python-socketio python-engineio
|
||||||
|
|
||||||
|
CMD ["python", "mt5_bridge.py"]
|
||||||
Reference in New Issue
Block a user