Browse Source

More signals

master
Denis Tereshkin 8 years ago
parent
commit
3812d99022
  1. 200
      data/signal.py
  2. 5
      ui/mainwindow.py

200
data/signal.py

@ -5,6 +5,7 @@ import random
import numpy import numpy
import talib import talib
from scipy.integrate.tests.test_odeint_jac import rhs
class Signal: class Signal:
@ -33,6 +34,9 @@ class PriceComparisonSignalGenerator:
rhs_shift = random.randint(0, 10) rhs_shift = random.randint(0, 10)
return PriceComparisonSignal(lhs, lhs_shift, rhs, rhs_shift) return PriceComparisonSignal(lhs, lhs_shift, rhs, rhs_shift)
def id(self):
return 'Price'
class PriceComparisonSignal(Signal): class PriceComparisonSignal(Signal):
OPEN = 0 OPEN = 0
@ -121,6 +125,9 @@ class RsiSignalGenerator:
threshold = random.randrange(1, 9) * 10 threshold = random.randrange(1, 9) * 10
ineq_type = random.randint(RsiSignal.LT, RsiSignal.GT) ineq_type = random.randint(RsiSignal.LT, RsiSignal.GT)
return RsiSignal(period, threshold, ineq_type, shift) return RsiSignal(period, threshold, ineq_type, shift)
def id(self):
return 'RSI'
class RsiSignal(Signal): class RsiSignal(Signal):
@ -176,6 +183,9 @@ class AtrSignalGenerator:
threshold = random.randint(1, 30) * 0.001 threshold = random.randint(1, 30) * 0.001
ineq_type = random.randint(AtrSignal.LT, AtrSignal.GT) ineq_type = random.randint(AtrSignal.LT, AtrSignal.GT)
return AtrSignal(period, threshold, ineq_type) return AtrSignal(period, threshold, ineq_type)
def id(self):
return 'ATR'
class AtrSignal(Signal): class AtrSignal(Signal):
@ -230,6 +240,9 @@ class AtrDeltaSignalGenerator:
ineq_type = random.randint(AtrDeltaSignal.LT, AtrDeltaSignal.GT) ineq_type = random.randint(AtrDeltaSignal.LT, AtrDeltaSignal.GT)
sign = random.randint(AtrDeltaSignal.PLUS, AtrDeltaSignal.MINUS) sign = random.randint(AtrDeltaSignal.PLUS, AtrDeltaSignal.MINUS)
return AtrDeltaSignal(period, threshold, ineq_type, sign) return AtrDeltaSignal(period, threshold, ineq_type, sign)
def id(self):
return 'ATR Delta'
class AtrDeltaSignal(Signal): class AtrDeltaSignal(Signal):
@ -301,6 +314,9 @@ class DayOfWeekSignalGenerator:
def generate(self): def generate(self):
dow = random.randint(0, 6) dow = random.randint(0, 6)
return DayOfWeekSignal(dow) return DayOfWeekSignal(dow)
def id(self):
return 'Day of week'
class DayOfWeekSignal(Signal): class DayOfWeekSignal(Signal):
@ -334,7 +350,9 @@ class DayOfMonthSignalGenerator:
month_day = random.randint(1, 31) month_day = random.randint(1, 31)
ineq_type = random.randint(DayOfMonthSignal.LT, DayOfMonthSignal.GT) ineq_type = random.randint(DayOfMonthSignal.LT, DayOfMonthSignal.GT)
return DayOfMonthSignal(month_day, ineq_type) return DayOfMonthSignal(month_day, ineq_type)
def id(self):
return 'Day of Month'
class DayOfMonthSignal(Signal): class DayOfMonthSignal(Signal):
@ -377,6 +395,9 @@ class CrtdrSignalGenerator:
threshold = 0.05 * random.randint(1, 19) threshold = 0.05 * random.randint(1, 19)
return CrtdrSignal(shift, threshold, ineq_type) return CrtdrSignal(shift, threshold, ineq_type)
def id(self):
return 'CRTDR'
class CrtdrSignal(Signal): class CrtdrSignal(Signal):
LT = 0 LT = 0
@ -435,6 +456,9 @@ class SmaSignalGenerator:
rhs = random.randint(SmaSignal.OPEN, SmaSignal.CLOSE) rhs = random.randint(SmaSignal.OPEN, SmaSignal.CLOSE)
ineq_sign = random.randint(SmaSignal.LT, SmaSignal.GT) ineq_sign = random.randint(SmaSignal.LT, SmaSignal.GT)
return SmaSignal(period, lhs, rhs, ineq_sign) return SmaSignal(period, lhs, rhs, ineq_sign)
def id(self):
return 'SMA'
class SmaSignal(Signal): class SmaSignal(Signal):
@ -513,6 +537,9 @@ class CciSignalGenerator:
threshold = random.randint(1, 30) * 10 threshold = random.randint(1, 30) * 10
ineq_type = random.randint(CciSignal.LT, CciSignal.GT) ineq_type = random.randint(CciSignal.LT, CciSignal.GT)
return CciSignal(shift, period, threshold, ineq_type) return CciSignal(shift, period, threshold, ineq_type)
def id(self):
return 'CCI'
class CciSignal(Signal): class CciSignal(Signal):
@ -574,6 +601,9 @@ class BbandsSignalGenerator:
dev = random.randint(1, 6) * 0.5 dev = random.randint(1, 6) * 0.5
band_type = random.randint(BbandsSignal.UP, BbandsSignal.DOWN) band_type = random.randint(BbandsSignal.UP, BbandsSignal.DOWN)
return BbandsSignal(period, lhs, rhs, dev, ineq_sign, band_type) return BbandsSignal(period, lhs, rhs, dev, ineq_sign, band_type)
def id(self):
return 'Bollinger bands'
class BbandsSignal(Signal): class BbandsSignal(Signal):
@ -657,5 +687,169 @@ class BbandsSignal(Signal):
elif component == BbandsSignal.CLOSE: elif component == BbandsSignal.CLOSE:
return "close" return "close"
else: else:
return "??" return "??"
class PivotPointsSignalGenerator:
def __init__(self):
pass
def generate(self):
lhs = random.randint(PivotPointsSignal.OPEN, PivotPointsSignal.R3)
lhs_shift = random.randint(0, 10)
rhs = random.randint(PivotPointsSignal.OPEN, PivotPointsSignal.R3)
rhs_shift = random.randint(0, 10)
return PivotPointsSignal(lhs, lhs_shift, rhs, rhs_shift)
def id(self):
return 'Pivot points'
class PivotPointsSignal(Signal):
OPEN = 0
HIGH = 1
LOW = 2
CLOSE = 3
PP = 4
S1 = 5
S2 = 6
S3 = 7
R1 = 8
R2 = 9
R3 = 10
def __init__(self, lhs, lhs_shift, rhs, rhs_shift):
self.lhs = lhs
self.lhs_shift = lhs_shift
self.rhs = rhs
self.rhs_shift = rhs_shift
def calculate(self, series):
result = []
for i in range(0, series.length()):
lhs = self.calculate_signal(series, self.lhs, i - self.lhs_shift)
rhs = self.calculate_signal(series, self.rhs, i - self.rhs_shift)
if i - self.lhs_shift >= 0 and i - self.rhs_shift >= 0:
result.append(lhs < rhs)
else:
result.append(False)
return result
def calculate_signal(self, series, signal_type, ix):
if signal_type == PivotPointsSignal.OPEN:
return series.get_open(ix)
elif signal_type == PivotPointsSignal.HIGH:
return series.get_high(ix)
elif signal_type == PivotPointsSignal.LOW:
return series.get_low(ix)
elif signal_type == PivotPointsSignal.CLOSE:
return series.get_close(ix)
elif signal_type == PivotPointsSignal.PP:
return (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
elif signal_type == PivotPointsSignal.S1:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp * 2 - series.get_high(ix)
elif signal_type == PivotPointsSignal.S2:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp - series.get_high(ix) + series.get_low(ix)
elif signal_type == PivotPointsSignal.S3:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp - 2 * series.get_high(ix) + 2 * series.get_low(ix)
elif signal_type == PivotPointsSignal.R1:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp * 2 - series.get_low(ix)
elif signal_type == PivotPointsSignal.R2:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp + series.get_high(ix) - series.get_low(ix)
elif signal_type == PivotPointsSignal.R3:
pp = (series.get_close(ix) + series.get_high(ix) + series.get_low(ix)) / 3
return pp + 2 * series.get_high(ix) - 2 * series.get_low(ix)
def get_text(self):
return "{:s}[{:d}] < {:s}[{:d}]".format(self.component_str(self.lhs), self.lhs_shift, self.component_str(self.rhs), self.rhs_shift)
def component_str(self, comp_id):
if comp_id == PivotPointsSignal.OPEN:
return "open"
elif comp_id == PivotPointsSignal.HIGH:
return "high"
elif comp_id == PivotPointsSignal.LOW:
return "low"
elif comp_id == PivotPointsSignal.CLOSE:
return "close"
elif comp_id == PivotPointsSignal.PP:
return "pivot"
elif comp_id == PivotPointsSignal.S1:
return "s1"
elif comp_id == PivotPointsSignal.S2:
return "s2"
elif comp_id == PivotPointsSignal.S3:
return "s3"
elif comp_id == PivotPointsSignal.R1:
return "r1"
elif comp_id == PivotPointsSignal.R2:
return "r2"
elif comp_id == PivotPointsSignal.R3:
return "r3"
class StochasticSignalGenerator:
def __init__(self):
pass
def generate(self):
shift = random.randint(0, 3)
period = random.randint(2, 30)
period2 = random.randint(2, 30)
threshold = random.randrange(1, 9) * 10
ineq_type = random.randint(StochasticSignal.LT, StochasticSignal.GT)
return StochasticSignal(period, period2, threshold, ineq_type, shift)
def id(self):
return 'Stochastic'
class StochasticSignal(Signal):
LT = 0
GT = 1
def __init__(self, period, period2, threshold, inequality_type, shift):
self.period = period
self.period2 = period2
self.threshold = threshold
self.inequality_type = inequality_type
self.shift = shift
if inequality_type == StochasticSignal.LT:
self.inequality_sign_str = '<'
else:
self.inequality_sign_str = '>'
def calculate(self, series):
closes = numpy.array([series.get_close(i) for i in range(0, series.length())])
highs = numpy.array([series.get_high(i) for i in range(0, series.length())])
lows = numpy.array([series.get_low(i) for i in range(0, series.length())])
stoch_k, stoch_d = talib.STOCHF(highs, lows, closes, self.period, self.period2)
result = [self.calc_signal(v) for v in stoch_k]
if self.shift == 0:
return result
else:
return [False] * self.shift + result[:-self.shift]
def calc_signal(self, value):
if self.inequality_type == StochasticSignal.LT:
return value < self.threshold
else:
return value > self.threshold
def get_text(self):
return "stoch(c, {:d})[{:d}] {:s} {:d}".format(self.period, self.shift, self.inequality_sign_str, int(self.threshold))

5
ui/mainwindow.py

@ -9,7 +9,8 @@ from data.series import Series
from data.signal import PriceComparisonSignalGenerator, RsiSignalGenerator,\ from data.signal import PriceComparisonSignalGenerator, RsiSignalGenerator,\
AtrSignalGenerator, DayOfWeekSignalGenerator, CrtdrSignalGenerator,\ AtrSignalGenerator, DayOfWeekSignalGenerator, CrtdrSignalGenerator,\
AtrDeltaSignalGenerator, SmaSignalGenerator, DayOfMonthSignalGenerator,\ AtrDeltaSignalGenerator, SmaSignalGenerator, DayOfMonthSignalGenerator,\
CciSignalGenerator, BbandsSignalGenerator CciSignalGenerator, BbandsSignalGenerator, PivotPointsSignalGenerator,\
StochasticSignalGenerator
from PyQt5.Qt import Qt, QFileDialog, QThread, Q_ARG, QMetaObject from PyQt5.Qt import Qt, QFileDialog, QThread, Q_ARG, QMetaObject
import pyqtgraph import pyqtgraph
@ -48,6 +49,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.solver.add_generator(CrtdrSignalGenerator()) self.solver.add_generator(CrtdrSignalGenerator())
self.solver.add_generator(CciSignalGenerator()) self.solver.add_generator(CciSignalGenerator())
self.solver.add_generator(BbandsSignalGenerator()) self.solver.add_generator(BbandsSignalGenerator())
self.solver.add_generator(PivotPointsSignalGenerator())
self.solver.add_generator(StochasticSignalGenerator())
params = { 'num_strategies' : self.sb_strategiesNum.value() } params = { 'num_strategies' : self.sb_strategiesNum.value() }
if self.cb_minTradesFilter.isChecked(): if self.cb_minTradesFilter.isChecked():

Loading…
Cancel
Save