You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

108 lines
4.2 KiB

'''
'''
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, IntradayBarNumberSignalGenerator
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())
self.solver.add_generator(IntradayBarNumberSignalGenerator(14))
params = { 'num_strategies' : self.sb_strategiesNum.value(),
'max_hold_bars' : self.sb_maxHoldBars.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)