예제 #1
0
class BacktestBroker(Broker):
    def __init__(self, hub: Hub) -> None:
        self.hub = hub
        self.publisher = Publisher(hub, prefix='broker')
        self.subscriber = Subscriber(hub, 'broker')
        self.subscriber.add_sync_listener(events.AnyNewTrade,
                                          self.log_trade_timestamp)
        self.orders = []
        self.positions = []
        self._timestamp = None

    def submit_order(self, order: Order) -> None:
        order.timestamp = self.get_timestamp()
        exchange = order.exchange
        self.publisher.publish([exchange.name, 'new-order'], order)
        self.orders.append(order)
        position = self.make_position(order)
        self.positions.append(position)
        position.open(order.price)

    def make_position(self, order: Order) -> Position:
        position = Position(order.market.quote,
                            order.amount,
                            timestamp=order.timestamp)
        self.publisher.publish([str(order.market), 'new-position'], position)
        return position

    def get_timestamp(self) -> datetime:
        if self._timestamp is not None:
            return self._timestamp
        else:
            return utc_now()

    def log_trade_timestamp(self, key: Key, trade: Trade) -> None:
        self._timestamp = trade.timestamp
예제 #2
0
 def __init__(self, hub: Hub, filename: str) -> None:
     self.filename = filename
     logger.info("Reading csv")
     self.df = pd.read_csv(self.filename, names=COLUMN_NAMES)
     self.df.time = pd.to_datetime(self.df.time, unit='s')
     self.publisher = Publisher(hub, prefix='csv_trade_processor')
     logger.info("Reading done")
예제 #3
0
class ThresholdBarGenerator:
    """
    ThresholdBarGenerator samples price statistics and generates a new bar
    when predefined threshold of given statistics has been reached.
    """
    def __init__(self, hub: Hub, threshold: int):
        self.subscriber = Subscriber(hub, 'threshold_bars')
        self.subscriber.add_sync_listener(events.AnyNewTrade,
                                          self.on_new_trade)
        self.publisher = Publisher(hub, prefix='threshold_bars')
        self.threshold = threshold
        self.bar = None
        self.value = 0

    def on_new_trade(self, key: Key, trade: Trade) -> None:
        if not self.bar:
            self.bar = Bar(trade)
        self.bar.append(trade)
        if self.value >= self.threshold:
            namespace = key[1]
            self._build_new_bar(trade, namespace)
        self.value += self.metric(trade)

    def _build_new_bar(self, trade: Trade, namespace: str) -> Bar:
        self.value = 0
        key = [namespace, 'new-bar']
        self.publisher.publish(key, self.bar)
        self.bar = Bar(trade)
        return self.bar
예제 #4
0
 def __init__(self, hub: Hub, threshold: int):
     self.subscriber = Subscriber(hub, 'threshold_bars')
     self.subscriber.add_sync_listener(events.AnyNewTrade,
                                       self.on_new_trade)
     self.publisher = Publisher(hub, prefix='threshold_bars')
     self.threshold = threshold
     self.bar = None
     self.value = 0
예제 #5
0
 def __init__(self, hub: Hub) -> None:
     self.hub = hub
     self.publisher = Publisher(hub, prefix='broker')
     self.subscriber = Subscriber(hub, 'broker')
     self.subscriber.add_sync_listener(events.AnyNewTrade,
                                       self.log_trade_timestamp)
     self.orders = []
     self.positions = []
     self._timestamp = None
예제 #6
0
 def __init__(self, hub: Hub,
              exchange: Exchange,
              market: Market,
              date_range: Optional[DateRange] = None
              ) -> None:
     self.library_name = str(exchange)
     self.symbol = str(market)
     self.store = Arctic('localhost')
     self.library = self.store[self.library_name]
     self.date_range = date_range
     self.publisher = Publisher(hub, prefix='arctic_trade_processor')
예제 #7
0
def test_mullti_strategy_on_new_bar_is_called():
    hub = Hub()
    publisher = Publisher(hub, 'test-publisher')
    trade = Trade(12345, price=1.0, amount=1.0)
    bar = Bar(trade)
    exchange = 'test'
    market = Markets.BTCEUR
    broker = BacktestBroker(hub)
    strat = NewBarTestMultiStrategy(hub, broker)
    publisher.publish([f'{exchange}-{market}', 'new-bar'], bar)
    assert strat.on_new_bar_called
예제 #8
0
def test_multi_strategy_stores_bars():
    hub = Hub()
    publisher = Publisher(hub, 'test-publisher')
    bars = [1, 2, 3]
    exchange = 'test'
    market = Markets.BTCUSD
    broker = BacktestBroker(hub)
    strat = NewBarTestMultiStrategy(hub, broker)
    [
        publisher.publish([f'{exchange}-{market}', 'new-bar'], bar)
        for bar in bars
    ]
    assert strat.bars['test-BTCUSD'] == bars
