def create_dummy_data(influx_database: InfluxDBClient):
    storage = OrderInnoDbStorage(influx_database, 'test_orders')
    storage.save_order(Order(
        UUID('16fd2706-8baf-433b-82eb-8c7fada847da'),
        UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
        DUMMY_MARKET,
        DIRECTION_BUY,
        datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
        BTC_USD_PAIR,
        ORDER_TYPE_LIMIT,
        Decimal('1'),
        Decimal('8000'),
        'aaa-id-from-market',
        ORDER_STATUS_OPEN
    ))
    storage.save_order(Order(
        UUID('16fd2706-8baf-433b-82eb-8c7fada847db'),
        UUID('99fd2706-8baf-433b-82eb-8c7fada847db'),
        DUMMY_MARKET,
        DIRECTION_SELL,
        datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc),
        BTC_USD_PAIR,
        ORDER_TYPE_LIMIT,
        Decimal('2'),
        Decimal('9000'),
        'bbb-id-from-market',
        ORDER_STATUS_CLOSED
    ))
Example #2
0
    def place_order(self, order: Order) -> Order:
        assert order.market_name == self.name

        logging.info('Placing order: {}'.format(order))
        market = self._format_market_pair(order.pair)
        self._validate_minimal_order(order)

        if order.type == ORDER_TYPE_MARKET:
            raise NotImplementedError(
                'Bittrex does not support MARKET orders.')

        elif order.type == ORDER_TYPE_LIMIT:
            if order.is_sell():
                result = self._client_v1.sell_limit(market,
                                                    float(order.quantity),
                                                    float(order.rate))
            elif order.is_buy():
                result = self._client_v1.buy_limit(market,
                                                   float(order.quantity),
                                                   float(order.rate))
            else:
                raise ValueError('Unknown order direction: {}'.format(
                    order._direction))

            self._validate_result(result)
            order.set_id_on_market(result['result']['uuid'])
            return order

        else:
            raise ValueError('Unknown order type: {}'.format(order.type))
Example #3
0
    def place_order(self, order: Order) -> Order:
        fee = self._calculate_fee(order)
        self._initialize_balances(order.pair)

        if order.is_sell():
            self._process_sell(fee, order)
        elif order.is_buy():
            self._process_buy(fee, order)

        order.close(order.created_at)

        return order
Example #4
0
    def cancel(self, market: Market, order: Order,
               canceled_at: datetime.datetime):
        try:
            market.cancel_order(order.id_on_market)
        except MarketException as e:
            logger.error('Order "{}" cancelling failed: Error: "{}"!'.format(
                order.order_id, e))
            return

        order.cancel(canceled_at)
        self._order_storage.save_order(order)
        logger.info('Order "{}" has been CANCELED!'.format(order.order_id))
Example #5
0
    def _create_order_from_serialized(
            row: Dict[str, Union[str, int, float, bool]]) -> Order:
        pair_data = str(row[ORDER_FIELD_PAIR]).split('_')

        closed_at = None
        if ORDER_FIELD_CLOSED_AT in row and row[
                ORDER_FIELD_CLOSED_AT] is not None:
            closed_at = dateutil.parser.parse(str(
                row[ORDER_FIELD_CLOSED_AT])).replace(
                    tzinfo=datetime.timezone.utc)

        canceled_at = None
        if ORDER_FIELD_CANCELED_AT in row and row[
                ORDER_FIELD_CANCELED_AT] is not None:
            canceled_at = dateutil.parser.parse(
                str(row[ORDER_FIELD_CANCELED_AT])).replace(
                    tzinfo=datetime.timezone.utc)

        return Order(
            UUID(str(row[ORDER_FIELD_ORDER_ID])),
            UUID(str(row[ORDER_FIELD_STRATEGY_RUN_ID])),
            str(row[ORDER_FIELD_MARKET]),
            str(row[ORDER_FIELD_DIRECTION]),
            dateutil.parser.parse(str(row['time'])).replace(tzinfo=datetime.timezone.utc),
            Pair(pair_data[0], pair_data[1]),
            str(row[ORDER_FIELD_TYPE]),
            Decimal(row[ORDER_FIELD_QUANTITY]),
            Decimal(row[ORDER_FIELD_RATE]) if ORDER_FIELD_RATE in row and row[ORDER_FIELD_RATE] is not None else None,
            str(row[ORDER_FIELD_ID_ON_MARKET]) \
                if ORDER_FIELD_ID_ON_MARKET in row and row[ORDER_FIELD_ID_ON_MARKET] \
                else None,
            str(row[ORDER_FIELD_STATUS]),
            closed_at,
            canceled_at
        )
