示例#1
0
 def get_all_currencies(config):
     currencies = set()
     for symbol in ConfigManager.get_symbols(config):
         quote, base = split_symbol(symbol)
         currencies.add(quote)
         currencies.add(base)
     return currencies
示例#2
0
    def get_trade_fee(
            self,
            symbol,
            order_type,
            quantity,
            price,
            taker_or_maker=ExchangeConstantsMarketPropertyColumns.TAKER.value):
        symbol_fees = self.get_fees(symbol)
        rate = symbol_fees[
            taker_or_maker] / 100  # /100 because rate in used in %
        currency, market = split_symbol(symbol)
        fee_currency = currency

        precision = self.get_market_status(symbol)[ExchangeConstantsMarketStatusColumns.PRECISION.value] \
            [ExchangeConstantsMarketStatusColumns.PRECISION_PRICE.value]
        cost = float(round_into_str_with_max_digits(quantity * rate,
                                                    precision))

        if order_type == OrderConstants.TraderOrderTypeClasses[TraderOrderType.SELL_MARKET] \
                or order_type == OrderConstants.TraderOrderTypeClasses[TraderOrderType.SELL_LIMIT]:
            cost = float(
                round_into_str_with_max_digits(cost * price, precision))
            fee_currency = market

        return {
            FeePropertyColumns.TYPE.value: taker_or_maker,
            FeePropertyColumns.CURRENCY.value: fee_currency,
            FeePropertyColumns.RATE.value: rate,
            FeePropertyColumns.COST.value: cost
        }
示例#3
0
 def init_traded_currencies_without_market_specific(self):
     for cryptocurrency in self.config[CONFIG_CRYPTO_CURRENCIES]:
         for pair in self.exchange.get_exchange_manager().get_traded_pairs(
                 cryptocurrency):
             symbol, _ = split_symbol(pair)
             if symbol not in self.traded_currencies_without_market_specific:
                 self.traded_currencies_without_market_specific.add(symbol)
示例#4
0
def get_standalone_backtesting_bot(config, data_files):
    config_to_use = create_blank_config_using_loaded_one(config)
    config_to_use[CONFIG_CRYPTO_CURRENCIES] = {}
    config_to_use[CONFIG_BACKTESTING][CONFIG_BACKTESTING_DATA_FILES] = []
    # do not activate web interface on standalone backtesting bot
    WebService.enable(config_to_use, False)
    ignored_files = []
    reference_market = _get_reference_market(data_files)
    if DEFAULT_REFERENCE_MARKET != reference_market:
        _switch_reference_market(config_to_use, reference_market)
    if data_files:
        for data_file_to_use in data_files:
            _, file_symbol, _ = interpret_file_name(data_file_to_use)
            currency, _ = split_symbol(file_symbol)
            full_file_path = CONFIG_DATA_COLLECTOR_PATH + data_file_to_use
            full_file_path += full_file_path if not full_file_path.endswith(
                DATA_FILE_EXT) else ""
            if currency not in config_to_use[CONFIG_CRYPTO_CURRENCIES]:
                config_to_use[CONFIG_CRYPTO_CURRENCIES][currency] = {
                    CONFIG_CRYPTO_PAIRS: []
                }
            if file_symbol not in config_to_use[CONFIG_CRYPTO_CURRENCIES][
                    currency][CONFIG_CRYPTO_PAIRS]:
                config_to_use[CONFIG_CRYPTO_CURRENCIES][currency][
                    CONFIG_CRYPTO_PAIRS].append(file_symbol)
                config_to_use[CONFIG_BACKTESTING][
                    CONFIG_BACKTESTING_DATA_FILES].append(full_file_path)
            else:
                ignored_files.append(data_file_to_use)

    return create_backtesting_bot(config_to_use), ignored_files
 async def create_order(self, order_data, current_price, symbol_market,
                        trader, portfolio):
     created_order = None
     currency, market = split_symbol(order_data.symbol)
     try:
         for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                 order_data.quantity, order_data.price, symbol_market):
             selling = order_data.side == TradeOrderSide.SELL
             if selling:
                 if portfolio.get_portfolio()[currency][
                         Portfolio.AVAILABLE] < order_quantity:
                     return None
             elif portfolio.get_portfolio()[market][
                     Portfolio.AVAILABLE] < order_quantity * order_price:
                 return None
             order_type = TraderOrderType.SELL_LIMIT if selling else TraderOrderType.BUY_LIMIT
             created_order = trader.create_order_instance(
                 order_type=order_type,
                 symbol=order_data.symbol,
                 current_price=current_price,
                 quantity=order_quantity,
                 price=order_price)
             await trader.create_order(created_order, portfolio)
     except InsufficientFunds as e:
         raise e
     except Exception as e:
         self.logger.error(
             f"Failed to create order : {e}. "
             f"Order: "
             f"{created_order.get_string_info() if created_order else None}"
         )
         self.logger.exception(e)
         return None
     return created_order
