''' ''' from data import series from execution.executor import Executor import random from math import inf import numpy from PyQt5.Qt import pyqtSignal, QObject from PyQt5 import QtCore import talib class Solver(QObject): ''' ''' progress = pyqtSignal(int, int, name='progress') done = pyqtSignal(list, name='done') def __init__(self, series): ''' Constructor ''' super().__init__(None) self.series = series self.executor = Executor(series) self.generators = [] def add_generator(self, generator): self.generators.append(generator) @QtCore.pyqtSlot(dict) def solve(self, params): max_signals = 5 max_strategies = params.get('num_strategies', 1000) results = [] min_trades = params.get('min_trades', 0) min_win_rate = params.get('min_win_rate', 0) min_sharpe = params.get('min_sharpe', 0) is_long = params.get('direction', 'long') == 'long' print(is_long) while len(results) < max_strategies: sig_num = random.randint(1, max_signals) strategy = [] for i in range(0, sig_num): strategy.append(random.choice(self.generators).generate()) trades = self.executor.execute(strategy, is_long) if len(trades) >= min_trades: result = self.evaluate_trades(trades) if result['win_percentage'] > min_win_rate and result['sharpe'] > min_sharpe: result['strategy'] = strategy result['display_name'] = ' && '.join([signal.get_text() for signal in strategy]) result['trades'] = trades results.append(result) self.progress.emit(len(results), max_strategies) self.done.emit(results) def evaluate_trades(self, trades): result = {} profits = [x.pnl() for x in trades] total_won = len(list(filter(lambda x: x.pnl() > 0, trades))) if len(trades) > 0: result['win_percentage'] = total_won / len(trades) * 100 else: result['win_percentage'] = 0 result['trades_number'] = len(trades) result['total_pnl'] = sum(profits) if len(trades) > 0: result['avg_percentage'] = sum([trade.pnl_percentage() for trade in trades]) / len(trades) else: result['avg_percentage'] = 0 gross_profit = sum([max(0, x.pnl()) for x in trades]) gross_loss = sum([min(0, x.pnl()) for x in trades]) if gross_loss != 0: result['profit_factor'] = gross_profit / (-gross_loss) else: result['profit_factor'] = inf if len(profits) > 0: mean = numpy.mean(profits) stddev = numpy.std(profits) if stddev != 0: result['sharpe'] = mean / stddev else: result['sharpe'] = 0 else: result['sharpe'] = 0 return result