Ejemplo n.º 1
0
 def update_prices(self, prices: List[dict]):
     instrument_service_prices = defaultdict(lambda: defaultdict(list))
     for price in prices:
         instrument_service_prices[price['instrument']][
             price['service']].append(price)
     signals = []  # type: List[dict]
     spreads = []  # type: List[dict]
     for instrument, service_prices in instrument_service_prices.items():
         service_pairs = sorted(itertools.permutations(
             service_prices.keys(), 2),
                                key=str)
         for b, a in service_pairs:
             bid_data, ask_data = service_prices[b][-1], service_prices[a][
                 -1]
             signaler = self.get_signaler(instrument, b, a)
             d = signaler.judge(bid_data=bid_data, ask_data=ask_data)
             if d:
                 spreads.append(d)  # minus spread
                 if d['signaled']:
                     d['signaler'] = signaler
                     d['bg'] = None
                     d['signaled_time'] = d['time'].strftime(
                         '%Y-%m-%d %H:%M:%S.%f%Z')
                     d['sp'] = '{:.2f}'.format(d['sp'])
                     signals.append(d)
     GlobalSignal().update_signals.emit(signals)
     GlobalSignal().update_spreads.emit(spreads)
Ejemplo n.º 2
0
 def update_prices():
     services = [
         'click', 'gaitame', 'lion', 'pfx', 'nano', 'sbi', 'try', 'yjfx',
         'noaccount'
     ]
     instruments = ('USD/JPY', 'EUR/JPY', 'GBP/JPY', 'AUD/JPY')
     prices = []
     accounts = []
     for service in services:
         positions = {}
         for i, instrument in enumerate(instruments):
             bid = 101 + i + random.random() * 0.8 / 100
             ask = 100 + i + random.random() * 0.2 / 100
             prices.append(
                 dict(time=timeutil.jst_now(),
                      service=service,
                      instrument=instrument,
                      bid=bid,
                      ask=ask))
             if services.index(service) < len(services) / 2:
                 positions[instrument] = random.randint(0, 3) * 1000
             else:
                 positions[instrument] = random.randint(0, 3) * -1000
         if service != 'noaccount':
             accounts += [new_account(service, positions=positions)]
     GlobalSignal().update_prices.emit(prices)
     GlobalSignal().update_accounts.emit(accounts)
Ejemplo n.º 3
0
 def __init__(self, *, spread_log: str = None, signal_log: str = None):
     super().__init__()
     self.spread_log = spread_log
     self.signal_log = signal_log
     if spread_log:
         GlobalSignal().update_spreads.connect(self.update_spreads)
     if signal_log:
         GlobalSignal().update_signals.connect(self.update_signals)
Ejemplo n.º 4
0
 def __init__(self, name: str):
     labels = ['E', 'service', 'time', 'equity', 'pl', 'margin', 'amount']
     super().__init__(labels=labels, name=name)
     self.instrument = ''
     self.cellClicked.connect(self.cell_clicked)
     GlobalSignal().update_accounts.connect(self.update_accounts)
     GlobalSignal().update_prices.connect(self.update_prices)
     self.services = set()
Ejemplo n.º 5
0
    def __init__(self, *, name: str):
        labels = ['signaled_time', 'instrument', 'bidder', 'asker', 'sp']
        super().__init__(labels=labels, name=name)
        self.signalers = {}
        self.signals = []

        GlobalSignal().update_prices.connect(self.update_prices)
        GlobalSignal().update_signals.connect(self.update_signals)
        GlobalSignal().update_filters.connect(self.refresh_log)
Ejemplo n.º 6
0
        def __init__(self, *args, name: str, **kwargs):
            labels = ('service', 'sell', 'buy', 'disabled')
            super().__init__(labels=labels, name=name)
            self.setContentsMargins(0, 0, 0, 0)
            self.verticalHeader().hide()
            self.instrument = ''

            font = self.horizontalHeader().font()
            # font.setPointSize(5)
            self.horizontalHeader().setFont(font)

            GlobalSignal().update_services.connect(self.update_services)
            GlobalSignal().update_filters.connect(self.update_filters)
            GlobalSignal().update_disabled_services.connect(self.update_disabled_services)
            self.cellClicked.connect(self.cell_clicked)
