Пример #1
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    network = scheduler.get_network()
    values = Interval(scheduler)
    Do(network, values, lambda: print(f"input values: {values.get_value()}"))

    window = WindowWithCount(network, values, count=5)
    Do(network, window, lambda: print(f"window values: {window.get_value()}"))
Пример #2
0
    def init(self, ctx: StrategyContext):
        self.ctx = ctx

        big_print_qty = float(ctx.getenv('BIG_PRINT_QTY'))
        self.trade_qty = float(ctx.getenv('CONTRACT_TRADE_QTY'))

        api_key = ctx.getenv('PHEMEX_API_KEY')
        api_secret = ctx.getenv('PHEMEX_API_SECRET')
        if not api_key:
            raise ValueError('missing PHEMEX_API_KEY')
        if not api_secret:
            raise ValueError('missing PHEMEX_API_SECRET')

        credentials = AuthCredentials(api_key, api_secret)

        exchange_instance = ctx.getenv('PHEMEX_INSTANCE', 'prod')
        if exchange_instance == 'prod':
            self.trading_conn = PhemexConnection(credentials)
        elif exchange_instance == 'test':
            self.trading_conn = PhemexConnection(
                credentials, api_url='https://testnet-api.phemex.com')
        else:
            raise ValueError(
                f'Unknown PHEMEX_INSTANCE value: {exchange_instance}')

        self.logger.info(f'Connected to Phemex {exchange_instance} instance')

        self.spot_feed = ctx.fh_registry.get_feed(
            f'coinbasepro:{exchange_instance}:BTC-USD')
        self.futures_feed = ctx.fh_registry.get_feed(
            f'phemex:{exchange_instance}:BTCUSD')

        self.logger.info(
            f'Connected to spot & futures {exchange_instance} feeds')

        network = self.ctx.get_network()

        # scan the spot market for large trades
        spot_trades = self.spot_feed.get_trades()
        Do(
            network, spot_trades, lambda: self.logger.info(
                f'Spot market trade: {spot_trades.get_value()}'))
        self.big_prints = Filter(network, spot_trades,
                                 lambda x: x.get_qty() >= big_print_qty)

        # compute 5 minute bins for the futures market and extract the volume field
        self.futures_trades = self.futures_feed.get_trades()
        buffer_5min = BufferWithTime(network, self.futures_trades,
                                     timedelta(minutes=5))
        self.ohlc_5min = ComputeOHLC(network, buffer_5min)
        Do(
            network, self.ohlc_5min, lambda: self.logger.info(
                f'OHLC[5min]: {self.ohlc_5min.get_value()}'))
        self.volume = Map(network, self.ohlc_5min, lambda x: x.volume)

        # track the exponentially weighted moving average of the futures volume
        self.ewma = ExponentialMovingAverage(network, self.volume)
Пример #3
0
    def __init__(self, config: BacktestConfig):
        logger = logging.getLogger(__name__)
        logger.info('Serenity backtester starting up')

        sys.path.append(str(config.get_strategy_basedir()))

        bt_env = config.get_env()

        exchange_id = bt_env.getenv('EXCHANGE_ID', 'autofill')
        instance_id = bt_env.getenv('EXCHANGE_INSTANCE', 'prod')
        account = bt_env.getenv('EXCHANGE_ACCOUNT', 'Main')

        self.logger.info('Connecting to Serenity database')
        conn = connect_serenity_db()
        conn.autocommit = True
        cur = conn.cursor()

        self.scheduler = HistoricNetworkScheduler(
            config.get_start_time_millis(), config.get_end_time_millis())
        instrument_cache = InstrumentCache(cur, TypeCodeCache(cur))

        oms = OrderManagerService(self.scheduler)

        md_service = AzureHistoricMarketdataService(
            self.scheduler, bt_env.getenv('AZURE_CONNECT_STR'))
        mark_service = MarketdataMarkService(self.scheduler.get_network(),
                                             md_service)
        op_service = OrderPlacerService(self.scheduler, oms)
        op_service.register_order_placer(
            f'{exchange_id}:{instance_id}',
            AutoFillOrderPlacer(self.scheduler, oms, md_service, account))

        xps = NullExchangePositionService(self.scheduler)

        extra_outputs_txt = bt_env.getenv('EXTRA_OUTPUTS')
        if extra_outputs_txt is None:
            extra_outputs = []
        else:
            extra_outputs = extra_outputs_txt.split(',')
        self.dcs = HDF5DataCaptureService(Mode.BACKTEST, self.scheduler,
                                          extra_outputs)

        # wire up orders and fills from OMS
        Do(self.scheduler.get_network(), oms.get_orders(),
           lambda: self.dcs.capture_order(oms.get_orders().get_value()))
        Do(self.scheduler.get_network(), oms.get_order_events(),
           lambda: self.dcs.capture_fill(oms.get_order_events().get_value()))

        self.strategy_name = config.get_strategy_name()
        strategy_env = config.get_strategy_env()
        ctx = StrategyContext(self.scheduler, instrument_cache, md_service,
                              mark_service, op_service,
                              PositionService(self.scheduler, oms), xps,
                              self.dcs, strategy_env.values)
        strategy_instance = config.get_strategy_instance()
        strategy_instance.init(ctx)
        strategy_instance.start()