示例#6
0
 def _evaluate_config_crypto_currencies_values(self):
     values_dict = {}
     for crypto_currency_data in self.config[CONFIG_CRYPTO_CURRENCIES].values():
         pairs = crypto_currency_data[CONFIG_CRYPTO_PAIRS]
         if pairs:
             currency, _ = split_symbol(pairs[0])
             values_dict[currency] = self._evaluate_value(currency, 1)
     return values_dict
 def __init__(self, trading_mode, symbol_evaluator, exchange):
     super().__init__(trading_mode, symbol_evaluator, exchange)
     self.volume_weight = self.price_weight = self.last_buy_candle = None
     self.last_buy_candle = {self.SIMUALTOR_KEY: None, self.REAL_KEY: None}
     self.first_trigger = True
     self.sell_targets_by_order = {}
     self.quote, _ = split_symbol(self.symbol)
     self.sell_orders_per_buy = self.trading_mode.get_trading_config_value(
         "sell_orders_count")
示例#8
0
def get_currency_graph_update(exchange_name, symbol, time_frame, cryptocurrency_name):
    symbol_evaluator_list = get_bot().get_symbol_evaluator_list()
    exchange_list = get_bot().get_exchanges_list()

    if time_frame is not None:
        if len(symbol_evaluator_list) > 0:
            evaluator_thread_managers = symbol_evaluator_list[symbol].get_evaluator_thread_managers(
                exchange_list[exchange_name])

            if time_frame in evaluator_thread_managers:
                evaluator_thread_manager = evaluator_thread_managers[time_frame]
                data = evaluator_thread_manager.get_evaluator().get_data()

                if data is not None:
                    _, pair_tag = split_symbol(symbol)
                    add_to_symbol_data_history(symbol, data, time_frame)
                    data = get_symbol_data_history(symbol, time_frame)

                    # data.loc[:, PriceStrings.STR_PRICE_TIME.value] /= 1000

                    data_x = data[PriceIndexes.IND_PRICE_TIME.value]
                    data_y = data[PriceIndexes.IND_PRICE_CLOSE.value]

                    # Candlestick
                    ohlc_graph = go.Ohlc(x=data[PriceIndexes.IND_PRICE_TIME.value],
                                         open=data[PriceIndexes.IND_PRICE_OPEN.value],
                                         high=data[PriceIndexes.IND_PRICE_HIGH.value],
                                         low=data[PriceIndexes.IND_PRICE_LOW.value],
                                         close=data[PriceIndexes.IND_PRICE_CLOSE.value])

                    real_trades_prices, real_trades_times, simulated_trades_prices, simulated_trades_times = \
                        get_trades_by_times_and_prices()

                    real_trades_points = go.Scatter(
                        x=real_trades_prices,
                        y=real_trades_times,
                        mode='markers',
                        name='markers'
                    )

                    simulated_trades_points = go.Scatter(
                        x=simulated_trades_times,
                        y=simulated_trades_prices,
                        mode='markers',
                        name='markers'
                    )

                    return {'data': [ohlc_graph, real_trades_points, simulated_trades_points],
                            'layout': go.Layout(
                                title="{} real time data (per time frame)".format(cryptocurrency_name),
                                xaxis=dict(range=[min(data_x), max(data_x)],
                                           title=TIME_AXIS_TITLE),
                                yaxis=dict(range=[min(data_y) * 0.98, max(data_y) * 1.02],
                                           title=pair_tag)
                            )}
    return None
示例#9
0
 def get_market_pair(config, currency) -> (str, bool):
     if CONFIG_TRADING in config:
         reference_market = ConfigManager.get_reference_market(config)
         for symbol in ConfigManager.get_symbols(config):
             symbol_currency, symbol_market = split_symbol(symbol)
             if currency == symbol_currency and reference_market == symbol_market:
                 return symbol, False
             elif reference_market == symbol_currency and currency == symbol_market:
                 return symbol, True
     return "", False