Ejemplo n.º 7
0
    def __init__(self, bind_address: Tuple[str, int]):
        super().__init__(name='appmaster', bind_address=bind_address)
        config = Config()

        self.window = AppWindow(name='appwindow')

        GlobalSignal().load_config.emit()
        GlobalSignal().call_lazy()

        self.window.show()
        self.pools = {}  # type: Dict[str, Pool]

        self.elapsed_list = []
        self.request_elapsed_list = []

        self.account_task = gevent.spawn(self.get_accounts)
Ejemplo n.º 8
0
    def __init__(self, *, name: str):
        super().__init__(name=name)
        config = self.config
        Config().instruments.clear()
        Config().services.clear()

        self.setContentsMargins(0, 0, 0, 0)
        w = QWidget()
        w.setContentsMargins(0, 0, 0, 0)

        splitter = Splitter(Qt.Vertical, name=name + '.splitter')
        splitter.setContentsMargins(0, 0, 0, 0)
        self.setCentralWidget(splitter)

        # filter view
        filter_view = FilterView(name=name + '.filter_view')
        splitter.addWidget(filter_view)

        # sound player
        player = SoundPlayer(name=name + '.sound_player')
        splitter.addWidget(player)

        # signal log view
        signal_log_view = SignalLogView(name=name + '.signal_log_view')
        # lo.addWidget(signal_log)
        splitter.addWidget(signal_log_view)

        # signal slot
        GlobalSignal().update_prices.connect(self.update_prices)

        # style sheet
        self.setStyleSheet('QSplitter::handle{background: white;}')
        return
Ejemplo n.º 9
0
 def update_signals(self, signals: List[dict]):
     filters = Config().filters
     selected = Config().selected_instruments
     disabled = Config().disabled_services
     for signal in signals:
         b, a = signal['bidder'], signal['asker']
         if signal['instrument'] not in selected or b in disabled or a in disabled:
             pass
         else:
             bidder_amount = get_amount(signal['bidder'], signal['instrument'])
             asker_amount = get_amount(signal['asker'], signal['instrument'])
             if bidder_amount > 0 and asker_amount < 0:
                 signal['bg'] = QBrush(Qt.green)
                 GlobalSignal().play_sound.emit('signal_close')
             else:
                 GlobalSignal().play_sound.emit('signal_open')
         self.signals.append(signal)
         self.refresh_log()
Ejemplo n.º 10
0
    def get_prices(self):
        now = timeutil.jst_now()

        def extend_prices(_pool: Pool):
            with _pool.connection() as client:
                l = client.get_prices() or []
            for x in l:
                x['time'] = now
            prices.extend(l)

        prices = []
        spawns = {
            key: gevent.spawn(lambda _pool: extend_prices(_pool), pool)
            for key, pool in random.sample(list(self.pools.items()),
                                           len(self.pools))
        }

        gevent.joinall(list(spawns.values()), timeout=1)
        is_timeout = False
        for key, spawn in spawns.items():
            if not spawn.successful():
                is_timeout = True
                try:
                    del self.pools[key]
                except KeyError:
                    pass
                try:
                    del self.registered[key[0]]
                except KeyError:
                    pass

        elapsed = timeutil.jst_now() - now
        self.request_elapsed_list.append(elapsed)
        if prices:
            GlobalSignal().update_prices.emit(prices)
        elapsed = timeutil.jst_now() - now
        self.elapsed_list.append(elapsed)
        N = 10
        if elapsed > timedelta() and len(self.elapsed_list) >= N:
            request_total = sum(
                map(lambda x: x.total_seconds(), self.request_elapsed_list))
            total = sum(map(lambda x: x.total_seconds(), self.elapsed_list))
            self.logger.info(
                '# elapsed:{:.3f}, request:{:.3f}({:.2f}%), 1loop: {:.3f}, request:{:.3f}'
                .format(total, request_total, request_total / total * 100,
                        total / N, request_total / N))
            self.elapsed_list = []
            self.request_elapsed_list = []
        if is_timeout:
            self.logger.warn('#timeout sleep(3)')
            gevent.sleep(3)
        else:
            gevent.sleep(
                max((timedelta(seconds=Config()['interval']) -
                     elapsed).total_seconds(), 0.05))