Пример #4
0
    def init(self, ctx: StrategyContext):
        self.ctx = ctx

        account = ctx.getenv('EXCHANGE_ACCOUNT')
        if account is None:
            raise ValueError('Missing EXCHANGE_ACCOUNT')

        exchange_code, peg_symbol = ctx.getenv('PEG_INSTRUMENT').split(':')
        self.peg_instrument = ctx.get_instrument_cache(
        ).get_crypto_exchange_instrument(exchange_code, peg_symbol)

        peg_type = ctx.getenv('PEG_TYPE', 'Near')
        if peg_type == 'Near':
            self.peg_type = PegType.NEAR

        peg_side = ctx.getenv('PEG_SIDE')
        if peg_side == 'Buy':
            self.peg_side = Side.BUY
        elif peg_side == 'Sell':
            self.peg_side = Side.SELL
        else:
            raise ValueError(f'Unknown or missing PegSide: {peg_side}')

        self.peg_qty = ctx.getenv('PEG_QTY', 1)

        exchange_id = ctx.getenv('EXCHANGE_ID', 'phemex')
        exchange_instance = ctx.getenv('EXCHANGE_INSTANCE', 'prod')
        op_uri = f'{exchange_id}:{exchange_instance}'
        self.order_placer = ctx.get_order_placer_service().get_order_placer(
            op_uri)

        self.logger.info(f'Connected to Phemex {exchange_instance} instance')

        # subscribe to top of book
        self.peg_book = self.ctx.get_marketdata_service().get_order_books(
            self.peg_instrument)

        # subscribe to position updates and exchange position updates
        position = self.ctx.get_position_service().get_position(
            account, self.peg_instrument)
        Do(ctx.get_scheduler().get_network(), position,
           lambda: self.logger.info(position.get_value()))

        exch_position = self.ctx.get_exchange_position_service(
        ).get_exchange_positions()
        Do(ctx.get_scheduler().get_network(), exch_position,
           lambda: self.logger.info(exch_position.get_value()))

        # subscribe to order events from the OMS, and log them
        order_events = self.ctx.get_order_placer_service(
        ).get_order_manager_service().get_order_events()
        Do(ctx.get_scheduler().get_network(), order_events,
           lambda: self.logger.info(order_events.get_value()))
Пример #5
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    network = scheduler.get_network()
    values = Interval(scheduler)
    Do(network, values, lambda: print(f"input values: {values.get_value()}"))

    buffer1 = BufferWithCount(network, values, count=2)
    Do(network, buffer1,
       lambda: print(f"buffer1 values: {buffer1.get_value()}"))

    buffer2 = BufferWithTime(scheduler, values, timedelta(seconds=5))
    Do(network, buffer2,
       lambda: print(f"buffer2 values: {buffer2.get_value()}"))