示例#10
0
def _get_reference_market(data_files):
    reference_market = None
    for data_file in data_files:
        _, file_symbol, _, _ = interpret_file_name(data_file)
        currency, market = split_symbol(file_symbol)
        if reference_market is None:
            reference_market = market
        elif not reference_market == market:
            # more than one reference market in data_files: use first reference market
            return reference_market
    return reference_market if reference_market is not None else DEFAULT_REFERENCE_MARKET
示例#11
0
 def get_market_pair(config, currency) -> (str, bool):
     if CONFIG_TRADING in config:
         reference_market = get_value_or_default(
             config[CONFIG_TRADING], CONFIG_TRADER_REFERENCE_MARKET,
             DEFAULT_REFERENCE_MARKET)
         for symbol in ConfigManager.get_symbols(config):
             symbol_currency, symbol_market = split_symbol(symbol)
             if currency == symbol_currency and reference_market == symbol_market:
                 return symbol, False
             elif reference_market == symbol_currency and currency == symbol_market:
                 return symbol, True
     return "", False
 async def _evaluate_config_crypto_currencies_values(self):
     values_dict = {}
     evaluated_currencies = set()
     for crypto_currency_data in self.config[CONFIG_CRYPTO_CURRENCIES].values():
         pairs = crypto_currency_data[CONFIG_CRYPTO_PAIRS]
         if pairs:
             currency, market = split_symbol(pairs[0])
             if currency not in evaluated_currencies:
                 values_dict[currency] = await self._evaluate_value(currency, 1)
                 evaluated_currencies.add(currency)
             if market not in evaluated_currencies:
                 values_dict[market] = await self._evaluate_value(market, 1)
                 evaluated_currencies.add(market)
     return values_dict
示例#13
0
 async def _evaluate_config_crypto_currencies_values(self):
     values_dict = {}
     evaluated_currencies = set()
     for cryptocurrency in self.config[CONFIG_CRYPTO_CURRENCIES]:
         pairs = self.exchange.get_exchange_manager().get_traded_pairs(
             cryptocurrency)
         if pairs:
             currency, market = split_symbol(pairs[0])
             if currency not in evaluated_currencies:
                 values_dict[currency] = await self.evaluate_value(
                     currency, 1)
                 evaluated_currencies.add(currency)
             if market not in evaluated_currencies:
                 values_dict[market] = await self.evaluate_value(market, 1)
                 evaluated_currencies.add(market)
     return values_dict
def test_get_market_pair():
    config = load_config("tests/static/config.json")

    pair, inverted = ConfigManager.get_market_pair(
        config, config[CONFIG_TRADING][CONFIG_TRADER_REFERENCE_MARKET])
    assert pair == ""
    assert inverted is False

    pair, inverted = ConfigManager.get_market_pair(config, "")
    assert pair == ""
    assert inverted is False

    pair, inverted = ConfigManager.get_market_pair(config, "VEN")
    assert pair == "VEN/BTC"
    assert inverted is False

    pair, inverted = ConfigManager.get_market_pair(config, "USDT")
    assert pair == "BTC/USDT"
    assert inverted is True

    pair, inverted = ConfigManager.get_market_pair(config, "XBT")
    assert pair == ""
    assert inverted is False

    # now change config reference market
    config[CONFIG_TRADING][CONFIG_TRADER_REFERENCE_MARKET] = "USDT"

    pair, inverted = ConfigManager.get_market_pair(config, "BTC")
    assert pair == "BTC/USDT"
    assert inverted is False

    pair, inverted = ConfigManager.get_market_pair(config, "VEN")
    assert pair == ""
    assert inverted is False

    config[CONFIG_TRADING].pop(CONFIG_TRADER_REFERENCE_MARKET)

    # now use config/__init__.py reference market
    pair, inverted = ConfigManager.get_market_pair(config, "ADA")
    assert pair == "ADA/BTC"
    assert split_symbol(pair)[1] == DEFAULT_REFERENCE_MARKET
    assert inverted is False

    config.pop(CONFIG_TRADING)
    pair, inverted = ConfigManager.get_market_pair(config, "ADA")
    assert pair == ""
    assert inverted is False
    def __init__(self, trading_mode, symbol_evaluator, exchange, trader, creators):
        AbstractTradingModeDeciderWithBot.__init__(self, trading_mode, symbol_evaluator, exchange, trader, creators)
        Initializable.__init__(self)
        exchange_fees = max(exchange.get_fees(self.symbol).values())
        self.LONG_THRESHOLD = -2 * exchange_fees
        self.SHORT_THRESHOLD = 2 * exchange_fees
        self.filled_creators = []
        self.pending_creators = []
        self.blocked_creators = []

        self.currency, self.market = split_symbol(self.symbol)
        market_status = exchange.get_market_status(self.symbol)
        self.currency_max_digits = get_value_or_default(market_status[Ecmsc.PRECISION.value],
                                                        Ecmsc.PRECISION_PRICE.value,
                                                        CURRENCY_DEFAULT_MAX_PRICE_DIGITS)
        limit_cost = market_status[Ecmsc.LIMITS.value][Ecmsc.LIMITS_COST.value]
        self.currency_min_cost = get_value_or_default(limit_cost, Ecmsc.LIMITS_COST_MIN.value)
