예제 #1
0
    def find_by(
        self,
        market_name: str,
        pair: Pair,
        interval: DateTimeInterval = DateTimeInterval(None, None),
        candle_size: CandleSize = CandleSize(CANDLE_SIZE_UNIT_MINUTE, 1)
    ) -> List[Candle]:
        parameters = {
            CANDLE_STORAGE_FIELD_MARKET: "= '{}'".format(market_name),
            CANDLE_STORAGE_FIELD_PAIR: "= '{}'".format(serialize_pair(pair)),
        }
        if interval.since is not None:
            parameters['"time" >'] = "'{}'".format(interval.since.isoformat())

        if interval.till is not None:
            parameters['"time" <'] = "'{}'".format(interval.till.isoformat())

        select = '*'
        if not candle_size.is_one_minute():
            select = 'FIRST("open") AS "open", MAX("high") AS "high", MIN("low") AS "low", LAST("close") AS "close"'

        sql = 'SELECT {} FROM "{}" WHERE '.format(select,
                                                  MEASUREMENT_CANDLES_NAME)
        where = []
        for key, value in parameters.items():
            where.append('{} {}'.format(key, value))
        sql += ' AND '.join(where)
        sql += self._get_group_by(candle_size)

        result: ResultSet = self._client.query(sql)
        data = list(result.get_points())

        return self._parse_db_result_into_candles(data, market_name, pair,
                                                  candle_size)
예제 #2
0
def serialize_order(order: Order) -> Dict[str, Union[str, None]]:
    return {
        ORDER_FIELD_ORDER_ID:
        str(order.order_id),
        ORDER_FIELD_STRATEGY_RUN_ID:
        str(order.strategy_run_id),
        ORDER_FIELD_MARKET:
        order.market_name,
        ORDER_FIELD_DIRECTION:
        order._direction,
        ORDER_FIELD_CREATED_AT:
        order.created_at.isoformat(),
        ORDER_FIELD_PAIR:
        serialize_pair(order.pair),
        ORDER_FIELD_TYPE:
        order.type,
        ORDER_FIELD_QUANTITY:
        str(order.quantity),
        ORDER_FIELD_RATE:
        str(order.rate),
        ORDER_FIELD_ID_ON_MARKET:
        order.id_on_market,
        ORDER_FIELD_STATUS:
        order._status,
        ORDER_FIELD_CLOSED_AT:
        order.closed_at.isoformat() if order.closed_at is not None else None,
        ORDER_FIELD_CANCELED_AT:
        order.canceled_at.isoformat()
        if order.canceled_at is not None else None,
    }
예제 #3
0
    def _get_serialized_order(self, order: Order) -> Dict:
        return {
            'measurement': self._measurement_name,
            'tags': {
                ORDER_FIELD_MARKET: order.market_name,
                ORDER_FIELD_PAIR: serialize_pair(order.pair),
                ORDER_FIELD_ORDER_ID: str(order.order_id),
                ORDER_FIELD_STRATEGY_RUN_ID: str(order.strategy_run_id),
            },
            'time': order.created_at.isoformat(),
            'fields': {
                ORDER_FIELD_DIRECTION:
                order._direction,
                ORDER_FIELD_ID_ON_MARKET:
                order.id_on_market,
                ORDER_FIELD_TYPE:
                order.type,
                ORDER_FIELD_STATUS:
                order._status,

                # Todo: figure out how to store decimals in influx (maybe int -> *100000)
                ORDER_FIELD_QUANTITY:
                float(order.quantity),
                ORDER_FIELD_RATE:
                float(order.rate),
                ORDER_FIELD_CLOSED_AT:
                order.closed_at.isoformat()
                if order.closed_at is not None else None,
                ORDER_FIELD_CANCELED_AT:
                order.canceled_at.isoformat()
                if order.canceled_at is not None else None,
            }
        }
