|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
from PyQt5.QtWidgets import QMainWindow, QTreeWidgetItem
|
|
|
|
|
|
|
|
|
|
from .ui_mainwindow import Ui_MainWindow
|
|
|
|
|
from solver.solver import Solver
|
|
|
|
|
from data.series import Series
|
|
|
|
|
from data.signal import PriceComparisonSignalGenerator, RsiSignalGenerator,\
|
|
|
|
|
AtrSignalGenerator, DayOfWeekSignalGenerator, CrtdrSignalGenerator,\
|
|
|
|
|
AtrDeltaSignalGenerator, SmaSignalGenerator, DayOfMonthSignalGenerator,\
|
|
|
|
|
CciSignalGenerator, BbandsSignalGenerator, PivotPointsSignalGenerator,\
|
|
|
|
|
StochasticSignalGenerator
|
|
|
|
|
from PyQt5.Qt import Qt, QFileDialog, QThread, Q_ARG, QMetaObject
|
|
|
|
|
|
|
|
|
|
import pyqtgraph
|
|
|
|
|
import numpy
|
|
|
|
|
|
|
|
|
|
class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
|
|
'''
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
|
'''
|
|
|
|
|
Constructor
|
|
|
|
|
'''
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setupUi(self)
|
|
|
|
|
self.work_thread = QThread()
|
|
|
|
|
self.work_thread.start()
|
|
|
|
|
|
|
|
|
|
def browse(self):
|
|
|
|
|
fname = QFileDialog.getOpenFileName(self, 'Open file')
|
|
|
|
|
if fname[0] != '':
|
|
|
|
|
self.e_filename.setText(fname[0])
|
|
|
|
|
|
|
|
|
|
def go(self):
|
|
|
|
|
self.tw_strategies.clear()
|
|
|
|
|
self.series = Series()
|
|
|
|
|
self.series.load_from_finam_csv(self.e_filename.text())
|
|
|
|
|
self.solver = Solver(self.series)
|
|
|
|
|
self.solver.add_generator(PriceComparisonSignalGenerator())
|
|
|
|
|
self.solver.add_generator(RsiSignalGenerator())
|
|
|
|
|
self.solver.add_generator(AtrSignalGenerator())
|
|
|
|
|
self.solver.add_generator(AtrDeltaSignalGenerator())
|
|
|
|
|
self.solver.add_generator(DayOfWeekSignalGenerator())
|
|
|
|
|
self.solver.add_generator(DayOfMonthSignalGenerator())
|
|
|
|
|
self.solver.add_generator(SmaSignalGenerator())
|
|
|
|
|
self.solver.add_generator(CrtdrSignalGenerator())
|
|
|
|
|
self.solver.add_generator(CciSignalGenerator())
|
|
|
|
|
self.solver.add_generator(BbandsSignalGenerator())
|
|
|
|
|
self.solver.add_generator(PivotPointsSignalGenerator())
|
|
|
|
|
self.solver.add_generator(StochasticSignalGenerator())
|
|
|
|
|
|
|
|
|
|
params = { 'num_strategies' : self.sb_strategiesNum.value() }
|
|
|
|
|
if self.cb_minTradesFilter.isChecked():
|
|
|
|
|
params['min_trades'] = self.sb_minTrades.value()
|
|
|
|
|
|
|
|
|
|
if self.cb_minWinRate.isChecked():
|
|
|
|
|
params['min_win_rate'] = self.sb_minWinRate.value()
|
|
|
|
|
if self.cb_minSharpe.isChecked():
|
|
|
|
|
params['min_sharpe'] = self.sb_minSharpe.value()
|
|
|
|
|
|
|
|
|
|
if self.rb_long.isChecked():
|
|
|
|
|
params['direction'] = 'long'
|
|
|
|
|
else:
|
|
|
|
|
params['direction'] = 'short'
|
|
|
|
|
|
|
|
|
|
self.solver.done.connect(self.done)
|
|
|
|
|
self.solver.progress.connect(self.progress)
|
|
|
|
|
|
|
|
|
|
self.solver.moveToThread(self.work_thread)
|
|
|
|
|
QMetaObject.invokeMethod(self.solver, 'solve', Q_ARG(dict, params))
|
|
|
|
|
#results = self.solver.solve(params)
|
|
|
|
|
|
|
|
|
|
def done(self, results):
|
|
|
|
|
for result in results:
|
|
|
|
|
item = QTreeWidgetItem(self.tw_strategies)
|
|
|
|
|
item.setText(0, result['display_name'])
|
|
|
|
|
item.setText(1, str(result['trades_number']))
|
|
|
|
|
item.setText(2, "{:.4f}".format(result['total_pnl']))
|
|
|
|
|
item.setText(3, "{:.2f}".format(result['profit_factor']))
|
|
|
|
|
item.setText(4, "{:.2f}".format(result['sharpe']))
|
|
|
|
|
item.setText(5, "{:.2f}%".format(result['avg_percentage']))
|
|
|
|
|
item.setText(6, "{:.2f}%".format(result['win_percentage']))
|
|
|
|
|
item.setData(0, Qt.UserRole + 1, result)
|
|
|
|
|
|
|
|
|
|
for i in range(0, 7):
|
|
|
|
|
self.tw_strategies.resizeColumnToContents(i)
|
|
|
|
|
|
|
|
|
|
def progress(self, current, total):
|
|
|
|
|
if current < total:
|
|
|
|
|
self.pb_progress.setValue(float(current) / total * 100)
|
|
|
|
|
else:
|
|
|
|
|
self.pb_progress.setValue(100)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def strategyClicked(self, item, column):
|
|
|
|
|
result = item.data(0, Qt.UserRole + 1)
|
|
|
|
|
pnl = numpy.cumsum([trade.pnl() for trade in result['trades']])
|
|
|
|
|
xs = [trade.entry_bar for trade in result['trades']]
|
|
|
|
|
pyqtgraph.plot(xs, pnl)
|
|
|
|
|
|
|
|
|
|
for trade in result['trades']:
|
|
|
|
|
print(trade.entry_bar, trade.entry_price, trade.exit_price)
|
|
|
|
|
|