Пример #6
0
    def init(self, ctx: StrategyContext):
        self.ctx = ctx

        big_print_qty = float(ctx.getenv('BIG_PRINT_QTY'))
        self.trade_qty = float(ctx.getenv('CONTRACT_TRADE_QTY'))

        exchange_instance = ctx.getenv('EXCHANGE_INSTANCE', 'prod')
        op_uri = f'phemex:{exchange_instance}'
        self.order_placer = ctx.get_order_placer_service().get_order_placer(
            op_uri)

        self.logger.info(f'Connected to Phemex {exchange_instance} instance')

        network = self.ctx.get_network()

        # scan the spot market for large trades
        btc_usd_spot = self.ctx.get_instrument_cache(
        ).get_crypto_exchange_instrument('CoinbasePro', 'BTC-USD')
        spot_trades = self.ctx.get_marketdata_service().get_trades(
            btc_usd_spot)
        Do(
            network, spot_trades, lambda: self.logger.info(
                f'Spot market trade: {spot_trades.get_value()}'))
        self.big_prints = Filter(network, spot_trades,
                                 lambda x: x.get_qty() >= big_print_qty)

        # compute 5 minute bins for the futures market and extract the volume field
        btc_usd_future = self.ctx.get_instrument_cache(
        ).get_crypto_exchange_instrument('Phemex', 'BTCUSD')
        self.futures_trades = self.ctx.get_marketdata_service().get_trades(
            btc_usd_future)
        buffer_5min = BufferWithTime(self.ctx.get_scheduler(),
                                     self.futures_trades, timedelta(minutes=5))
        self.ohlc_5min = ComputeOHLC(network, buffer_5min)
        Do(
            network, self.ohlc_5min, lambda: self.logger.info(
                f'OHLC[5min]: {self.ohlc_5min.get_value()}'))
        self.volume = Map(network, self.ohlc_5min, lambda x: x.volume)

        # subscribe to top of book
        self.futures_book = self.ctx.get_marketdata_service().get_order_books(
            btc_usd_future)
        Do(
            network, self.futures_book, lambda: self.logger.info(
                f'Futures bid/ask: '
                f'{self.futures_book.get_value().get_best_bid()} / '
                f'{self.futures_book.get_value().get_best_ask()}'))

        # track the exponentially weighted moving average of the futures volume
        self.ewma = ExponentialMovingAverage(network, self.volume)
Пример #7
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    network = scheduler.get_network()
    values = From(scheduler, [0.0, 3.2, 2.1, 2.9, 8.3, 5.7])
    mapper = Map(network, values, lambda x: round(x))
    accumulator = Scan(network, mapper)
    Do(network, accumulator, lambda: print(f"{accumulator.get_value()}"))
Пример #8
0
def test_filter():
    scheduler = HistoricNetworkScheduler(0, 30 * 1000)
    network = scheduler.get_network()
    values = From(scheduler, [0.0, -3.2, 2.1, -2.9, 8.3, -5.7])
    filt = Filter(network, values, lambda x: x >= 0.0)
    Do(network, filt, lambda: print(f'{filt.get_value()}'))
    scheduler.run()
    assert filt.get_value() == 8.3
Пример #9
0
def test_map_reduce():
    scheduler = HistoricNetworkScheduler(0, 30 * 1000)
    network = scheduler.get_network()
    values = From(scheduler, [0.0, 3.2, 2.1, 2.9, 8.3, 5.7])
    mapper = Map(network, values, lambda x: round(x))
    accumulator = Scan(network, mapper)
    Do(network, accumulator, lambda: print(f'{accumulator.get_value()}'))
    scheduler.run()
    assert accumulator.get_value() == 22.0
Пример #10
0
                def on_activate(self) -> bool:
                    if fh.get_state().get_value() == FeedHandlerState.LIVE:
                        feed = registry.get_feed(f'{uri_scheme}:{instance_id}:{self.trade_symbol}')
                        instrument_code = feed.get_instrument().get_exchange_instrument_code()
                        journal = Journal(Path(f'{journal_path}/{db}_BOOKS/{instrument_code}'))
                        self.appender = journal.create_appender()

                        books = feed.get_order_books()
                        Do(scheduler.get_network(), books, lambda: self.on_book_update(books.get_value()))
                    return False
Пример #11
0
def test_repeating_timer():
    # run for one minute
    scheduler = HistoricNetworkScheduler(0, 60 * 1000)

    tz = pytz.timezone('US/Eastern')
    timer = RepeatingTimer(scheduler, datetime.timedelta(seconds=15))
    timestamps = list()
    Do(scheduler.get_network(), timer,
       lambda: timestamps.append(scheduler.get_clock().get_time(tz)))
    scheduler.run()
    assert len(timestamps) == 4
    assert str(timestamps[3]) == '1969-12-31 19:01:00-05:00'
