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

8 years ago
'''
'''
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
8 years ago
class Solver(QObject):
8 years ago
'''
'''
progress = pyqtSignal(int, int, name='progress')
done = pyqtSignal(list, name='done')
8 years ago
def __init__(self, series):
'''
Constructor
'''
super().__init__(None)
8 years ago
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 = []
8 years ago
min_trades = params.get('min_trades', 0)
min_win_rate = params.get('min_win_rate', 0)
min_sharpe = params.get('min_sharpe', 0)
8 years ago
is_long = params.get('direction', 'long') == 'long'
print(is_long)
while len(results) < max_strategies:
8 years ago
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)
8 years ago
self.done.emit(results)
8 years ago
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
8 years ago
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