コード例 #1
0
def test_number_of_markets_validation(error: bool, markets: List[Union[Market,
                                                                       Mock]]):
    candle_storage = flexmock()
    candle_storage.should_receive('mean').and_return(0).mock()
    candle_storage.should_receive('get_last_minute_candle').and_return(
        flexmock(average_price=Decimal('8000')))

    if len(
            markets
    ) == 1:  # Flexmock is not working properly with @pytest.mark.parametrize (MethodSignatureError)
        markets = [
            markets[0].should_receive('name').and_return(
                DUMMY_MARKET_NAME).mock()
        ]

    order_storage = create_order_storage_mock()
    order_storage.should_receive('find_by').and_return([])
    order_storage.should_receive('find_last_order').and_return(None)

    strategy = DoubleCrossoverStrategy(
        candle_storage,
        OrderFacade(order_storage, create_portfolio_snapshot_mock(),
                    create_event_emitter_mock()), CurrentUtcDateTimeFactory(),
        STRATEGY_RUN)
    if error:
        with pytest.raises(StrategyConfigurationException):
            strategy.tick(markets)
    else:
        strategy.tick(markets)
コード例 #2
0
def test_not_enough_balance_logs_warning():
    candle_storage = flexmock()
    candle_storage.should_receive('mean').and_return(8000).and_return(
        7900).and_return(8000).and_return(8100)
    candle_storage.should_receive('get_last_minute_candle').and_return(
        flexmock(average_price=Decimal(Decimal('8000'))))

    market = create_market_mock()
    market.should_receive('place_order').and_raise(
        NotEnoughBalanceToPerformOrderException)
    market.should_receive('get_balances').and_return([])

    order_storage = create_order_storage_mock()
    order_storage.should_receive('find_by').and_return([])
    order_storage.should_receive('find_last_order').and_return(None)

    strategy = DoubleCrossoverStrategy(
        candle_storage,
        OrderFacade(order_storage, create_portfolio_snapshot_mock(),
                    create_event_emitter_mock()), CurrentUtcDateTimeFactory(),
        STRATEGY_RUN)
    flexmock(logging.getLogger('coinrat_double_crossover_strategy.strategy')
             ).should_receive('warning').once()
    strategy.tick([market])
    strategy.tick([market])
コード例 #3
0
def test_mock_market_current_price():
    market = MockMarket(CurrentUtcDateTimeFactory(),
                        {'mocked_market_name': 'yolo_market'})
    with pytest.raises(KeyError):
        market.get_current_price(BTC_USD_PAIR)
    market.mock_current_price(BTC_USD_PAIR, Decimal('9854.458'))
    assert market.get_current_price(BTC_USD_PAIR) == Decimal('9854.458')
コード例 #4
0
def test_sending_signal(
    expected_buy: int,
    expected_sell: int,
    canceled_orders_count: int,
    mean_evolution: List[Tuple[int, int]],
    previous_order_rate: Union[int, None],
    current_candle_average_price: int,
):
    candle_storage = flexmock()
    expectation = candle_storage.should_receive('mean')
    for mean in mean_evolution:
        expectation.and_return(mean[0]).and_return(mean[1])
    candle_storage.should_receive('get_last_minute_candle').and_return(
        flexmock(average_price=Decimal(current_candle_average_price)))
    market = create_market_mock()

    class OrderDirectionMatcher(object):
        def __init__(self, direction):
            self._direction = direction

        def __eq__(self, order: Order):
            return self._direction == order._direction

    market.should_receive('place_order') \
        .with_args(OrderDirectionMatcher(DIRECTION_BUY)) \
        .and_return(DUMMY_CLOSED_ORDER) \
        .times(expected_buy)

    market.should_receive('place_order') \
        .with_args(OrderDirectionMatcher(DIRECTION_SELL)) \
        .and_return(DUMMY_CLOSED_ORDER) \
        .times(expected_sell)

    market.should_receive('cancel_order').with_args(
        DUMMY_OPEN_ORDER.id_on_market).times(canceled_orders_count)
    market.should_receive('get_order_status').and_return(STILL_OPEN_ORDER_INFO)
    market.should_receive('get_balances').and_return([])

    order_storage = flexmock(name='yolo_order_storage')
    order_storage.should_receive('find_by').and_return([])
    order_storage.should_receive('find_by').and_return([DUMMY_OPEN_ORDER])
    order_storage.should_receive('find_by').and_return([DUMMY_OPEN_ORDER])
    order_storage.should_receive('save_order').times(expected_buy +
                                                     expected_sell +
                                                     canceled_orders_count)
    order_storage.should_receive('delete')

    previous_order = None
    if previous_order_rate is not None:
        previous_order = flexmock(rate=Decimal(previous_order_rate))
    order_storage.should_receive('find_last_order').and_return(previous_order)

    strategy = DoubleCrossoverStrategy(
        candle_storage,
        OrderFacade(order_storage, create_portfolio_snapshot_mock(),
                    create_event_emitter_mock()), CurrentUtcDateTimeFactory(),
        STRATEGY_RUN)
    for x in range(0, len(mean_evolution)):
        strategy.tick([market])