def test_find_last_order(influx_database: InfluxDBClient):
    storage = OrderInnoDbStorage(influx_database, 'test_orders')

    order = storage.find_last_order(DUMMY_MARKET, BTC_USD_PAIR)
    assert order is None

    storage.save_order(DUMMY_ORDER)

    order = storage.find_last_order(DUMMY_MARKET, BTC_USD_PAIR)
    assert str(order.order_id) == '16fd2706-8baf-433b-82eb-8c7fada847da'

    later_order = Order(
        UUID('16fd2706-8baf-433b-82eb-8c7fada847db'),
        UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
        DUMMY_MARKET,
        DIRECTION_BUY,
        datetime.datetime(2017, 11, 26, 10, 11, 13, tzinfo=datetime.timezone.utc),
        BTC_USD_PAIR,
        ORDER_TYPE_LIMIT,
        Decimal('1'),
        Decimal('8000'),
        'aaa-id-from-market'
    )
    storage.save_order(later_order)

    order = storage.find_last_order(DUMMY_MARKET, BTC_USD_PAIR)
    assert str(order.order_id) == '16fd2706-8baf-433b-82eb-8c7fada847db'
Example #7
0
    def _trade_on_signal(self, market: Market) -> None:
        logger.info('Checking trade on signal: "{}".'.format(
            self._last_signal))
        try:
            if self._last_signal.is_buy():
                self._cancel_open_order(market, DIRECTION_SELL)
                if self._does_trade_worth_it(market):
                    order = Order(
                        uuid.uuid4(), self._strategy_run.strategy_run_id,
                        market.name, DIRECTION_BUY,
                        self._datetime_factory.now(), self._strategy_run.pair,
                        ORDER_TYPE_LIMIT,
                        market.calculate_maximal_amount_to_buy(
                            self._strategy_run.pair,
                            self._last_signal.average_price),
                        self._last_signal.average_price)
                    self._order_facade.create(market, order)
                    self._last_signal = None

            elif self._last_signal.is_sell():
                self._cancel_open_order(market, DIRECTION_BUY)
                if self._does_trade_worth_it(market):
                    order = Order(
                        uuid.uuid4(), self._strategy_run.strategy_run_id,
                        market.name, DIRECTION_SELL,
                        self._datetime_factory.now(), self._strategy_run.pair,
                        ORDER_TYPE_LIMIT,
                        market.calculate_maximal_amount_to_sell(
                            self._strategy_run.pair),
                        self._last_signal.average_price)
                    self._order_facade.create(market, order)
                    self._last_signal = None
            else:
                raise ValueError('Unknown signal: "{}"'.format(
                    self._last_signal))  # pragma: no cover

        except NotEnoughBalanceToPerformOrderException as e:
            # Intentionally, this strategy does not need state of order,
            # just ignores buy/sell and waits for next signal.
            logger.warning(str(e))
            self._last_signal = None
def _crate_serialized_order(pair: Pair, market_name: str, created_at: datetime.datetime):
    return serialize_order(
        Order(
            uuid.uuid4(),
            uuid.UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
            market_name,
            DIRECTION_SELL,
            created_at,
            pair,
            ORDER_TYPE_LIMIT,
            Decimal('1'),
            Decimal('11000')
        ))