Пример #12
0
def test_alarm():
    # run for one day
    scheduler = HistoricNetworkScheduler(0, 60 * 60 * 24 * 1000)

    # schedule at 4pm US/Eastern
    tz = pytz.timezone('US/Eastern')
    alarm = Alarm(scheduler, datetime.time(16, 00, 00), tz)
    timestamps = list()
    Do(scheduler.get_network(), alarm,
       lambda: timestamps.append(scheduler.get_clock().get_time(tz)))
    scheduler.run()
    assert len(timestamps) == 1
Пример #13
0
            def on_activate(self) -> bool:
                if fh.get_state().get_value() == FeedHandlerState.LIVE:
                    feed = registry.get_feed(
                        f'{uri_scheme}:{instance_id}:{self.trade_symbol}')
                    instrument_code = feed.get_instrument(
                    ).get_exchange_instrument_code()
                    txlog = TransactionLog(
                        Path(f'{journal_path}/{db}_TRADES/{instrument_code}'))
                    self.tx_writer = txlog.create_writer()

                    trades = feed.get_trades()
                    Do(scheduler.get_network(), trades,
                       lambda: self.on_trade_print(trades.get_value()))
                return False
Пример #14
0
def test_buffer_with_time_historic():
    scheduler = HistoricNetworkScheduler(0, 30 * 1000)
    network = scheduler.get_network()
    values = MutableSignal()
    scheduler.schedule_update_at(values, 1.0, 1000)
    scheduler.schedule_update_at(values, -3.2, 2000)
    scheduler.schedule_update_at(values, 2.1, 10000)
    scheduler.schedule_update_at(values, -2.9, 15000)
    scheduler.schedule_update_at(values, 8.3, 25000)
    scheduler.schedule_update_at(values, -5.7, 30000)

    buffer = BufferWithTime(scheduler, values, timedelta(seconds=5))
    Do(network, buffer, lambda: print(f'{buffer.get_value()}'))
    scheduler.run()
Пример #15
0
def test_oms_cancel_not_pending(mocker: MockFixture):
    scheduler = HistoricNetworkScheduler(0, 1000)
    oms = OrderManagerService(scheduler)
    order_events = []
    Do(scheduler.get_network(), oms.get_order_events(),
       lambda: order_events.append(oms.get_order_events().get_value()))
    instrument = mocker.MagicMock(ExchangeInstrument)
    order = MarketOrder(10, instrument, Side.BUY, 'Main')
    order.set_order_id(str(uuid1()))
    oms.pending_new(order)
    oms.new(order, str(uuid1()))
    oms.apply_cancel(order, str(uuid1()))
    scheduler.run()
    assert (isinstance(order_events[2], CancelReject))
    assert (order_events[2].get_message() ==
            'Attempt to apply cancel when not pending')
Пример #16
0
def test_oms_late_fill(mocker: MockFixture):
    scheduler = HistoricNetworkScheduler(0, 1000)
    oms = OrderManagerService(scheduler)
    order_events = []
    Do(scheduler.get_network(), oms.get_order_events(),
       lambda: order_events.append(oms.get_order_events().get_value()))
    instrument = mocker.MagicMock(ExchangeInstrument)
    order = MarketOrder(10, instrument, Side.BUY, 'Main')
    order.set_order_id(str(uuid1()))
    oms.pending_new(order)
    oms.new(order, str(uuid1()))
    oms.pending_cancel(order)
    oms.apply_cancel(order, str(uuid1()))
    oms.apply_fill(order, 1, 10_000, str(uuid1()))
    scheduler.run()
    assert (isinstance(order_events[4], Reject))
    assert (order_events[4].get_message() == 'Order canceled')