示例#16
0
    async def can_create_order(symbol, exchange, state, portfolio):
        currency, market = split_symbol(symbol)

        # get symbol min amount when creating order
        symbol_limit = exchange.get_market_status(symbol)[Ecmsc.LIMITS.value]
        symbol_min_amount = symbol_limit[Ecmsc.LIMITS_AMOUNT.value][Ecmsc.LIMITS_AMOUNT_MIN.value]
        order_min_amount = symbol_limit[Ecmsc.LIMITS_COST.value][Ecmsc.LIMITS_COST_MIN.value]

        # short cases => sell => need this currency
        if state == EvaluatorStates.VERY_SHORT or state == EvaluatorStates.SHORT:
            return portfolio.get_currency_portfolio(currency) > symbol_min_amount

        # long cases => buy => need money(aka other currency in the pair) to buy this currency
        elif state == EvaluatorStates.LONG or state == EvaluatorStates.VERY_LONG:
            return portfolio.get_currency_portfolio(market) > order_min_amount

        # other cases like neutral state or unfulfilled previous conditions
        return False
示例#17
0
    async def get_pre_order_data(exchange, symbol, portfolio):
        last_prices = await exchange.execute_request_with_retry(exchange.get_recent_trades(symbol))

        reference_sum = sum([float(last_price["price"])
                             for last_price in last_prices[-ORDER_CREATION_LAST_TRADES_TO_USE:]])

        reference = reference_sum / ORDER_CREATION_LAST_TRADES_TO_USE

        currency, market = split_symbol(symbol)

        current_symbol_holding = portfolio.get_currency_portfolio(currency)
        current_market_quantity = portfolio.get_currency_portfolio(market)

        market_quantity = current_market_quantity / reference

        price = reference
        symbol_market = exchange.get_market_status(symbol, with_fixer=False)

        return current_symbol_holding, current_market_quantity, market_quantity, price, symbol_market
示例#18
0
    def new(self,
            order_type,
            symbol,
            current_price,
            quantity,
            price=None,
            stop_price=None,
            status=None,
            order_notifier=None,
            order_id=None,
            quantity_filled=None,
            timestamp=None,
            linked_to=None,
            linked_portfolio=None):

        self.order_id = order_id
        self.origin_price = price
        self.status = status
        self.created_last_price = current_price
        self.origin_quantity = quantity
        self.origin_stop_price = stop_price
        self.symbol = symbol
        self.order_type = order_type
        self.order_notifier = order_notifier
        self.currency, self.market = split_symbol(symbol)
        self.filled_quantity = quantity_filled
        self.linked_to = linked_to
        self.linked_portfolio = linked_portfolio

        if timestamp is None:
            self.creation_time = time.time()
        else:
            # if we have a timestamp, it's a real trader => need to format timestamp if necessary
            self.creation_time = self.exchange.get_uniform_timestamp(timestamp)

        if status is None:
            self.status = OrderStatus.OPEN
        else:
            self.status = status

        if self.trader.simulate:
            self.filled_quantity = quantity
示例#19
0
    def get_pre_order_data(exchange, symbol, portfolio):
        last_prices = exchange.get_recent_trades(symbol)
        reference_sum = 0

        for last_price in last_prices[-ORDER_CREATION_LAST_TRADES_TO_USE:]:
            reference_sum += float(last_price["price"])

        reference = reference_sum / ORDER_CREATION_LAST_TRADES_TO_USE

        currency, market = split_symbol(symbol)

        current_symbol_holding = portfolio.get_currency_portfolio(currency)
        current_market_quantity = portfolio.get_currency_portfolio(market)

        market_quantity = current_market_quantity / reference

        price = reference
        symbol_market = exchange.get_market_status(symbol)

        return current_symbol_holding, current_market_quantity, market_quantity, price, symbol_market