Ejemplo n.º 11
0
 def __init__(self, *, name: str):
     labels = ['bidder', 'bid', 'sp', 'ask', 'asker']
     super().__init__(labels=labels, name=name)
     self.setContentsMargins(0, 0, 0, 0)
     self.instrument = ''
     self.setHorizontalHeaderLabels([''] * len(self.labels))
     font = self.horizontalHeader().font()
     font.setPointSize(1)
     self.horizontalHeader().setFont(font)
     self.verticalHeader().hide()
     GlobalSignal().update_prices.connect(self.update_prices)
Ejemplo n.º 12
0
        def __init__(self, name: str):
            super().__init__(name=name)

            add_tab = QPushButton('+')
            add_tab.setMaximumWidth(24)
            self.setExpanding(False)
            self.addTab('')
            self.setTabButton(0, 1, add_tab)
            self.setTabsClosable(True)
            self.setMovable(True)
            add_tab.clicked.connect(self.add_tab)
            self.tabCloseRequested.connect(self.close_tab)
            GlobalSignal().update_spreads.connect(self.update_spreads)
Ejemplo n.º 13
0
    def get_accounts(self):
        import time
        next_refresh = time.time() + random.random() * 3600
        while True:
            # GlobalSignal().update_accounts.emit([])
            # gevent.sleep(10)
            # continue

            try:
                accounts = []

                do_refresh = self.do_refresh
                self.do_refresh = False

                def extend_accounts(_pool: Pool):
                    with _pool.connection() as client:
                        l = client.get_accounts() or []
                        if do_refresh:
                            client.refresh()
                    accounts.extend(l)

                spawns = {
                    key: gevent.spawn(lambda _pool: extend_accounts(_pool),
                                      pool)
                    for key, pool in random.sample(list(self.pools.items()),
                                                   len(self.pools))
                }

                gevent.joinall(list(spawns.values()), timeout=1)
                is_timeout = False
                for key, spawn in spawns.items():
                    if not spawn.successful():
                        is_timeout = True
                        try:
                            del self.pools[key]
                        except KeyError:
                            pass
                        try:
                            del self.registered[key[0]]
                        except KeyError:
                            pass
                if accounts:
                    GlobalSignal().update_accounts.emit(accounts)
            except Exception as e:
                self.logger.exception(str(e))
            gevent.sleep(1)
Ejemplo n.º 14
0
    def __init__(self, *, name: str):
        super().__init__(name=name)
        self.sounds = self.config.setdefault(
            'sounds', {
                'signal_open': {
                    'file': './signal_open.wav',
                    'loop': 1,
                },
                'signal_close': {
                    'file': './signal_close.wav',
                    'loop': 3,
                },
            })
        self.q_sounds = {}

        test_button = QPushButton('sound test')
        test_button.setContentsMargins(0, 0, 0, 0)
        mute = QCheckBox('Mute')
        mute.setChecked(self.config.setdefault('mute', False))
        check = QCheckBox('CloseOnly')
        check.setChecked(self.config.setdefault('close_only', False))

        def check_clicked_slot(key):
            @pyqtSlot(bool)
            def check_clicked(b):
                self.config[key] = b

            return check_clicked

        test_button.clicked.connect(
            lambda: self.play('signal_open')
            if not self.config['close_only'] else self.play('signal_close'))
        mute.clicked.connect(check_clicked_slot('mute'))
        check.clicked.connect(check_clicked_slot('close_only'))

        lo = QHBoxLayout()
        lo.setContentsMargins(0, 0, 0, 0)
        lo.addStretch()
        lo.addWidget(test_button)
        lo.addWidget(mute)
        lo.addWidget(check)
        self.setLayout(lo)
        GlobalSignal().play_sound.connect(self.play)