Пример #17
0
def test_oms_regular_sequence(mocker: MockFixture):
    scheduler = HistoricNetworkScheduler(0, 1000)
    oms = OrderManagerService(scheduler)
    order_statuses = []
    Do(
        scheduler.get_network(), oms.get_order_events(), lambda: order_statuses
        .append(oms.get_order_events().get_value().get_order_status()))
    instrument = mocker.MagicMock(ExchangeInstrument)
    order = MarketOrder(10, instrument, Side.BUY, 'Main')
    order.set_order_id(str(uuid1()))
    oms.pending_new(order)
    oms.new(order, str(uuid1()))
    oms.apply_fill(order, 1, 10_000, str(uuid1()))
    oms.pending_cancel(order)
    oms.apply_cancel(order, str(uuid1()))
    scheduler.run()
    assert (order_statuses == [
        OrderStatus.PENDING_NEW, OrderStatus.NEW, OrderStatus.PARTIALLY_FILLED,
        OrderStatus.PENDING_CANCEL, OrderStatus.CANCELED
    ])
Пример #18
0
    def init(self, ctx: StrategyContext):
        scheduler = ctx.get_scheduler()
        network = scheduler.get_network()

        contract_qty = int(ctx.getenv('BBANDS_QTY', 1))
        window = int(ctx.getenv('BBANDS_WINDOW'))
        num_std = int(ctx.getenv('BBANDS_NUM_STD'))
        stop_std = int(ctx.getenv('BBANDS_STOP_STD'))
        bin_minutes = int(ctx.getenv('BBANDS_BIN_MINUTES', 5))
        cooling_period_seconds = int(ctx.getenv('BBANDS_COOL_SECONDS', 15))
        exchange_code, instrument_code = ctx.getenv(
            'TRADING_INSTRUMENT').split(':')
        instrument = ctx.get_instrument_cache().get_crypto_exchange_instrument(
            exchange_code, instrument_code)
        trades = ctx.get_marketdata_service().get_trades(instrument)
        trades_5m = BufferWithTime(scheduler, trades,
                                   timedelta(minutes=bin_minutes))
        prices = ComputeOHLC(network, trades_5m)
        close_prices = Map(network, prices, lambda x: x.close_px)
        bbands = ComputeBollingerBands(network, close_prices, window, num_std)

        op_service = ctx.get_order_placer_service()
        oms = op_service.get_order_manager_service()
        dcs = ctx.get_data_capture_service()

        exchange_id = ctx.getenv('EXCHANGE_ID', 'phemex')
        exchange_instance = ctx.getenv('EXCHANGE_INSTANCE', 'prod')
        account = ctx.getenv('EXCHANGE_ACCOUNT')
        op_uri = f'{exchange_id}:{exchange_instance}'

        # subscribe to marks, position updates and exchange position updates
        marks = ctx.get_mark_service().get_marks(instrument)
        Do(scheduler.get_network(), marks,
           lambda: self.logger.debug(marks.get_value()))

        position = ctx.get_position_service().get_position(account, instrument)
        Do(scheduler.get_network(), position,
           lambda: self.logger.info(position.get_value()))

        exch_position = ctx.get_exchange_position_service(
        ).get_exchange_positions()
        Do(scheduler.get_network(), exch_position,
           lambda: self.logger.info(exch_position.get_value()))

        # capture position and Bollinger Band data
        Do(
            scheduler.get_network(), position, lambda: dcs.capture(
                'Position', {
                    'time': pd.to_datetime(scheduler.get_time(), unit='ms'),
                    'position': position.get_value().get_qty()
                }))
        Do(
            scheduler.get_network(), bbands, lambda: dcs.capture(
                'BollingerBands', {
                    'time': pd.to_datetime(scheduler.get_time(), unit='ms'),
                    'sma': bbands.get_value().sma,
                    'upper': bbands.get_value().upper,
                    'lower': bbands.get_value().lower
                }))

        # debug log basic marketdata
        Do(scheduler.get_network(), prices,
           lambda: self.logger.debug(prices.get_value()))

        class TraderState(Enum):
            GOING_LONG = auto()
            LONG = auto()
            FLATTENING = auto()
            FLAT = auto()

        # order placement logic
        class BollingerTrader(Event):
            # noinspection PyShadowingNames
            def __init__(self, scheduler: NetworkScheduler,
                         op_service: OrderPlacerService,
                         strategy: BollingerBandsStrategy1):
                self.scheduler = scheduler
                self.op = op_service.get_order_placer(f'{op_uri}')
                self.strategy = strategy
                self.last_entry = 0
                self.last_exit = 0
                self.cum_pnl = 0
                self.stop = None
                self.trader_state = TraderState.FLAT
                self.last_trade_time = 0

                self.scheduler.get_network().connect(oms.get_order_events(),
                                                     self)
                self.scheduler.get_network().connect(position, self)

            def on_activate(self) -> bool:
                if self.scheduler.get_network().has_activated(
                        oms.get_order_events()):
                    order_event = oms.get_order_events().get_value()
                    if isinstance(order_event,
                                  ExecutionReport) and order_event.is_fill():
                        order_type = 'stop order' if self.stop is not None and order_event.get_order_id() == \
                                                     self.stop.order_id else 'market order'
                        self.strategy.logger.info(
                            f'Received fill event for {order_type}: {order_event}'
                        )
                        if self.trader_state == TraderState.GOING_LONG:
                            self.last_entry = order_event.get_last_px()
                            if order_event.get_order_status(
                            ) == OrderStatus.FILLED:
                                self.strategy.logger.info(
                                    f'Entered long position: entry price={self.last_entry}'
                                )
                                self.trader_state = TraderState.LONG
                        elif self.trader_state in (TraderState.FLATTENING, TraderState.LONG) and \
                                order_event.get_order_status() == OrderStatus.FILLED:
                            if order_type == 'stop order':
                                self.strategy.logger.info(
                                    f'stop loss filled at {order_event.get_last_px()}'
                                )
                                self.stop = None

                            trade_pnl = (order_event.get_last_px() - self.last_entry) * \
                                        (contract_qty / self.last_entry)
                            self.cum_pnl += trade_pnl
                            self.strategy.logger.info(
                                f'Trade P&L={trade_pnl}; cumulative P&L={self.cum_pnl}'
                            )

                            dcs.capture(
                                'PnL', {
                                    'time':
                                    pd.to_datetime(scheduler.get_time(),
                                                   unit='ms'),
                                    'trade_pnl':
                                    trade_pnl,
                                    'cum_pnl':
                                    self.cum_pnl
                                })
                            self.trader_state = TraderState.FLAT
                    elif isinstance(order_event, Reject):
                        self.strategy.logger.error(
                            f'Order rejected: {order_event.get_message()}')
                        self.trader_state = TraderState.FLAT
                elif self.trader_state == TraderState.FLAT and close_prices.get_value(
                ) < bbands.get_value().lower:
                    if self.last_trade_time != 0 and (scheduler.get_time() - self.last_trade_time) < \
                            cooling_period_seconds * 1000:
                        self.strategy.logger.info(
                            'Cooling off -- not trading again on rapidly repeated signal'
                        )
                        return False

                    self.strategy.logger.info(
                        f'Close below lower Bollinger band, enter long position '
                        f'at {scheduler.get_clock().get_time()}')

                    stop_px = close_prices.get_value() - (
                        (bbands.get_value().sma - bbands.get_value().lower) *
                        (stop_std / num_std))

                    self.strategy.logger.info(
                        f'Submitting orders: last_px = {close_prices.get_value()}, '
                        f'stop_px = {stop_px}')

                    order = self.op.get_order_factory().create_market_order(
                        Side.BUY, contract_qty, instrument)
                    self.stop = self.op.get_order_factory().create_stop_order(
                        Side.SELL, contract_qty, stop_px, instrument)

                    self.op.submit(order)
                    self.op.submit(self.stop)

                    self.last_trade_time = scheduler.get_time()
                    self.trader_state = TraderState.GOING_LONG
                elif self.trader_state == TraderState.LONG and close_prices.get_value(
                ) > bbands.get_value().upper:
                    self.strategy.logger.info(
                        f'Close above upper Bollinger band, exiting long position at '
                        f'{scheduler.get_clock().get_time()}')

                    order = self.op.get_order_factory().create_market_order(
                        Side.SELL, contract_qty, instrument)
                    self.op.submit(order)
                    if self.stop is not None:
                        self.op.cancel(self.stop)
                        self.stop = None

                    self.trader_state = TraderState.FLATTENING
                return False

        network.connect(bbands, BollingerTrader(scheduler, op_service, self))