示例#20
0
    def __init__(self, trading_mode, symbol_evaluator, exchange, trader,
                 creators):
        super().__init__(trading_mode, symbol_evaluator, exchange, trader,
                         creators)
        exchange_fees = max(exchange.get_fees(self.symbol))
        self.LONG_THRESHOLD = -2 * exchange_fees
        self.SHORT_THRESHOLD = 2 * exchange_fees
        self.filled_creators = []
        self.pending_creators = []
        self.blocked_creators = []

        self.currency, self.market = split_symbol(self.symbol)
        market_status = exchange.get_market_status(self.symbol)
        self.currency_max_digits = HighFrequencyModeCreator.get_value_or_default(
            market_status[Ecmsc.PRECISION.value], Ecmsc.PRECISION_PRICE.value,
            CURRENCY_DEFAULT_MAX_PRICE_DIGITS)
        limit_cost = market_status[Ecmsc.LIMITS.value][Ecmsc.LIMITS_COST.value]
        self.currency_min_cost = HighFrequencyModeCreator.get_value_or_default(
            limit_cost, Ecmsc.LIMITS_COST_MIN.value)
        self._update_available_creators()
    async def create_buy_order(self, volume_weight, trader, portfolio, symbol,
                               exchange):

        current_order = None
        try:
            current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \
                await self.get_pre_order_data(exchange, symbol, portfolio)

            quote, _ = split_symbol(symbol)
            created_orders = []
            quantity = await self._get_buy_quantity_from_weight(
                volume_weight, trader, market_quantity, portfolio, quote)
            limit_price = self.adapt_price(symbol_market,
                                           self.get_limit_price(price))
            for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                    quantity, limit_price, symbol_market):
                current_order = trader.create_order_instance(
                    order_type=TraderOrderType.BUY_LIMIT,
                    symbol=symbol,
                    current_price=price,
                    quantity=order_quantity,
                    price=order_price)
                created_order = await trader.create_order(
                    current_order, portfolio)
                created_orders.append(created_order)
            return created_orders

        except InsufficientFunds as e:
            raise e

        except Exception as e:
            self.logger.error(
                f"Failed to create order : {e}. Order: "
                f"{current_order.get_string_info() if current_order else None}"
            )
            self.logger.exception(e)
            return []
示例#22
0
async def test_evaluator_factory_with_wildcard():
    btc_crypto_currency = "Bitcoin"
    btc_quote = "BTC"
    exchange = "binance"
    config = load_test_config()
    config[CONFIG_CRYPTO_CURRENCIES] = {
        btc_crypto_currency: {
            CONFIG_CRYPTO_PAIRS: CONFIG_WILDCARD,
            CONFIG_CRYPTO_QUOTE: btc_quote
        }
    }
    bot = create_bot_with_config(config)
    await bot.initialize()

    symbol_count = len(
        set([
            symbol if split_symbol(symbol)[1] == btc_quote else None
            for symbol in bot.evaluator_factory.octobot.exchange_factory.
            exchanges_list['binance'].exchange.client.symbols
        ])) - 1  # -1 for 1 None (set consequence)

    perform_evaluator_factory_tests(bot.evaluator_factory, btc_crypto_currency,
                                    "ETH/BTC", exchange, 1, 1, symbol_count,
                                    symbol_count)
    async def create_sell_orders(self, sell_orders_count, trader, portfolio,
                                 symbol, exchange, quantity, sell_weight,
                                 sell_base):
        current_order = None
        try:
            current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \
                await self.get_pre_order_data(exchange, symbol, portfolio)

            quote, _ = split_symbol(symbol)
            created_orders = []
            sell_max_quantity = min(current_symbol_holding, quantity)
            to_create_orders = self._generate_sell_orders(
                sell_orders_count, sell_max_quantity, sell_weight, sell_base,
                symbol_market)
            for order_quantity, order_price in to_create_orders:
                current_order = trader.create_order_instance(
                    order_type=TraderOrderType.SELL_LIMIT,
                    symbol=symbol,
                    current_price=sell_base,
                    quantity=order_quantity,
                    price=order_price)
                created_order = await trader.create_order(
                    current_order, portfolio)
                created_orders.append(created_order)
            return created_orders

        except InsufficientFunds as e:
            raise e

        except Exception as e:
            self.logger.error(
                f"Failed to create order : {e}. Order: "
                f"{current_order.get_string_info() if current_order else None}"
            )
            self.logger.exception(e)
            return []
示例#24
0
def update_starting_portfolio_if_required(config, wanted_symbol):
    quote, base = split_symbol(wanted_symbol)
    if DEFAULT_REFERENCE_MARKET != base:
        _switch_reference_market(config, base)
