Untitled
unknown
plain_text
17 days ago
18 kB
1
Indexable
Never
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 {}
Leave a Comment