Ejemplo n.º 15
0
    def __init__(self, name, nodes):
        super().__init__(name, bind_address=nodes[name], nodes=nodes)
        self.config = Config()

        self.window = AppWindow(name='appwindow')

        GlobalSignal().load_config.emit()
        GlobalSignal().call_lazy()

        self.window.show()
        self.pools = {}  # type: Dict[str, Pool]

        self.elapsed_list = []
        self.request_elapsed_list = []

        self.do_reload = False
        self.do_refresh = False

        def on_reload():
            self.do_reload = True

        def on_refresh():
            def call():
                self.info('refresh start')
                for name, address in self._nodes.items():
                    if name == self.name:
                        continue
                    try:
                        self.info('refresh {}{}'.format(name, address))
                        self.rpc(address).refresh()
                    except Exception as e:
                        self.exception('refresh {}{} {}'.format(
                            name, address, str(e)))

            threading.Thread(target=call, daemon=True).start()
            self.do_refresh = True

        GlobalSignal().reload.connect(on_reload)
        GlobalSignal().refresh.connect(on_refresh)
        import time
        self._last_tick = time.time()
        self._accounts = {}
        self._setsock = False
        self.run_notify_nodes = lambda: None

        def write_csv(file_name: str, flush_interval: float):
            now = datetime.now().date()
            with open(file_name + now.strftime('_%Y%m%d'), 'a') as f:
                w = csv.writer(f)
                flush_at = time.time()
                while True:
                    d = yield
                    if d:
                        keys = [
                            'time', 'instrument', 'bidder', 'asker', 'bid',
                            'ask', 'sp'
                        ]
                        d = dict(**d)
                        instrument = d['instrument']
                        d['time'] = d['time'].astimezone(timeutil.TOKYO)
                        d['bid'] = get_float_format(instrument).format(
                            d['bid'])
                        d['ask'] = get_float_format(instrument).format(
                            d['ask'])
                        if isinstance(d['sp'], float):
                            d['sp'] = '{:.2f}'.format(d['sp'])
                        values = [d[k] for k in keys]
                        w.writerow(values)
                    if time.time() - flush_at >= flush_interval:
                        f.flush()
                        flush_at = time.time()

        self.csv_writer = write_csv('./spread_log.csv', 10.0)
        self.csv_writer.send(None)
        self.last_spread_at = timeutil.jst_now()
Ejemplo n.º 16
0
 def closeEvent(self, e: QCloseEvent):
     GlobalSignal().dump_config.emit()
     config = Config()
     if config['auto_save']:
         yamlutil.save_yaml(dict(config), config['config_file'])
     e.accept()
Ejemplo n.º 17
0
    def handle_udp(self, data, address: Tuple[str, int]):
        if not self._setsock:
            modify_buf_size(self._udp_server._socket, 0x10000, 1024**2 * 4)
            self._setsock = True
        assert isinstance(data, dict), '{}'.format(data)
        self.handle(**data)

        now = datetime.utcnow().replace(tzinfo=pytz.utc)
        minus_spreads = []
        for (bidder, asker), instrument_spreads in self.spreads.items():
            for instrument, spreads in instrument_spreads.items():
                if spreads[-1].time > self.last_spread_at and get_pip_scale(
                        spreads[-1].instrument) * (-spreads[-1].sp) < -0.25:
                    minus_spreads.append(spreads[-1])
        self.last_spread_at = now
        for s in minus_spreads:
            d = dict(bidder=s.pair[0],
                     asker=s.pair[1],
                     instrument=s.instrument,
                     time=s.time,
                     bid=s.bid,
                     ask=s.ask,
                     sp=get_pip_scale(s.instrument) * (-s.sp))
            self.csv_writer.send(d)

        import time
        if time.time() - self._last_tick <= self.config['interval']:
            return
        self._last_tick = time.time()

        if not minus_spreads:
            self.csv_writer.send(None)

        if 'accounts' in data:
            accounts = [
                account.to_dict() for account in self.accounts.values()
            ]
            for account in accounts:
                account['service'] = account['name']
                account['pl'] = account['profit_loss']
                account[
                    'available'] = account['equity'] - account['used_margin']
                account['margin_ratio'] = (
                    account['equity'] / account['used_margin']
                ) * 100 if account['used_margin'] > 0 else 0
            for account in accounts:
                self._accounts[account['name']] = account
            GlobalSignal().update_accounts.emit(list(self._accounts.values()))

        if 'prices' in data:
            _prices = []
            for service, instrument_prices in self.prices.items():
                for instrument, prices in instrument_prices.items():
                    if len(prices) > 0:
                        _prices.append(prices[-1].to_dict())
            [price.update(service=price['name']) for price in _prices]
            _prices = list(
                filter(lambda x: (now - x['time']).total_seconds() < 5,
                       _prices))
            #
            #             print('#prices')
            GlobalSignal().update_prices.emit(_prices)