示例#25
0
 def init_traded_currencies_without_market_specific(self):
     for crypto_currency in self.config[CONFIG_CRYPTO_CURRENCIES].values():
         for pair in crypto_currency[CONFIG_CRYPTO_PAIRS]:
             symbol, _ = split_symbol(pair)
             if symbol not in self.traded_currencies_without_market_specific:
                 self.traded_currencies_without_market_specific.add(symbol)
示例#26
0
 def _is_tradable_with_cryptocurrency(symbol, cryptocurrency):
     return symbol if split_symbol(symbol)[1] == cryptocurrency else None
示例#27
0
    async def create_new_order(self, eval_note, symbol, exchange, trader,
                               portfolio, state):
        current_order = None
        try:
            current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \
                await self.get_pre_order_data(exchange, symbol, portfolio)

            quote, _ = split_symbol(symbol)
            created_orders = []

            if state == EvaluatorStates.VERY_SHORT:
                quantity = self._get_market_quantity_from_risk(
                    eval_note, trader, current_symbol_holding, quote, True)
                quantity = self.add_dusts_to_quantity_if_necessary(
                    quantity, price, symbol_market, current_symbol_holding)
                for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                        quantity, price, symbol_market):
                    current_order = trader.create_order_instance(
                        order_type=TraderOrderType.SELL_MARKET,
                        symbol=symbol,
                        current_price=order_price,
                        quantity=order_quantity,
                        price=order_price)
                    await trader.create_order(current_order, portfolio)
                    created_orders.append(current_order)
                return created_orders

            elif state == EvaluatorStates.SHORT:
                quantity = await self._get_sell_limit_quantity_from_risk(
                    eval_note, trader, current_symbol_holding, portfolio,
                    quote)
                quantity = self.add_dusts_to_quantity_if_necessary(
                    quantity, price, symbol_market, current_symbol_holding)
                limit_price = self.adapt_price(
                    symbol_market,
                    price * self._get_limit_price_from_risk(eval_note, trader))
                for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                        quantity, limit_price, symbol_market):
                    current_order = trader.create_order_instance(
                        order_type=TraderOrderType.SELL_LIMIT,
                        symbol=symbol,
                        current_price=price,
                        quantity=order_quantity,
                        price=order_price)
                    updated_limit = await trader.create_order(
                        current_order, portfolio)
                    created_orders.append(updated_limit)

                    if self.USE_STOP_ORDERS:
                        stop_price = self.adapt_price(
                            symbol_market,
                            price * self._get_stop_price_from_risk(trader))
                        current_order = trader.create_order_instance(
                            order_type=TraderOrderType.STOP_LOSS,
                            symbol=symbol,
                            current_price=price,
                            quantity=order_quantity,
                            price=stop_price,
                            linked_to=updated_limit)
                        await trader.create_order(current_order, portfolio)
                return created_orders

            elif state == EvaluatorStates.NEUTRAL:
                pass

            # TODO : stop loss
            elif state == EvaluatorStates.LONG:
                quantity = self._get_buy_limit_quantity_from_risk(
                    eval_note, trader, market_quantity, quote)
                quantity = quantity * await self._get_quantity_ratio(
                    trader, portfolio, quote)
                limit_price = self.adapt_price(
                    symbol_market,
                    price * self._get_limit_price_from_risk(eval_note, trader))
                for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                        quantity, limit_price, symbol_market):
                    current_order = trader.create_order_instance(
                        order_type=TraderOrderType.BUY_LIMIT,
                        symbol=symbol,
                        current_price=price,
                        quantity=order_quantity,
                        price=order_price)
                    await trader.create_order(current_order, portfolio)
                    created_orders.append(current_order)
                return created_orders

            elif state == EvaluatorStates.VERY_LONG:
                quantity = self._get_market_quantity_from_risk(
                    eval_note, trader, market_quantity, quote)
                quantity = quantity * await self._get_quantity_ratio(
                    trader, portfolio, quote)
                for order_quantity, order_price in self.check_and_adapt_order_details_if_necessary(
                        quantity, price, symbol_market):
                    current_order = trader.create_order_instance(
                        order_type=TraderOrderType.BUY_MARKET,
                        symbol=symbol,
                        current_price=order_price,
                        quantity=order_quantity,
                        price=order_price)
                    await trader.create_order(current_order, portfolio)
                    created_orders.append(current_order)
                return created_orders

            # if nothing go returned, return None
            return None

        except InsufficientFunds as e:
            raise e

        except Exception as e:
            self.logger.error(
                f"Failed to create order : {e}. "
                f"Order: "
                f"{current_order.get_string_info() if current_order else None}"
            )
            self.logger.exception(e)
            return None
