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.
 

104 lines
3.1 KiB

'''
'''
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