Example #9
0
def create_order(direction: str = DIRECTION_BUY,
                 quantity: Decimal = Decimal('1'),
                 rate: Decimal = Decimal('10000'),
                 pair: Pair = BTC_USD_PAIR) -> Order:
    return Order(
        UUID('16fd2706-8baf-433b-82eb-8c7fada847da'),
        UUID('99fd2706-8baf-433b-82eb-8c7fada847da'), 'dummy_market_name',
        direction,
        datetime.datetime(2017,
                          11,
                          26,
                          10,
                          11,
                          12,
                          tzinfo=datetime.timezone.utc), pair,
        ORDER_TYPE_LIMIT, quantity, rate)
Example #10
0
 def create_order(self, market: Market, direction: str):
     current_price = market.get_current_price(self._strategy_run.pair)
     logger.info(direction.upper() + 'ING at price: ' + str(current_price))
     order = Order(
         uuid.uuid4(),
         self._strategy_run.strategy_run_id,
         market.name,
         direction,
         self._datetime_factory.now(),
         self._strategy_run.pair,
         ORDER_TYPE_LIMIT,
         market.calculate_maximal_amount_to_buy(self._strategy_run.pair, current_price) \
             if direction is DIRECTION_BUY \
             else market.calculate_maximal_amount_to_sell(self._strategy_run.pair),
         current_price
     )
     self._order_facade.create(market, order)
Example #11
0
def test_order_export_import():
    pair = Pair('USD', 'BTC')
    order = Order(
        UUID('16fd2706-8baf-433b-82eb-8c7fada847da'),
        UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
        DUMMY_MARKET,
        DIRECTION_BUY,
        datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
        pair,
        ORDER_TYPE_LIMIT,
        Decimal('1'),
        Decimal('8000'),
        'aaa-id-from-market'
    )

    storage = flexmock()
    storage.should_receive('find_by').and_return([order]).once()
    storage.should_receive('save_order').once()
    exporter = OrderExporter(storage)
    file_name = os.path.dirname(__file__) + '_orders.json'

    exporter.export_to_file(file_name, 'dummy_market', pair)

    expected = [{
        "order_id": "16fd2706-8baf-433b-82eb-8c7fada847da",
        "strategy_run_id": "99fd2706-8baf-433b-82eb-8c7fada847da",
        "market": "dummy_market_name",
        "direction": "buy",
        "created_at": "2017-11-26T10:11:12+00:00",
        "pair": "USD_BTC",
        "type": "limit",
        "quantity": "1",
        "rate": "8000",
        "id_on_market": "aaa-id-from-market",
        "status": "open",
        "closed_at": None,
        "canceled_at": None
    }]

    with open(file_name) as json_file:
        assert json.load(json_file) == expected

    exporter.import_from_file(file_name)

    os.remove(file_name)
Example #12
0
from coinrat.domain.pair import Pair
from coinrat.domain.market import Market
from coinrat.domain.order import ORDER_TYPE_LIMIT, Order, OrderMarketInfo, DIRECTION_BUY, DIRECTION_SELL, \
    NotEnoughBalanceToPerformOrderException, ORDER_STATUS_CLOSED, ORDER_STATUS_OPEN, OrderStorage
from coinrat.order_facade import OrderFacade
from coinrat_double_crossover_strategy.strategy import DoubleCrossoverStrategy
from coinrat.event.event_emitter import EventEmitter

DUMMY_MARKET_NAME = 'dummy_market'
BTC_USD_PAIR = Pair('USD', 'BTC')
STRATEGY_RUN_ID = UUID('99fd2706-8baf-433b-82eb-8c7fada847da')

DUMMY_CLOSED_ORDER = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da'), STRATEGY_RUN_ID,
    DUMMY_MARKET_NAME, DIRECTION_BUY,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
    BTC_USD_PAIR, ORDER_TYPE_LIMIT, Decimal('1'), Decimal('8000'),
    'aaa-id-from-market', ORDER_STATUS_CLOSED,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc))
DUMMY_OPEN_ORDER = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847db'), STRATEGY_RUN_ID,
    DUMMY_MARKET_NAME, DIRECTION_BUY,
    datetime.datetime(2017, 11, 26, 10, 11, 12,
                      tzinfo=datetime.timezone.utc), BTC_USD_PAIR,
    ORDER_TYPE_LIMIT, Decimal('1'), Decimal('8000'), 'aaa-id-from-market')