示例#28
0
 def get_pairs(config, currency) -> []:
     pairs = []
     for symbol in ConfigManager.get_symbols(config):
         if currency in split_symbol(symbol):
             pairs.append(symbol)
     return pairs
    def _create_orders(self, lower_bound, upper_bound, side, sorted_orders,
                       portfolio, current_price, missing_orders, state):

        if lower_bound >= upper_bound:
            self.logger.warning(f"No {side} orders for {self.symbol} possible: current price beyond boundaries.")
            return []

        orders = []
        selling = side == TradeOrderSide.SELL

        currency, market = split_symbol(self.symbol)
        order_limiting_currency = currency if selling else market

        order_limiting_currency_amount = portfolio[order_limiting_currency][Portfolio.AVAILABLE] \
            if order_limiting_currency in portfolio else 0
        if state == self.NEW:
            # create staggered orders

            starting_bound = lower_bound * (1 + self.spread / 2) if selling else upper_bound * (1 - self.spread / 2)
            self.flat_spread = AbstractTradingModeCreator.adapt_price(self.symbol_market,
                                                                      current_price * self.spread)
            orders_count, average_order_quantity = \
                self._get_order_count_and_average_quantity(current_price, selling, lower_bound,
                                                           upper_bound, order_limiting_currency_amount,
                                                           currency=order_limiting_currency)
            for i in range(orders_count):
                price = self._get_price_from_iteration(starting_bound, selling, i)
                if price is not None:
                    quantity = self._get_quantity_from_iteration(average_order_quantity, self.mode,
                                                                 side, i, orders_count, price)
                    if quantity is not None:
                        orders.append(OrderData(side, quantity, price, self.symbol))
            if not orders:
                self.logger.error(f"Not enough {order_limiting_currency} to create {side.name} orders. "
                                  f"For the strategy to work better, add {order_limiting_currency} funds or "
                                  f"change change the strategy settings to make less but bigger orders.")
            else:
                orders.reverse()

        if state == self.FILL:
            # complete missing orders
            if missing_orders:
                max_quant_per_order = order_limiting_currency_amount / len(missing_orders)
                missing_orders_around_spread = []
                for missing_order_price, missing_order_side in missing_orders:
                    if missing_order_side == side:
                        previous_o = None
                        following_o = None
                        for o in sorted_orders:
                            if previous_o is None:
                                previous_o = o
                            elif o.origin_price > missing_order_price:
                                following_o = o
                                break
                            else:
                                previous_o = o
                        if previous_o.side == following_o.side:
                            # missing order between similar orders
                            quantity = min(DataUtil.mean([previous_o.origin_quantity, following_o.origin_quantity]),
                                           max_quant_per_order / missing_order_price)
                            orders.append(OrderData(missing_order_side, quantity,
                                                    missing_order_price, self.symbol, False))
                            self.logger.debug(f"Creating missing orders not around spread: {orders[-1]}")
                        else:
                            missing_orders_around_spread.append((missing_order_price, missing_order_side))

                if missing_orders_around_spread:
                    # missing order next to spread
                    starting_bound = upper_bound if selling else lower_bound
                    increment_window = self.flat_increment/2
                    order_limiting_currency_available_amount = \
                        portfolio[order_limiting_currency][Portfolio.AVAILABLE] \
                        if order_limiting_currency in portfolio else 0
                    portfolio_total = portfolio[order_limiting_currency][Portfolio.TOTAL] \
                        if order_limiting_currency in portfolio else 0
                    order_limiting_currency_amount = portfolio_total
                    if order_limiting_currency_available_amount:
                        orders_count, average_order_quantity = \
                            self._get_order_count_and_average_quantity(current_price, selling, lower_bound,
                                                                       upper_bound, portfolio_total,
                                                                       currency=order_limiting_currency)
                        for missing_order_price, missing_order_side in missing_orders_around_spread:
                            limiting_amount_from_this_order = order_limiting_currency_amount
                            price = starting_bound
                            found_order = False
                            i = 0
                            while not found_order and i < orders_count:
                                quantity = self._get_quantity_from_iteration(average_order_quantity, self.mode,
                                                                             side, i, orders_count,
                                                                             price)
                                limiting_currency_quantity = quantity if selling else quantity / price
                                if price is not None and limiting_amount_from_this_order > 0 and \
                                        price-increment_window <= missing_order_price <= price+increment_window:

                                    if limiting_currency_quantity > limiting_amount_from_this_order or \
                                            limiting_currency_quantity > order_limiting_currency_available_amount:
                                        limiting_currency_quantity = min(limiting_amount_from_this_order,
                                                                         order_limiting_currency_available_amount)
                                    found_order = True
                                    if limiting_currency_quantity is not None:
                                        orders.append(OrderData(side, limiting_currency_quantity, price,
                                                                self.symbol, False))
                                        self.logger.debug(f"Creating missing order around spread {orders[-1]}")
                                price = price - self.flat_increment if selling else price + self.flat_increment
                                limiting_amount_from_this_order -= limiting_currency_quantity
                                i += 1

        elif state == self.ERROR:
            self.logger.error("Impossible to create staggered orders when incompatible order are already in place. "
                              "Cancel these orders of you want to use this trading mode.")
        return orders