コード例 #5
0
def test_market():
    market = MockMarket(
        CurrentUtcDateTimeFactory(), {
            'mocked_market_name': 'yolo',
            'mocked_base_currency_balance': Decimal('1001'),
            'mocked_base_currency': 'WTF',
            'mocked_transaction_maker_fee': Decimal('0.001'),
            'mocked_transaction_taker_fee': Decimal('0.001'),
        })
    assert 'yolo' == market.name
    assert Decimal('0.004') == market.get_pair_market_info(
        BTC_USD_PAIR).minimal_order_size
    assert '1001.00000000 WTF' == str(market.get_balance('WTF'))
    assert '0.00000000 LOL' == str(market.get_balance('LOL'))
    assert Decimal('0.001') == market.transaction_taker_fee
    assert Decimal('0.001') == market.transaction_maker_fee
    order = create_order(pair=Pair('WTF', 'BTC'), quantity=Decimal('0.1001'))
    assert order == market.place_order(order)
    assert market.cancel_order('xxx') is None

    assert str(market.get_balances()
               ) == '[0.00000000 WTF, 0.00000000 LOL, 0.09999990 BTC]'
コード例 #6
0
def test_closes_open_orders_if_closed_on_market(
        expected_save_order_called: int, markets_order_info: OrderMarketInfo):
    candle_storage = flexmock()
    candle_storage.should_receive('mean').and_return(8000).and_return(7900)
    candle_storage.should_receive('get_last_minute_candle').and_return(
        flexmock(average_price=Decimal(Decimal('8000'))))

    order_storage = create_order_storage_mock()
    order_storage.should_receive('find_by').and_return([DUMMY_OPEN_ORDER])
    order_storage.should_receive('delete')
    order_storage.should_receive('save_order').times(
        expected_save_order_called)

    market = create_market_mock()
    market.should_receive('get_order_status').and_return(
        markets_order_info).once()
    market.should_receive('get_balances').and_return([])

    strategy = DoubleCrossoverStrategy(
        candle_storage,
        OrderFacade(order_storage, create_portfolio_snapshot_mock(),
                    create_event_emitter_mock()), CurrentUtcDateTimeFactory(),
        STRATEGY_RUN)
    strategy.tick([market])
コード例 #7
0
def test_market_processes_orders():
    market = MockMarket(CurrentUtcDateTimeFactory(),
                        {'mocked_market_name': 'yolo_market'})

    assert market.get_balance('USD').available_amount == Decimal('1000')

    with pytest.raises(NotEnoughBalanceToPerformOrderException):
        market.place_order(create_order())

    assert market.get_balance('USD').available_amount == Decimal('1000')

    market.place_order(create_order(quantity=Decimal('0.1')))
    assert market.get_balance('USD').available_amount == Decimal('0')
    assert market.get_balance('BTC').available_amount == Decimal('0.09975')

    with pytest.raises(NotEnoughBalanceToPerformOrderException):
        market.place_order(
            create_order(direction=DIRECTION_SELL, quantity=Decimal('0.1')))

    market.place_order(
        create_order(direction=DIRECTION_SELL, quantity=Decimal('0.09975')))
    assert market.get_balance('USD').available_amount == Decimal(
        '995.00625')  # fee applied twice
    assert market.get_balance('BTC').available_amount == Decimal('0')