예제 #9
0
def test_tick_bar_generation_after_threshold():
    hub = Hub()
    publisher = Publisher(hub, 'test-publisher')
    generator = TickBarGenerator(hub, threshold=3)
    subscriber = Subscriber(hub, 'test-subscriber')
    bars = []
    def new_bar_handler(key, bar):
        bars.append(bar)
    subscriber.add_sync_listener(events.AnyNewBar, new_bar_handler)
    assert len(bars) == 0
    for i in range(5):
        trade = Trade(12345, price=1.0, amount=1.0)
        publisher.publish(['test-BTCUSD', 'new-trade'], trade)
    assert len(bars) == 1
예제 #10
0
class CSVTradeProcessor:
    def __init__(self, hub: Hub, filename: str) -> None:
        self.filename = filename
        logger.info("Reading csv")
        self.df = pd.read_csv(self.filename, names=COLUMN_NAMES)
        self.df.time = pd.to_datetime(self.df.time, unit='s')
        self.publisher = Publisher(hub, prefix='csv_trade_processor')
        logger.info("Reading done")

    def run(self) -> None:
        logger.info("Processing trades from CSV")
        self.df.apply(self.send_signal, axis=1)
        logger.info("Finished, sending signal")
        self.publisher.publish(events.ProcessingFinished, None)

    def send_signal(self, row) -> None:
        trade = Trade(timestamp=row.time, price=row.price, amount=row.amount)
        self.publisher.publish(['csvfile-BTCUSD', 'new-trade'], trade)
예제 #11
0
class FeedProcessor:
    def __init__(self, hub: Hub, exchange_class: str, pair: str) -> None:
        self.feed = FeedHandler()
        self.publisher = Publisher(hub, prefix='feed_processor')
        self.pair = pair
        self._add_feed(exchange_class)

    def _add_feed(self, exchange_class: str):
        trades_feed = exchange_class(pairs=[self.pair],
                                     channels=[TRADES],
                                     callbacks={TRADES: TradeCallback(self.trade)})
        self.feed.add_feed(trades_feed)

    def run(self) -> None:
        self.feed.run()

    async def trade(self, feed, pair, order_id, timestamp, side, amount, price):
        # print(f"Timestamp: {timestamp} Feed: {feed} Pair: {pair} ID: {order_id} Side: {side} Amount: {amount} Price: {price}")
        trade = Trade(timestamp=timestamp, price=price, amount=amount)
        self.publisher.publish([self.pair, 'new-trade'], trade)
예제 #12
0
 def __init__(self, hub: Hub, initial_theta: int = 50) -> None:
     self.subscriber = Subscriber(hub, 'tick_imbalance_bar_generator')
     self.subscriber.add_sync_listener(events.AnyNewTrade,
                                       self.on_new_trade)
     self.publisher = Publisher(hub, prefix='tick_imbalance_bar_generator')
     self.bar = None
     self.last_trade = None
     self.b_ts = []
     self.t_vals = []
     self.theta = 0
     self.expected_theta = initial_theta
     self.initial_T = 50
예제 #13
0
class ArcticTradeProcessor:
    def __init__(self, hub: Hub,
                 exchange: Exchange,
                 market: Market,
                 date_range: Optional[DateRange] = None
                 ) -> None:
        self.library_name = str(exchange)
        self.symbol = str(market)
        self.store = Arctic('localhost')
        self.library = self.store[self.library_name]
        self.date_range = date_range
        self.publisher = Publisher(hub, prefix='arctic_trade_processor')

    def run(self) -> None:
        logger.info("Processing trades from Arctic")
        item = self.library.read(self.symbol, date_range=self.date_range)
        logger.info("Finished reading, launching trades")
        item.data.apply(self.send_signal, axis=1)
        self.publisher.publish(events.ProcessingFinished, None)

    def send_signal(self, row) -> None:
        trade = Trade(timestamp=row.time, price=row.price, amount=row.amount)
        self.publisher.publish([f"{self.library_name}-{self.symbol}", 'new-trade'], trade)
예제 #14
0
def publisher(hub) -> Publisher:
    return Publisher(hub, 'test_publisher')
예제 #15
0
def publisher(hub):
    return Publisher(hub, 'test-publisher')
예제 #16
0
 def __init__(self, hub: Hub, exchange_class: str, pair: str) -> None:
     self.feed = FeedHandler()
     self.publisher = Publisher(hub, prefix='feed_processor')
     self.pair = pair
     self._add_feed(exchange_class)