示例#30
0
def get_currency_price_graph_update(exchange_name,
                                    symbol,
                                    time_frame,
                                    list_arrays=True,
                                    backtesting=False):
    bot = get_bot()
    if backtesting and bot.get_tools() and bot.get_tools(
    )[BOT_TOOLS_BACKTESTING]:
        bot = bot.get_tools()[BOT_TOOLS_BACKTESTING].get_bot()
    symbol = parse_get_symbol(symbol)
    symbol_evaluator_list = bot.get_symbol_evaluator_list()
    in_backtesting = Backtesting.enabled(get_global_config()) or backtesting

    exchange = exchange_name
    exchange_list = bot.get_exchanges_list()
    if backtesting:
        exchanges = [key for key in exchange_list if exchange_name in key]
        if exchanges:
            exchange = exchanges[0]

    if time_frame is not None:
        if symbol_evaluator_list:
            evaluator_thread_managers = symbol_evaluator_list[
                symbol].get_evaluator_thread_managers(exchange_list[exchange])

            if time_frame in evaluator_thread_managers:
                evaluator_thread_manager = evaluator_thread_managers[
                    time_frame]
                data = evaluator_thread_manager.get_evaluator().get_data()

                if data is not None:

                    candles_key = "candles"
                    real_trades_key = "real_trades"
                    simulated_trades_key = "simulated_trades"
                    result_dict = {
                        candles_key: [],
                        real_trades_key: [],
                        simulated_trades_key: [],
                    }

                    _, pair_tag = split_symbol(symbol)
                    add_to_symbol_data_history(symbol, data, time_frame,
                                               in_backtesting)
                    data = get_symbol_data_history(symbol, time_frame)

                    data_x = convert_timestamps_to_datetime(
                        data[PriceIndexes.IND_PRICE_TIME.value],
                        time_format="%y-%m-%d %H:%M:%S",
                        force_timezone=False)

                    real_trades_history, simulated_trades_history = get_trades_history(
                        bot, symbol)

                    if real_trades_history:
                        result_dict[real_trades_key] = _format_trades(
                            real_trades_history)

                    if real_trades_history:
                        result_dict[simulated_trades_key] = _format_trades(
                            simulated_trades_history)

                    if list_arrays:
                        result_dict[candles_key] = {
                            PriceStrings.STR_PRICE_TIME.value:
                            data_x,
                            PriceStrings.STR_PRICE_CLOSE.value:
                            data[PriceIndexes.IND_PRICE_CLOSE.value].tolist(),
                            PriceStrings.STR_PRICE_LOW.value:
                            data[PriceIndexes.IND_PRICE_LOW.value].tolist(),
                            PriceStrings.STR_PRICE_OPEN.value:
                            data[PriceIndexes.IND_PRICE_OPEN.value].tolist(),
                            PriceStrings.STR_PRICE_HIGH.value:
                            data[PriceIndexes.IND_PRICE_HIGH.value].tolist()
                        }
                    else:
                        result_dict[candles_key] = {
                            PriceStrings.STR_PRICE_TIME.value:
                            data_x,
                            PriceStrings.STR_PRICE_CLOSE.value:
                            data[PriceIndexes.IND_PRICE_CLOSE.value],
                            PriceStrings.STR_PRICE_LOW.value:
                            data[PriceIndexes.IND_PRICE_LOW.value],
                            PriceStrings.STR_PRICE_OPEN.value:
                            data[PriceIndexes.IND_PRICE_OPEN.value],
                            PriceStrings.STR_PRICE_HIGH.value:
                            data[PriceIndexes.IND_PRICE_HIGH.value]
                        }
                    return result_dict
    return None