Untitled
unknown
plain_text
a year ago
18 kB
13
Indexable
Y3BOT
###
main.py
import os
from src.gui import BotGUI
import tkinter as tk
from src.loading_screen import LoadingScreen
if __name__ == "__main__":
loading_root = tk.Tk()
loading_screen = LoadingScreen(loading_root)
loading_screen.update_status("Starting application...", 0)
gui = BotGUI(loading_screen)
loading_screen.update_status("Loading complete!", 100)
loading_root.after(1000, loading_screen.close)
gui.run()
###
requirements.txt
MetaTrader5==5.0.37
tk==0.1.0
###
settings.json
{"symbol": "XAUUSD", "lot": "0.01", "time_frame": "M15", "stop_loss": "80", "take_profit": "40", "preset": "scalping", "custom": {"period": "", "deviation": ""}}
###
Y3BOT.spec
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='Y3BOT',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='Y3BOT',
)
###
src/bot.py
import MetaTrader5 as mt5
import pandas as pd # Убедитесь, что вы импортируете pandas, если используете его
from src.trade_logic import TradeLogic # Импортируйте TradeLogic из соответствующего модуля
from config.presets import Presets # Импортируйте Presets из соответствующего модуля
class Y3BOT:
def __init__(self, symbol, lot, time_frame, stop_loss, take_profit, preset='scalping'):
self.symbol = symbol
self.lot = lot
self.time_frame = self.convert_time_frame(time_frame)
self.stop_loss = stop_loss
self.take_profit = take_profit
self.preset = preset
self.trade_logic = TradeLogic(self.symbol, self.lot, self.stop_loss, self.take_profit)
self.preset_config = Presets.load_preset(self.preset) # Изменено на load_preset
def connect(self, account, server):
if not mt5.initialize():
print("Failed to initialize MT5")
return False
login_status = mt5.login(account, server=server)
if login_status:
account_info = mt5.account_info()
if account_info is None:
print("Failed to get account info")
return False
print(f"Connected to account: {account_info.login}, balance: {account_info.balance}")
return True
else:
print("Failed to login")
return False
def convert_time_frame(self, time_frame):
time_frames = {
"M1": mt5.TIMEFRAME_M1,
"M5": mt5.TIMEFRAME_M5,
"M15": mt5.TIMEFRAME_M15,
"M30": mt5.TIMEFRAME_M30,
"H1": mt5.TIMEFRAME_H1,
"H4": mt5.TIMEFRAME_H4,
"D1": mt5.TIMEFRAME_D1,
}
return time_frames.get(time_frame, mt5.TIMEFRAME_M1)
def get_data(self):
rates = mt5.copy_rates_from_pos(self.symbol, self.time_frame, 0, 100)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
return df
###
src/gui.py
import tkinter as tk
from tkinter import ttk
import json
import MetaTrader5 as mt5
from src.bot import Y3BOT
from config.presets import Presets
from src.loading_screen import LoadingScreen
import os
class BotGUI:
def __init__(self, loading_screen):
self.loading_screen = loading_screen
self.root = tk.Tk()
self.root.title("Y3BOT - Forex Scalping Bot")
self.create_widgets()
self.bot = None
self.account_info = None # Для хранения информации о счете
def create_widgets(self):
# Установка стиля
style = ttk.Style()
style.configure("TLabel", font=("Helvetica", 12))
style.configure("TButton", font=("Helvetica", 12))
self.loading_screen.update_status("Loading symbols...", 10)
# Инициализация MetaTrader 5
if not mt5.initialize():
print("Ошибка инициализации MetaTrader 5")
self.loading_screen.update_status("Ошибка инициализации MetaTrader 5", 100)
return # Прекращаем выполнение, если инициализация не удалась
symbols = mt5.symbols_get()
if symbols is None:
print("Не удалось получить символы. Проверьте подключение к MetaTrader 5.")
self.loading_screen.update_status("Не удалось получить символы", 100)
return # Прекращаем выполнение, если символы не получены
symbols = [sym.name for sym in symbols]
self.symbol_label = ttk.Label(self.root, text="Symbol:")
self.symbol_label.grid(row=0, column=0)
self.symbol_combobox = ttk.Combobox(self.root, values=symbols)
self.symbol_combobox.grid(row=0, column=1)
self.loading_screen.update_status("Loading time frames...", 20)
self.time_frame_label = ttk.Label(self.root, text="Time frame:")
self.time_frame_label.grid(row=1, column=0)
time_frames = ["M1", "M5", "M15", "M30", "H1", "H4", "D1"]
self.time_frame_combobox = ttk.Combobox(self.root, values=time_frames)
self.time_frame_combobox.grid(row=1, column=1)
self.loading_screen.update_status("Loading trading settings...", 40)
self.lot_label = ttk.Label(self.root, text="Lot size:")
self.lot_label.grid(row=2, column=0)
self.lot_entry = ttk.Entry(self.root)
self.lot_entry.grid(row=2, column=1)
self.stop_loss_label = ttk.Label(self.root, text="Stop Loss:")
self.stop_loss_label.grid(row=3, column=0)
self.stop_loss_entry = ttk.Entry(self.root)
self.stop_loss_entry.grid(row=3, column=1)
self.take_profit_label = ttk.Label(self.root, text="Take Profit:")
self.take_profit_label.grid(row=4, column=0)
self.take_profit_entry = ttk.Entry(self.root)
self.take_profit_entry.grid(row=4, column=1)
self.preset_label = ttk.Label(self.root, text="Preset:")
self.preset_label.grid(row=5, column=0)
self.preset_combobox = ttk.Combobox(self.root, values=["scalping", "custom"])
self.preset_combobox.grid(row=5, column=1)
self.preset_combobox.bind("<<ComboboxSelected>>", self.toggle_custom_settings)
self.custom_frame = tk.Frame(self.root)
self.custom_frame.grid(row=6, column=0, columnspan=2)
# Новые настройки для custom
self.custom_period_label = ttk.Label(self.custom_frame, text="Period:")
self.custom_period_label.grid(row=0, column=0)
self.custom_period_entry = ttk.Entry(self.custom_frame)
self.custom_period_entry.grid(row=0, column=1)
self.custom_deviation_label = ttk.Label(self.custom_frame, text="Deviation:")
self.custom_deviation_label.grid(row=1, column=0)
self.custom_deviation_entry = ttk.Entry(self.custom_frame)
self.custom_deviation_entry.grid(row=1, column=1)
self.custom_frame.grid_remove() # Скрываем кастомные настройки по умолчанию
self.loading_screen.update_status("Loading buttons...", 70)
self.start_button = ttk.Button(self.root, text="Start Bot", command=self.start_bot)
self.start_button.grid(row=7, column=0, columnspan=2)
self.info_label = ttk.Label(self.root, text="Bot Status:")
self.info_label.grid(row=8, column=0, columnspan=2)
self.history_label = ttk.Label(self.root, text="Trade History:")
self.history_label.grid(row=9, column=0, columnspan=2)
self.history_text = tk.Text(self.root, height=10, width=50)
self.history_text.grid(row=10, column=0, columnspan=2)
# Метка для отображения информации о счете и валютной паре
self.account_info_label = ttk.Label(self.root, text="", font=("Helvetica", 14))
self.account_info_label.grid(row=11, column=0, columnspan=2)
# Поле для отладочной информации
self.debug_text = tk.Text(self.root, height=5, width=50, state='disabled')
self.debug_text.grid(row=12, column=0, columnspan=2)
self.loading_screen.update_status("Finalizing...", 90)
self.load_settings()
def get_account_info(self):
account_info = mt5.account_info()
if account_info is not None:
self.account_info = account_info
return account_info.login, account_info.server
else:
print("Не удалось получить информацию об аккаунте.")
return None, None
def toggle_custom_settings(self, event):
if self.preset_combobox.get() == "custom":
self.custom_frame.grid()
else:
self.custom_frame.grid_remove()
def start_bot(self):
symbol = self.symbol_combobox.get()
lot = float(self.lot_entry.get())
time_frame = self.time_frame_combobox.get()
stop_loss = float(self.stop_loss_entry.get())
take_profit = float(self.take_profit_entry.get())
preset = self.preset_combobox.get()
# Получите данные для подключения
account, server = self.get_account_info() # Получаем информацию о счете и сервере
if account is None or server is None:
print("Не удалось получить информацию об аккаунте и сервере.")
return # Прекращаем выполнение, если информация не получена
# Обновляем метку с информацией о счете
self.account_info_label.config(text=f"Connected to account: {account}, Symbol: {symbol}, Time Frame: {time_frame}")
if preset == 'custom':
custom_config = {
'period': int(self.custom_period_entry.get()),
'deviation': float(self.custom_deviation_entry.get())
}
Presets.save_preset('custom', custom_config)
self.bot = Y3BOT(symbol, lot, time_frame, stop_loss, take_profit, preset)
# Передаем account и server в метод connect
if self.bot.connect(account, server):
self.bot.run() # Запускаем бота
self.log_debug("Bot started.")
def stop_bot(self):
if self.bot:
self.bot.stop() # Останавливаем бота
self.log_debug("Bot stopped.")
def log_debug(self, message):
self.debug_text.config(state='normal')
self.debug_text.insert(tk.END, message + "\n")
self.debug_text.config(state='disabled')
self.debug_text.see(tk.END) # Прокручиваем текстовое поле вниз
def save_settings(self):
settings = {
'symbol': self.symbol_combobox.get(),
'lot': self.lot_entry.get(),
'time_frame': self.time_frame_combobox.get(),
'stop_loss': self.stop_loss_entry.get(),
'take_profit': self.take_profit_entry.get(),
'preset': self.preset_combobox.get(),
'custom': {
'period': self.custom_period_entry.get(),
'deviation': self.custom_deviation_entry.get()
}
}
with open('settings.json', 'w') as f:
json.dump(settings, f)
def load_settings(self):
try:
with open('settings.json', 'r') as f:
settings = json.load(f)
self.symbol_combobox.set(settings['symbol'])
self.lot_entry.insert(0, settings['lot'])
self.time_frame_combobox.set(settings['time_frame'])
self.stop_loss_entry.insert(0, settings['stop_loss'])
self.take_profit_entry.insert(0, settings['take_profit'])
self.preset_combobox.set(settings['preset'])
if settings['preset'] == 'custom':
self.custom_period_entry.insert(0, settings['custom']['period'])
self.custom_deviation_entry.insert(0, settings['custom']['deviation'])
self.custom_frame.grid()
except FileNotFoundError:
pass
def run(self):
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.root.mainloop()
def on_closing(self):
self.save_settings()
self.stop_bot()
mt5.shutdown() # Закрываем соединение с MetaTrader 5
self.root.destroy()
class Y3BOT:
def __init__(self, symbol, lot, time_frame, stop_loss, take_profit, preset):
self.symbol = symbol
self.lot = lot
self.time_frame = time_frame
self.stop_loss = stop_loss
self.take_profit = take_profit
self.preset = preset
self.running = False
def connect(self, account, server):
# Здесь добавьте логику для подключения к аккаунту
print(f"Connected to account: {account}, server: {server}")
return True # Возвращаем True, если подключение успешно
def run(self):
self.running = True
print("Бот запущен.")
# Здесь добавьте логику для работы бота
def stop(self):
self.running = False
print("Бот остановлен.")
###
src/loading_screen.py
import tkinter as tk
from tkinter import ttk
class LoadingScreen:
def __init__(self, root):
self.root = root
self.root.title("Loading Y3BOT...")
self.progress = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=300, mode='determinate')
self.progress.pack(pady=20)
self.status_label = tk.Label(root, text="Initializing...")
self.status_label.pack(pady=10)
def update_status(self, status, progress):
self.status_label.config(text=status)
self.progress['value'] = progress
self.root.update_idletasks()
def close(self):
self.root.destroy()
src/strategies.py
import pandas as pd
class BollingerBandsStrategy:
@staticmethod
def apply(df, period=20, deviation=2):
df['ma'] = df['close'].rolling(window=period).mean()
df['std'] = df['close'].rolling(window=period).std()
df['upper'] = df['ma'] + (df['std'] * deviation)
df['lower'] = df['ma'] - (df['std'] * deviation)
return df
@staticmethod
def generate_signal(df):
if df['close'].iloc[-1] > df['upper'].iloc[-1]:
return 'sell'
elif df['close'].iloc[-1] < df['lower'].iloc[-1]:
return 'buy'
return None
###
src/trade_logic.py
import MetaTrader5 as mt5
from src.strategies import BollingerBandsStrategy
class TradeLogic:
def __init__(self, symbol, lot, stop_loss, take_profit):
self.symbol = symbol
self.lot = lot
self.stop_loss = stop_loss
self.take_profit = take_profit
def analyze(self, df, preset_config):
df = BollingerBandsStrategy.apply(df)
signal = BollingerBandsStrategy.generate_signal(df)
return signal
def execute_trade(self, signal):
if signal == 'buy':
order = mt5.ORDER_TYPE_BUY
elif signal == 'sell':
order = mt5.ORDER_TYPE_SELL
else:
return
price = mt5.symbol_info_tick(self.symbol).ask if order == mt5.ORDER_TYPE_BUY else mt5.symbol_info_tick(self.symbol).bid
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": self.symbol,
"volume": self.lot,
"type": order,
"price": price,
"sl": price - self.stop_loss if signal == 'buy' else price + self.stop_loss,
"tp": price + self.take_profit if signal == 'buy' else price - self.take_profit,
"deviation": 10,
"magic": 234000,
"comment": "Y3BOT trade",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
print(f"Order failed, retcode={result.retcode}")
###
config/presets.py
import json
import os
class Presets:
presets_file = 'config/presets.json' # Изменено, чтобы учитывать правильный путь
@staticmethod
def load_preset(preset_name):
presets = Presets.load_presets()
return presets.get(preset_name, {})
@staticmethod
def save_preset(preset_name, preset_data):
presets = Presets.load_presets()
presets[preset_name] = preset_data
with open(Presets.presets_file, 'w') as f:
json.dump(presets, f)
@staticmethod
def load_presets():
try:
with open(Presets.presets_file, 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
Editor is loading...
Leave a Comment