Ejemplo n.º 18
0
    def __init__(self, *, name: str):
        super().__init__(name=name)
        config = self.config
        Config().instruments.clear()
        Config().services.clear()

        self.setContentsMargins(0, 0, 0, 0)
        w = QWidget()
        w.setContentsMargins(0, 0, 0, 0)

        splitter = Splitter(Qt.Vertical, name=name + '.splitter')
        splitter.setContentsMargins(0, 0, 0, 0)
        self.setCentralWidget(splitter)

        # filter view
        for i in range(4):
            filter_view = FilterView(name=name + '.filter_view_{}'.format(i))
            splitter.addWidget(filter_view)

        # accounts view
        accounts_view = AccountsView(name=name + '.accounts_view')
        splitter.addWidget(accounts_view)

        w = QWidget()
        splitter.addWidget(w)

        # spread intrval
        def update_interval(value: float):
            Config()['interval'] = value

        spread_interval = DoubleSpinBox(name='spread_interval',
                                        value=0.5,
                                        min=0.01,
                                        max=3.0,
                                        decimals=2,
                                        single_step=0.01)
        spread_interval.valueChanged.connect(update_interval)

        # bank view
        bank = DoubleSpinBox(name='tobank',
                             value=0.0,
                             min=-10000000,
                             max=10000000,
                             decimals=0,
                             single_step=1000)
        bank.valueChanged.connect(accounts_view.update_bank)

        # refresh button
        refresh_button = QPushButton('Refresh')
        refresh_button.clicked.connect(lambda: GlobalSignal().refresh.emit())

        lo = QHBoxLayout()
        lo.setContentsMargins(0, 0, 0, 0)
        lo.addWidget(refresh_button)
        lo.addWidget(bank)
        lo.addWidget(spread_interval)
        w.setLayout(lo)

        # sound player
        player = SoundPlayer(name=name + '.sound_player')
        # splitter.addWidget(player)
        lo.addWidget(player)

        # signal log view
        signal_log_view = SignalLogView(name=name + '.signal_log_view')
        # lo.addWidget(signal_log)
        splitter.addWidget(signal_log_view)

        # signal slot
        GlobalSignal().update_prices.connect(self.update_prices)

        # style sheet
        self.setStyleSheet('QSplitter::handle{background: white;}')
        return
Ejemplo n.º 19
0
 def __init__(self, service: str = '', *, name: str):
     super().__init__(name=name)
     self.addItem(service)
     self.setCurrentText(service)
     GlobalSignal().update_services.connect(self.update_services)
Ejemplo n.º 20
0
 def __init__(self):
     if not self._initialized:
         super().__init__()
         self._dict = dict()
         self._signals = GlobalSignal()
         self._initialized = True
Ejemplo n.º 21
0
 def __init__(self, *args, name, **kwargs):
     super().__init__(*args, **kwargs)
     self.name = name
     if name:
         GlobalSignal().dump_config.connect(self.dump_config)
         GlobalSignal().load_config.connect(self.load_config)
Ejemplo n.º 22
0
 def __init__(self, instrument: str = '', *, name: str):
     super().__init__(name=name)
     self.addItem(instrument)
     self.setCurrentText(instrument)
     self.update_instruments(Config().instruments)
     GlobalSignal().update_instruments.connect(self.update_instruments)