from flask import Flask, render_template, request, jsonify from flask_sqlalchemy import SQLAlchemy from datetime import datetime import os from sqlalchemy import Date def create_app(): app = Flask(__name__) # Конфигурация базы данных # Предполагаем, что база данных находится в директории Database проекта Adwizard adwizard_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) db_path = os.path.join(r'C:\Users\Antekov\AppData\Roaming\MetaQuotes\Terminal\Common\Files', 'article.19684.db.sqlite') app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Инициализация расширений db = SQLAlchemy(app) return app, db app, db = create_app() # Модели данных для базы данных оптимизации class Project(db.Model): __tablename__ = 'projects' id_project = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(255), nullable=False) version = db.Column(db.String(255), nullable=False) description = db.Column(db.Text) params = db.Column(db.Text) status = db.Column(db.String(20), nullable=False, default='Done') # Связи stages = db.relationship('Stage', backref='project', lazy=True) class Stage(db.Model): __tablename__ = 'stages' id_stage = db.Column(db.Integer, primary_key=True, autoincrement=True) id_project = db.Column(db.Integer, db.ForeignKey('projects.id_project'), nullable=False) id_parent_stage = db.Column(db.Integer, db.ForeignKey('stages.id_stage')) name = db.Column(db.String(255), nullable=False, default='1') expert = db.Column(db.String(255)) symbol = db.Column(db.String(20), nullable=False, default='EURGBP') period = db.Column(db.String(10), nullable=False, default='H1') optimization = db.Column(db.Integer, nullable=False, default=2) model = db.Column(db.Integer, nullable=False, default=2) from_date = db.Column(db.String(20), nullable=False, default='2022.01.01') to_date = db.Column(db.String(20), nullable=False, default='2022.06.01') forward_mode = db.Column(db.Integer, nullable=False, default=0) forward_date = db.Column(db.String(20)) deposit = db.Column(db.Integer, nullable=False, default=10000) currency = db.Column(db.String(10), nullable=False, default='USD') profit_in_pips = db.Column(db.Integer, nullable=False, default=0) leverage = db.Column(db.Integer, nullable=False, default=200) execution_mode = db.Column(db.Integer, nullable=False, default=0) optimization_criterion = db.Column(db.Integer, nullable=False, default=7) status = db.Column(db.String(20), nullable=False, default='Done') # Связи parent_stage = db.relationship('Stage', remote_side=[id_stage]) jobs = db.relationship('Job', backref='stage', lazy=True) class Job(db.Model): __tablename__ = 'jobs' id_job = db.Column(db.Integer, primary_key=True, autoincrement=True) id_stage = db.Column(db.Integer, db.ForeignKey('stages.id_stage'), nullable=False) symbol = db.Column(db.String(20), default='EURGBP') period = db.Column(db.String(10), default='H1') tester_inputs = db.Column(db.Text) status = db.Column(db.String(20), nullable=False, default='Done') # Связи tasks = db.relationship('Task', backref='job', lazy=True) class Task(db.Model): __tablename__ = 'tasks' id_task = db.Column(db.Integer, primary_key=True, autoincrement=True) id_job = db.Column(db.Integer, db.ForeignKey('jobs.id_job'), nullable=False) optimization_criterion = db.Column(db.Integer, default=7, nullable=False) start_date = db.Column(db.String(50)) finish_date = db.Column(db.String(50)) max_duration = db.Column(db.Integer, default=0, nullable=False) status = db.Column(db.String(20), nullable=False, default='Queued') # Связи passes = db.relationship('Pass', backref='task', lazy=True) class Pass(db.Model): __tablename__ = 'passes' id_pass = db.Column(db.Integer, primary_key=True, autoincrement=True) id_task = db.Column(db.Integer, db.ForeignKey('tasks.id_task')) is_optimization = db.Column(db.Boolean) is_forward = db.Column(db.Boolean) initial_deposit = db.Column(db.Float) withdrawal = db.Column(db.Float) profit = db.Column(db.Float) gross_profit = db.Column(db.Float) gross_loss = db.Column(db.Float) max_profittrade = db.Column(db.Float) max_losstrade = db.Column(db.Float) conprofitmax = db.Column(db.Float) conprofitmax_trades = db.Column(db.Float) max_conwins = db.Column(db.Float) max_conprofit_trades = db.Column(db.Float) conlossmax = db.Column(db.Float) conlossmax_trades = db.Column(db.Float) max_conlosses = db.Column(db.Float) max_conloss_trades = db.Column(db.Float) balancemin = db.Column(db.Float) balance_dd = db.Column(db.Float) balancedd_percent = db.Column(db.Float) balance_ddrel_percent = db.Column(db.Float) balance_dd_relative = db.Column(db.Float) equitymin = db.Column(db.Float) equity_dd = db.Column(db.Float) equitydd_percent = db.Column(db.Float) equity_ddrel_percent = db.Column(db.Float) equity_dd_relative = db.Column(db.Float) expected_payoff = db.Column(db.Float) profit_factor = db.Column(db.Float) recovery_factor = db.Column(db.Float) sharpe_ratio = db.Column(db.Float) min_marginlevel = db.Column(db.Float) deals = db.Column(db.Float) trades = db.Column(db.Float) profit_trades = db.Column(db.Float) loss_trades = db.Column(db.Float) short_trades = db.Column(db.Float) long_trades = db.Column(db.Float) profit_shorttrades = db.Column(db.Float) profit_longtrades = db.Column(db.Float) profittrades_avgcon = db.Column(db.Float) losstrades_avgcon = db.Column(db.Float) complex_criterion = db.Column(db.Float) custom_ontester = db.Column(db.Float) params = db.Column(db.Text) inputs = db.Column(db.Text) pass_date = db.Column(db.String(50)) # Связи strategy_group = db.relationship('StrategyGroup', backref='pass', uselist=False, lazy=True) class StrategyGroup(db.Model): __tablename__ = 'strategy_groups' id_pass = db.Column(db.Integer, db.ForeignKey('passes.id_pass'), primary_key=True) name = db.Column(db.String(255)) class PassCluster(db.Model): __tablename__ = 'passes_clusters' id_task = db.Column(db.Integer, primary_key=True) id_pass = db.Column(db.Integer, primary_key=True) cluster = db.Column(db.Integer) @app.route('/') def index(): """Главная страница приложения""" projects = Project.query.all() return render_template('index.html', projects=projects) @app.route('/projects') def projects_list(): """Список всех проектов""" projects = Project.query.all() return render_template('projects.html', projects=projects) @app.route('/project/') def project_detail(project_id): """Детали проекта""" project = Project.query.get_or_404(project_id) stages = Stage.query.filter_by(id_project=project_id).all() return render_template('project_detail.html', project=project, stages=stages) @app.route('/stage/') def stage_detail(stage_id): """Детали этапа""" stage = Stage.query.get_or_404(stage_id) jobs = Job.query.filter_by(id_stage=stage_id).all() return render_template('stage_detail.html', stage=stage, jobs=jobs) @app.route('/job/') def job_detail(job_id): """Детали работы""" job = Job.query.get_or_404(job_id) tasks = Task.query.filter_by(id_job=job_id).all() return render_template('job_detail.html', job=job, tasks=tasks) @app.route('/task/') def task_detail(task_id): """Детали задачи""" task = Task.query.get_or_404(task_id) passes = Pass.query.filter_by(id_task=task_id).order_by(Pass.id_pass).all() return render_template('task_detail.html', task=task, passes=passes) @app.route('/passes') def passes_list(): """Список всех проходов (результатов оптимизации)""" passes = Pass.query.limit(50).all() # Ограничиваем количество для производительности return render_template('passes.html', passes=passes) if __name__ == '__main__': app.run(debug=True)