STRATEGY_RUN = StrategyRun(
    STRATEGY_RUN_ID,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
    BTC_USD_PAIR, [], '', {
        'long_average_interval': 60 * 60,
        'short_average_interval': 15 * 60,
from flexmock import flexmock, Mock

from coinrat.domain.pair import Pair
from coinrat.domain.market import MarketException
from coinrat.domain.order import Order, ORDER_TYPE_LIMIT, ORDER_TYPE_MARKET, DIRECTION_BUY, DIRECTION_SELL, \
    NotEnoughBalanceToPerformOrderException
from coinrat_bittrex.market import BittrexMarket
from coinrat_bittrex.test.fixtures import MARKET_USDT_BTC_DATA, DUMMY_ORDER_ID_ON_MARKET, OPEN_ORDER, CLOSED_ORDER

BTC_USD_PAIR = Pair('USD', 'BTC')
DUMMY_LIMIT_BUY_ORDER = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da'),
    UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
    'bittrex',
    DIRECTION_BUY,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
    BTC_USD_PAIR,
    ORDER_TYPE_LIMIT,
    Decimal('1'),
    Decimal('8000')
)
DUMMY_MARKET_BUY_ORDER = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847db'),
    UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
    'bittrex',
    DIRECTION_BUY,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
    BTC_USD_PAIR,
    ORDER_TYPE_MARKET,
    Decimal('1'),
    None
Example #14
0
 def close(self, order: Order, closed_at: datetime.datetime) -> None:
     order.close(closed_at)
     self._order_storage.delete(order.order_id)
     self._order_storage.save_order(order)
     logger.info('Order "{}" has been successfully CLOSED.'.format(
         order.order_id))
from influxdb import InfluxDBClient

from coinrat.domain.pair import Pair
from coinrat.domain.order import Order, ORDER_TYPE_LIMIT, DIRECTION_BUY, DIRECTION_SELL, ORDER_STATUS_OPEN, \
    ORDER_STATUS_CLOSED
from coinrat_influx_db_storage.order_storage import OrderInnoDbStorage

DUMMY_MARKET = 'dummy_market'
BTC_USD_PAIR = Pair('USD', 'BTC')

DUMMY_ORDER = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da'),
    UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
    DUMMY_MARKET,
    DIRECTION_BUY,
    datetime.datetime(2017, 11, 26, 10, 11, 12, tzinfo=datetime.timezone.utc),
    BTC_USD_PAIR,
    ORDER_TYPE_LIMIT,
    Decimal('1'),
    Decimal('8000'),
    'aaa-id-from-market'
)


@pytest.fixture
def influx_database():
    influx = InfluxDBClient()
    influx.create_database('coinrat_test')
    influx._database = 'coinrat_test'
    yield influx
    influx.drop_database('coinrat_test')
Example #16
0
import copy
import datetime
from uuid import UUID

from decimal import Decimal

from coinrat.domain.pair import Pair
from coinrat.domain.order import Order, ORDER_TYPE_LIMIT, OrderMarketInfo, DIRECTION_BUY

DUMMY_ORDER_OPEN = Order(
    UUID('16fd2706-8baf-433b-82eb-8c7fada847db'),
    UUID('99fd2706-8baf-433b-82eb-8c7fada847da'),
    'lorem_ipsum',
    DIRECTION_BUY,
    datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc),
    Pair('USD', 'BTC'),
    ORDER_TYPE_LIMIT,
    Decimal('2'),
    Decimal('9000'),
    'bbb-id-from-market',
)


def test_open_order():
    order = DUMMY_ORDER_OPEN

    expected = 'BUY-OPEN, ' \
               + 'Id: "16fd2706-8baf-433b-82eb-8c7fada847db", ' \
               + 'Market: "lorem_ipsum", ' \
               + 'Created: "2017-01-02T03:04:05+00:00", ' \
               + 'Closed: "None", ' \