コード例 #8
0
    def __init__(self) -> None:
        super().__init__()

        self._storage = {
            'candle_storage_plugins': {
                'instance': None,
                'factory': lambda: CandleStoragePlugins(),
            },
            'order_storage_plugins': {
                'instance': None,
                'factory': lambda: OrderStoragePlugins(),
            },
            'market_plugins': {
                'instance': None,
                'factory': self._create_market_plugins,
            },
            'synchronizer_plugins': {
                'instance': None,
                'factory': lambda: SynchronizerPlugins(),
            },
            'strategy_plugins': {
                'instance': None,
                'factory': lambda: StrategyPlugins(),
            },
            'portfolio_snapshot_storage_plugins': {
                'instance': None,
                'factory': lambda: PortfolioSnapshotStoragePlugins(),
            },
            'rabbit_connection': {
                'instance': None,
                'factory': self._create_rabbit_connection,
            },
            'event_emitter': {
                'instance': None,
                'factory': self._create_event_emitter,
            },
            'task_planner': {
                'instance':
                None,
                'factory':
                lambda: TaskPlanner(self._get_factory('rabbit_connection')),
            },
            'datetime_factory': {
                'instance': None,
                'factory': lambda: CurrentUtcDateTimeFactory(),
            },
            'socket_server': {
                'instance':
                None,
                'factory':
                lambda:
                SocketServer(self.task_planner, self.datetime_factory, self.
                             candle_storage_plugins, self.
                             order_storage_plugins, self.market_plugins, self.
                             strategy_plugins, self.strategy_run_storage, self.
                             portfolio_snapshot_storage_plugins),
            },
            'strategy_replayer': {
                'instance':
                None,
                'factory':
                lambda: StrategyReplayer(
                    self.candle_storage_plugins, self.order_storage_plugins,
                    self.strategy_plugins, self.market_plugins, self.
                    portfolio_snapshot_storage_plugins, self.event_emitter)
            },
            'task_consumer': {
                'instance':
                None,
                'factory':
                lambda:
                TaskConsumer(self.rabbit_connection, self.strategy_replayer,
                             self.datetime_factory, self.strategy_run_storage,
                             self.event_emitter),
            },
            'subscription_storage': {
                'instance': None,
                'factory': lambda: SubscriptionStorage(),
            },
            'mysql_connection': {
                'instance':
                None,
                'factory':
                lambda: MySQLdb.connect(
                    host=os.environ.get('MYSQL_HOST'),
                    database=os.environ.get('MYSQL_DATABASE'),
                    user=os.environ.get('MYSQL_USER'),
                    password=os.environ.get('MYSQL_PASSWORD'),
                ),
            },
            'strategy_run_storage': {
                'instance': None,
                'factory': lambda: StrategyRunStorage(self.mysql_connection),
            },
            'strategy_standard_runner': {
                'instance':
                None,
                'factory':
                lambda: StrategyStandardRunner(
                    self.candle_storage_plugins,
                    self.order_storage_plugins,
                    self.strategy_plugins,
                    self.market_plugins,
                    self.portfolio_snapshot_storage_plugins,
                    self.event_emitter,
                    self.datetime_factory,
                ),
            }
        }
コード例 #9
0
def test_get_tradable_pairs():
    market = MockMarket(CurrentUtcDateTimeFactory(),
                        {'mocked_market_name': 'yolo_market'})
    pairs = market.get_all_tradable_pairs()
    assert len(pairs) > 0
コード例 #10
0
def test_market_get_order_status():
    market = MockMarket(CurrentUtcDateTimeFactory(),
                        {'mocked_market_name': 'yolo_market'})
    status = market.get_order_status(create_order())
    assert 'Order Id: "16fd2706-8baf-433b-82eb-8c7fada847da", OPEN, Closed at: "", Remaining quantity: "0"' \
           == str(status)