예제 #4
0
    def _fix_fields_in_raw_candle(raw_candle: Dict, market_name: str,
                                  pair: Pair, candle_size: CandleSize) -> Dict:
        if CANDLE_STORAGE_FIELD_MARKET not in raw_candle:
            raw_candle[CANDLE_STORAGE_FIELD_MARKET] = market_name
        if CANDLE_STORAGE_FIELD_PAIR not in raw_candle:
            raw_candle[CANDLE_STORAGE_FIELD_PAIR] = serialize_pair(pair)
        if CANDLE_STORAGE_FIELD_SIZE not in raw_candle:
            raw_candle[CANDLE_STORAGE_FIELD_SIZE] = serialize_candle_size(
                candle_size)

        return raw_candle
예제 #5
0
def serialize_candle(candle: Candle) -> Dict[str, str]:
    return {
        CANDLE_STORAGE_FIELD_MARKET: candle.market_name,
        CANDLE_STORAGE_FIELD_PAIR: serialize_pair(candle.pair),
        CANDLE_STORAGE_FIELD_TIME: candle.time.isoformat(),
        CANDLE_STORAGE_FIELD_OPEN: '{0:.8f}'.format(candle.open),
        CANDLE_STORAGE_FIELD_HIGH: '{0:.8f}'.format(candle.high),
        CANDLE_STORAGE_FIELD_LOW: '{0:.8f}'.format(candle.low),
        CANDLE_STORAGE_FIELD_CLOSE: '{0:.8f}'.format(candle.close),
        CANDLE_STORAGE_FIELD_SIZE: serialize_candle_size(candle.candle_size),
    }
예제 #6
0
def serialize_strategy_run(strategy_run: StrategyRun):
    return {
        'strategy_run_id': str(strategy_run.strategy_run_id),
        'run_at': strategy_run.run_at.isoformat(),
        'pair': serialize_pair(strategy_run.pair),
        'markets': serialize_strategy_run_markets(strategy_run.markets),
        'strategy_name': strategy_run.strategy_name,
        'strategy_configuration': strategy_run.strategy_configuration,
        'interval': serialize_datetime_interval(strategy_run.interval),
        'candle_storage_name': strategy_run.candle_storage_name,
        'order_storage_name': strategy_run.order_storage_name,
    }
예제 #7
0
    def get_last_minute_candle(self, market_name: str, pair: Pair,
                               current_time: datetime.datetime) -> Candle:
        sql = '''
            SELECT * FROM "{}" WHERE "pair"='{}' AND "market"='{}' AND "time" <= '{}' ORDER BY "time" DESC LIMIT 1
        '''.format(MEASUREMENT_CANDLES_NAME, serialize_pair(pair), market_name,
                   current_time.isoformat())

        result: ResultSet = self._client.query(sql)
        result = list(result.get_points())
        self._validate_result_has_some_data(market_name, result)

        return deserialize_candle(result[0])
예제 #8
0
    def find_last_order(self, market_name: str,
                        pair: Pair) -> Union[Order, None]:
        sql = '''
            SELECT * FROM "{}" WHERE "pair"='{}' AND "market"='{}' ORDER BY "time" DESC LIMIT 1
        '''.format(self._measurement_name, serialize_pair(pair), market_name)

        result: ResultSet = self._client.query(sql)
        result = list(result.get_points())
        if len(result) == 0:
            return None

        return self._create_order_from_serialized(result[0])
예제 #9
0
 def mean(
     self,
     market_name: str,
     pair: Pair,
     field: str,
     interval: DateTimeInterval = DateTimeInterval(None, None)
 ) -> Decimal:
     sql = '''
         SELECT MEAN("{}") AS "field_mean" 
         FROM "{}" WHERE "time" > '{}' AND "time" < '{}' AND "pair"='{}' AND "market"='{}' 
         GROUP BY "{}"
     '''.format(field, MEASUREMENT_CANDLES_NAME, interval.since.isoformat(),
                interval.till.isoformat(), serialize_pair(pair),
                market_name, field)
     result: ResultSet = self._client.query(sql)
     self._validate_result_has_some_data(market_name, result)
     mean = list(result.items()[0][1])[0]['field_mean']
     return Decimal(mean)
