230 satır
No EOL
8,4 KiB
Python
230 satır
No EOL
8,4 KiB
Python
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/<int:project_id>')
|
|
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/<int:stage_id>')
|
|
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/<int:job_id>')
|
|
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/<int:task_id>')
|
|
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) |