Пример #19
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    signal = From(scheduler, ["world"])
    Do(scheduler.get_network(), signal,
       lambda: print(f"Hello, {signal.get_value()}!"))
Пример #20
0
def test_hello_world():
    scheduler = HistoricNetworkScheduler(0, 30 * 1000)
    signal = From(scheduler, ['world'])
    Do(scheduler.get_network(), signal,
       lambda: print(f'Hello, {signal.get_value()}!'))
    scheduler.run()
Пример #21
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    network = scheduler.get_network()
    values = Interval(scheduler)
    accumulator = Scan(network, values)
    Do(network, accumulator, lambda: print(f"{accumulator.get_value()}"))
Пример #22
0
async def main():
    scheduler = RealtimeNetworkScheduler()
    network = scheduler.get_network()
    values = From(scheduler, [0.0, -3.2, 2.1, -2.9, 8.3, -5.7])
    filt = Filter(network, values, lambda x: x >= 0.0)
    Do(network, filt, lambda: print(f"{filt.get_value()}"))
Пример #23
0
    def init(self, ctx: StrategyContext):
        self.ctx = ctx

        big_print_qty = float(ctx.getenv('BIG_PRINT_QTY'))
        self.trade_qty = float(ctx.getenv('CONTRACT_TRADE_QTY'))

        api_key = ctx.getenv('PHEMEX_API_KEY')
        api_secret = ctx.getenv('PHEMEX_API_SECRET')
        if not api_key:
            raise ValueError('missing PHEMEX_API_KEY')
        if not api_secret:
            raise ValueError('missing PHEMEX_API_SECRET')

        credentials = AuthCredentials(api_key, api_secret)

        exchange_instance = ctx.getenv('PHEMEX_INSTANCE', 'prod')
        if exchange_instance == 'prod':
            self.trading_conn = PhemexConnection(credentials)
        elif exchange_instance == 'test':
            self.trading_conn = PhemexConnection(
                credentials, api_url='https://testnet-api.phemex.com')
        else:
            raise ValueError(
                f'Unknown PHEMEX_INSTANCE value: {exchange_instance}')

        self.logger.info(f'Connected to Phemex {exchange_instance} instance')

        network = self.ctx.get_network()

        # subscribe to AOP messages
        auth = WebsocketAuthenticator(api_key, api_secret)
        aop_sub = AccountOrderPositionSubscriber(auth, ctx.get_scheduler(),
                                                 exchange_instance)
        aop_sub.start()

        # scan the spot market for large trades
        btc_usd_spot = self.ctx.get_instrument_cache().get_exchange_instrument(
            'CoinbasePro', 'BTC-USD')
        spot_trades = self.ctx.get_marketdata_service().get_trades(
            btc_usd_spot)
        Do(
            network, spot_trades, lambda: self.logger.info(
                f'Spot market trade: {spot_trades.get_value()}'))
        self.big_prints = Filter(network, spot_trades,
                                 lambda x: x.get_qty() >= big_print_qty)

        # compute 5 minute bins for the futures market and extract the volume field
        btc_usd_future = self.ctx.get_instrument_cache(
        ).get_exchange_instrument('Phemex', 'BTCUSD')
        self.futures_trades = self.ctx.get_marketdata_service().get_trades(
            btc_usd_future)
        buffer_5min = BufferWithTime(network, self.futures_trades,
                                     timedelta(minutes=5))
        self.ohlc_5min = ComputeOHLC(network, buffer_5min)
        Do(
            network, self.ohlc_5min, lambda: self.logger.info(
                f'OHLC[5min]: {self.ohlc_5min.get_value()}'))
        self.volume = Map(network, self.ohlc_5min, lambda x: x.volume)

        # subscribe to top of book
        self.futures_book = self.ctx.get_marketdata_service().get_order_books(
            btc_usd_future)
        Do(
            network, self.futures_book, lambda: self.logger.info(
                f'Futures bid/ask: '
                f'{self.futures_book.get_value().get_best_bid()} / '
                f'{self.futures_book.get_value().get_best_ask()}'))

        # track the exponentially weighted moving average of the futures volume
        self.ewma = ExponentialMovingAverage(network, self.volume)