예제 #10
0
 def _create_point_data(candle: Candle):
     return {
         'measurement': MEASUREMENT_CANDLES_NAME,
         'tags': {
             'market': candle.market_name,
             'pair': serialize_pair(candle.pair),
         },
         'time': candle.time.isoformat(),
         'fields': {
             CANDLE_STORAGE_FIELD_OPEN:
             float(candle.open),
             CANDLE_STORAGE_FIELD_CLOSE:
             float(candle.close),
             CANDLE_STORAGE_FIELD_LOW:
             float(candle.low),
             CANDLE_STORAGE_FIELD_HIGH:
             float(candle.high),
             CANDLE_STORAGE_FIELD_SIZE:
             serialize_candle_size(candle.candle_size)
         }
     }
예제 #11
0
 def _insert(cursor, strategy_run: StrategyRun) -> None:
     cursor.execute("""
         INSERT INTO `strategy_runs` (
             `id`,
             `run_at`,
             `pair`,
             `markets`,
             `strategy_name`,
             `strategy_configuration`,
             `interval_since`,
             `interval_till`,
             `candle_storage_name`,
             `order_storage_name`
         ) VALUES (
             %s,
             %s,
             %s,
             %s,
             %s,
             %s,
             %s,
             %s,
             %s,
             %s
         )     
     """, (
         str(strategy_run.strategy_run_id),
         strategy_run.run_at.timestamp(),
         serialize_pair(strategy_run.pair),
         json.dumps(serialize_strategy_run_markets(strategy_run.markets)),
         strategy_run.strategy_name,
         json.dumps(strategy_run.strategy_configuration),
         strategy_run.interval.since.timestamp(),
         strategy_run.interval.till.timestamp() if strategy_run.interval.till is not None else None,
         strategy_run.candle_storage_name,
         strategy_run.order_storage_name
     ))
예제 #12
0
    def find_by(self,
                market_name: str,
                pair: Pair,
                status: Union[str, None] = None,
                direction: Union[str, None] = None,
                interval: DateTimeInterval = DateTimeInterval(None, None),
                strategy_run_id: Union[str, None] = None) -> List[Order]:
        assert status in POSSIBLE_ORDER_STATUSES or status is None, 'Invalid status: "{}"'.format(
            status)

        parameters = {
            ORDER_FIELD_MARKET: "= '{}'".format(market_name),
            ORDER_FIELD_PAIR: "= '{}'".format(serialize_pair(pair)),
        }

        if status is not None:
            parameters[ORDER_FIELD_STATUS] = "= '{}'".format(status)
        if direction is not None:
            parameters[ORDER_FIELD_DIRECTION] = "= '{}'".format(direction)
        if interval.since is not None:
            parameters['"time" >'] = "'{}'".format(interval.since.isoformat())
        if interval.till is not None:
            parameters['"time" <'] = "'{}'".format(interval.till.isoformat())
        if strategy_run_id is not None:
            parameters[ORDER_FIELD_STRATEGY_RUN_ID] = "= '{}'".format(
                strategy_run_id)

        sql = 'SELECT * FROM "{}" WHERE '.format(self._measurement_name)
        where = []
        for key, value in parameters.items():
            where.append('{} {}'.format(key, value))
        sql += ' AND '.join(where)
        result: ResultSet = self._client.query(sql)
        data = list(result.get_points())

        return [self._create_order_from_serialized(row) for row in data]
예제 #13
0
        def pairs(sid, data):
            logger.info('RECEIVED: {}, {}'.format(EVENT_GET_PAIRS, data))

            if 'market_name' not in data:
                return 'ERROR', {
                    'message': 'Missing "market_name" field in request.'
                }

            if 'market_plugin_name' not in data:
                return 'ERROR', {
                    'message': 'Missing "market_plugin_name" field in request.'
                }

            market_plugin = self._market_plugins.get_plugin(
                data['market_plugin_name'])
            market = market_plugin.get_market(data['market_name'],
                                              datetime_factory, {})

            return 'OK', list(
                map(
                    lambda pair: {
                        'key': serialize_pair(pair),
                        'name': pair.base_currency + '-' + pair.market_currency
                    }, market.get_all_tradable_pairs()))
예제 #14
0
 def get_current_price(self, pair: Pair) -> Decimal:
     return self._current_prices[serialize_pair(pair)]
예제 #15
0
 def mock_current_price(self, pair: Pair, value: Decimal) -> None:
     self._current_prices[serialize_pair(pair)] = value