예제 #1
0
def test_enact_order(create_exchange):
    # Create a trade
    exchange = copy.copy(create_exchange)
    exchange.reset()
    trade_price = exchange.current_price(symbol="ETH")
    trade_1 = Trade(0, "ETH", TradeType.LIMIT_BUY, 100, trade_price)
    exchange._next_observation()
    exchange.execute_trade(trade_1)

    trade_2 = Trade(1, "ETH", TradeType.LIMIT_BUY, 100, trade_price)
    exchange._next_observation()
    exchange.execute_trade(trade_2)

    trade_price = exchange.current_price(symbol="ETH")
    trade_3 = Trade(2, "ETH", TradeType.LIMIT_SELL, 73, trade_price)
    exchange._next_observation()
    exchange.execute_trade(trade_3)

    trade_4 = Trade(3, "ETH", TradeType.LIMIT_SELL, 50, trade_price)
    exchange._next_observation()
    exchange.execute_trade(trade_4)

    trade_5 = Trade(4, "ETH", TradeType.LIMIT_SELL, 25, trade_price)
    exchange._next_observation()
    exchange.execute_trade(trade_5)

    # Check that we're 5 trades in.
    assert len(exchange.trades) == 5
    assert exchange._current_step == 5
예제 #2
0
    def test_reward_invalid_trade_type_input(self):
        scheme = SimpleProfit()
        scheme.reset()

        # Create the first trade
        trade_1 = Trade(0, "BTC", 1, 100, 1500)
        trade_2 = Trade(2, "BTC", TradeType.LIMIT_SELL, 100, 1300)

        scheme.get_reward(0, trade_1)
        reward1 = scheme.get_reward(2, trade_2)
        assert reward1 == -1015.5908812273915
예제 #3
0
    def test_raise_reward(self):
        scheme = SimpleProfit()
        scheme.reset()

        # Create the first trade
        trade_1 = Trade(0, "BTC", TradeType.LIMIT_BUY, 100, 1000)
        trade_2 = Trade(2, "BTC", TradeType.LIMIT_SELL, 100, 1500)

        scheme.get_reward(0, trade_1)
        reward1 = scheme.get_reward(2, trade_2)
        
        assert reward1 == 1926.0370135765718
예제 #4
0
    def get_trade(self, current_step: int, action: TradeActionUnion) -> Trade:
        """The trade type is determined by `action % len(TradeType)`, and the trade amount is determined by the multiplicity of the action.

        For example, 1 = LIMIT_BUY|0.25, 2 = MARKET_BUY|0.25, 6 = LIMIT_BUY|0.5, 7 = MARKET_BUY|0.5, etc.
        """
        n_splits = self.n_actions / len(TradeType)
        trade_type = TradeType(action % len(TradeType))
        trade_amount = int(action / len(TradeType)) * float(1 / n_splits) + (
            1 / n_splits)

        current_price = self._exchange.current_price(symbol=self._instrument)
        base_precision = self._exchange.base_precision
        instrument_precision = self._exchange.instrument_precision

        amount = self._exchange.instrument_balance(self._instrument)
        price = current_price

        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            amount = round(
                self._exchange.balance * 0.99 * trade_amount / price,
                instrument_precision)

        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount_held = self._exchange.portfolio.get(self._instrument, 0)
            amount = round(amount_held * trade_amount, instrument_precision)

        return Trade(current_step, self._instrument, trade_type, amount, price)
    def get_trade(self, action: TradeActionUnion) -> Trade:
        """
        The trade type is determined by `action`, when there are only three types of trades:
        hold, buy and sell, implied by FutureTradeType.
        将action转化成position和trade
        """
        size = (self.action_space.n -1)/2
        position = (action - size) / size

        '''
        比如说n = 5, 生成01234五种动作,实际上对应的持仓大小应该是-1 -0.5 0 0.5 1
        '''
        change = position - self.last_position

        if change > 0.001:
            trade_type = FutureTradeType.BUY
        elif change < -0.001:
            trade_type = FutureTradeType.SELL
        else:
            trade_type = FutureTradeType.HOLD

        amount = abs(change)
        price = self._exchange.current_price(symbol=self.instrument_symbol)
        next_price = self._exchange.next_price(symbol=self.instrument_symbol)
        self.last_position = position
        return Trade(self.instrument_symbol, trade_type, amount, price, next_price)
예제 #6
0
    def fill_order(self, trade: Trade, current_price: float) -> Trade:
        amount_slippage = np.random.uniform(
            0, self.max_amount_slippage_percent / 100)
        price_slippage = np.random.uniform(
            0, self.max_price_slippage_percent / 100)

        fill_amount = trade.amount * (1 - amount_slippage)
        fill_price = current_price

        if trade.trade_type is TradeType.MARKET_BUY:
            fill_price = current_price * (1 + price_slippage)
        elif trade.trade_type is TradeType.LIMIT_BUY:
            fill_price = max(current_price * (1 + price_slippage), 1e-3)

            if fill_price > trade.price:
                fill_price = trade.price
                fill_amount *= trade.price / fill_price

        elif trade.trade_type is TradeType.MARKET_SELL:
            fill_price = current_price * (1 - price_slippage)
        elif trade.trade_type is TradeType.LIMIT_SELL:
            fill_price = max(current_price * (1 - price_slippage), 1e-3)

            if fill_price < trade.price:
                fill_price = trade.price
                fill_amount *= fill_price / trade.price

        return Trade(trade.step,
                     trade.symbol,
                     trade.trade_type,
                     amount=fill_amount,
                     price=fill_price)
    def _execute_sell_order(self, order: 'Order', base_wallet: 'Wallet',
                            quote_wallet: 'Wallet',
                            current_price: float) -> Trade:
        price = self._contain_price(current_price)

        if order.type == TradeType.LIMIT and order.price > current_price:
            return None

        commission = Quantity(order.pair.base, order.size * self._commission,
                              order.path_id)
        size = self._contain_size(order.size - commission.size)
        quantity = Quantity(order.pair.base, size, order.path_id)

        trade = Trade(order_id=order.id,
                      exchange_id=self.id,
                      step=self.clock.step,
                      pair=order.pair,
                      side=TradeSide.SELL,
                      trade_type=order.type,
                      quantity=quantity,
                      price=price,
                      commission=commission)

        # self._slippage_model.adjust_trade(trade)

        quote_size = trade.size / trade.price * (trade.price / order.price)

        quote_wallet -= Quantity(order.pair.quote, quote_size, order.path_id)
        base_wallet += quantity
        base_wallet -= commission

        return trade
예제 #8
0
    def execute_trade(self, trade: Trade) -> Trade:
        if trade.trade_type == TradeType.LIMIT_BUY:
            order = self._exchange.create_limit_buy_order(symbol=trade.symbol,
                                                          amount=trade.amount,
                                                          price=trade.price)
        elif trade.trade_type == TradeType.MARKET_BUY:
            order = self._exchange.create_market_buy_order(symbol=trade.symbol,
                                                           amount=trade.amount)
        elif trade.trade_type == TradeType.LIMIT_SELL:
            order = self._exchange.create_limit_sell_order(symbol=trade.symbol,
                                                           amount=trade.amount,
                                                           price=trade.price)
        elif trade.trade_type == TradeType.MARKET_SELL:
            order = self._exchange.create_market_sell_order(
                symbol=trade.symbol, amount=trade.amount)

        max_wait_time = time.time() + self._max_trade_wait_in_sec

        while order['status'] is 'open' and time.time() < max_wait_time:
            order = self._exchange.fetch_order(order.id)

        if order['status'] is 'open':
            self._exchange.cancel_order(order.id)

        self._performance.append(
            {
                'balance': self.balance,
                'net_worth': self.net_worth,
            },
            ignore_index=True)

        return Trade(symbol=trade.symbol,
                     trade_type=trade.trade_type,
                     amount=order['filled'],
                     price=order['price'])
예제 #9
0
    def get_trade(self, action: TradeActionUnion) -> Trade:
        action_type, trade_amount = action
        trade_type = TradeType(int(action_type * len(TradeType)))

        current_price = self._exchange.current_price(
            symbol=self.instrument_symbol)
        base_precision = self._exchange.base_precision
        instrument_precision = self._exchange.instrument_precision

        amount = self._exchange.instrument_balance(self.instrument_symbol)
        price = current_price

        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            amount = round(
                self._exchange.balance * 0.99 * trade_amount / price,
                instrument_precision)

        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount_held = self._exchange.portfolio.get(self.instrument_symbol,
                                                       0)
            amount = round(amount_held * trade_amount, instrument_precision)

        return Trade(self.instrument_symbol, trade_type, amount, price)
예제 #10
0
    def get_trade(self, current_step: int, action: TradeActionUnion) -> Trade:
        """The trade type is determined by `action % len(TradeType)`, and the trade amount is determined by the multiplicity of the action.
        获取Trade对象,交易类型,由 action % len(TradeType)决定, 交易数量, 根据action 动作对应级别获取

        For example, 1 = LIMIT_BUY|0.25, 2 = MARKET_BUY|0.25, 6 = LIMIT_BUY|0.5, 7 = MARKET_BUY|0.5, etc.
        """
        # 每个交易动作,对应的操作仓位份数。 20/ 5 = 4
        n_splits = self.n_actions / len(TradeType)

        # 交易类型 0 ~4 % 5
        trade_type = TradeType(action % len(TradeType))

        # 交易仓位, action/len(TradeType) +1 => 交易数量份数( 1~5) => 乘以每一份
        trade_amount_percent = int(action / len(TradeType)) * float(
            1 / n_splits) + (1 / n_splits)

        # 当前交易合约价格
        current_price = self._exchange.current_price(symbol=self._instrument)
        # 基准合约价格精度
        base_precision = self._exchange.base_precision
        # 交易合约价格精度
        instrument_precision = self._exchange.instrument_precision
        # 当前合约持仓数量
        amount = self._exchange.instrument_balance(self._instrument)
        # 当前价格
        price = current_price

        # 市价/限价买入
        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            # 滑点调整=》价格
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            # 精度修正=》价格
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            #  账号基准净值 * 仓位比例 / 价格 =》 修正 =》 买入交易合约数量
            amount = round(
                self._exchange.balance * 0.99 * trade_amount_percent / price,
                instrument_precision)
        # 市价卖出/限价卖出
        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            #  滑点调整=》价格
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)

            # 精度修正=》价格
            price = round(current_price * price_adjustment, base_precision)

            # 交易合约当前持仓数量
            amount_held = self._exchange.portfolio.get(self._instrument, 0)

            # 持仓数量 * 仓位比例 => 修正 =》 卖出交易合约数量
            amount = round(amount_held * trade_amount_percent,
                           instrument_precision)

        # 交易合约,交易类型,交易数量,交易价格 =》 Trade 对象
        return Trade(current_step, self._instrument, trade_type, amount, price)
예제 #11
0
def test_slippage_trade():
    """ Make sure the slippage is not zero. """
    trade_2 = Trade(2, "BTC", TradeType.LIMIT_SELL, 100, 1300)
    slippage = RandomUniformSlippageModel(max_amount_slippage_percent=3.0)
    slipped_trade = slippage.fill_order(trade_2, 1300)

    # print(slipped_trade._price, slipped_trade._amount)
    assert slipped_trade.symbol == "BTC"
    assert slipped_trade.trade_type == TradeType.LIMIT_SELL
    assert slipped_trade.amount != trade_2.amount
예제 #12
0
    def reset(self) -> pd.DataFrame:
        """Resets the state of the environment and returns an initial observation.

        Returns:
            observation: the initial observation.
        """
        self._action_strategy.reset()
        self._reward_strategy.reset()
        self._exchange.reset()

        self._current_step = 0

        return self._next_observation(Trade('N/A', 'hold', 0, 0))
예제 #13
0
    def get_trade(self, current_step: int, action: TradeActionUnion) -> Trade:
        """
        get a new Trade object. 根据action参数,获取一个新的Trade对象
        :param action: 交易动作类型,(tuple)
        :return:
        """
        # 动作类型(int), 交易仓位(0~1)
        action_type, trade_amount_percent = action
        # 交易类型
        trade_type = TradeType(int(action_type * len(TradeType)))

        # 获取合约的当前价格
        current_price = self._exchange.current_price(symbol=self._instrument)
        # 获取基准合约价格精度(例如USDT)
        base_precision = self._exchange.base_precision
        # 获取交易合约价格精度(例如BTC)
        instrument_precision = self._exchange.instrument_precision

        # 当前持有的
        # 获取交易合约当前持仓数量
        amount = self._exchange.instrument_balance(self._instrument)
        price = current_price

        # 市价买入/限价买入
        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            # 滑点调整=》价格
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            # 精度修正=》价格
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            # 账号基准净值 * 仓位比例 / 价格 =》 修正 =》 买入交易合约数量
            amount = round(
                self._exchange.balance * 0.99 * trade_amount_percent / price,
                instrument_precision)

        # 市价卖出/限价卖出
        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            #  滑点调整=》价格
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
            # 精度修正=》价格
            price = round(current_price * price_adjustment, base_precision)
            # 交易合约当前持仓数量
            amount_held = self._exchange.portfolio.get(self._instrument, 0)
            # 持仓数量 * 仓位比例 => 修正 =》 卖出交易合约数量
            amount = round(amount_held * trade_amount_percent,
                           instrument_precision)

        # 交易合约,交易类型,交易数量,交易价格 =》 Trade 对象
        return Trade(current_step, self._instrument, trade_type, amount, price)
예제 #14
0
    def get_trade(self, action: TradeActionUnion) -> Trade:
        """
        The trade type is determined by `action`, when there are only three types of trades:
        hold, buy and sell, implied by FutureTradeType.
        ACTION is determined, by default, discrete(3), and it should only include (0,1,2) 
        """
        trade_type = FutureTradeType(action)
        amount = 0.1
        current_price = self._exchange.current_price(
            symbol=self.instrument_symbol)

        price = current_price

        return Trade(self.instrument_symbol, trade_type, amount, price)
예제 #15
0
    def fill_order(self, trade: Trade) -> Trade:
        fill_amount = trade.amount * (
            1 - np.random.uniform(0, self.max_amount_slippage_percent))
        fill_price = trade.price

        if trade.trade_type is TradeType.MARKET_BUY or trade.trade_type is TradeType.LIMIT_BUY:
            fill_price = trade.price * (
                1 + np.random.uniform(0, self.max_price_slippage_percent))
        elif trade.trade_type is TradeType.MARKET_SELL or trade.trade_type is TradeType.LIMIT_SELL:
            fill_price = trade.price * (
                1 - np.random.uniform(0, self.max_price_slippage_percent))

        return Trade(trade.symbol,
                     trade.trade_type,
                     amount=fill_amount,
                     price=fill_price)
    def get_trade(self, current_step: int, action: TradeActionUnion) -> Trade:
        """The trade type is determined by `action % len(TradeType)`, and the trade amount is determined by the multiplicity of the action.

        For example, 1 = LIMIT_BUY|0.25, 2 = MARKET_BUY|0.25, 6 = LIMIT_BUY|0.5, 7 = MARKET_BUY|0.5, etc.
        """
        # n_splits = self.n_actions / len(TradeType)
        # trade_type = TradeType(action % len(TradeType))
        # trade_amount = int(action / len(TradeType)) * float(1 / n_splits) + (1 / n_splits)

        if action == 3:
            amount = abs(self._exchange.total_position)
            if self._exchange.total_position > 0:
                trade_type = TradeType(2)
            else:
                trade_type = TradeType(1)
        else:
            trade_type = TradeType(action)
            amount = self.max_allowed_amount

        current_price = self._exchange.current_price(symbol=self._instrument)
        # base_precision = self._exchange.base_precision
        # instrument_precision = self._exchange.instrument_precision

        # amount = self._exchange.instrument_balance(self._instrument)

        price = current_price

        # # if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
        # if trade_type is TradeType.MARKET_LONG:
        #     price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
        #     price = max(round(current_price * price_adjustment, base_precision), base_precision)
        #     # amount = round(self._exchange.balance * 0.99 * trade_amount / price, instrument_precision)
        #     # amount = round((self._exchange.balance * self._exchange.leverage * price) / 10000) + 5
        #     # amount = self.max_allowed_amount
        #     # print('Position Size => ', amount, '    USDT')
        # # elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
        # elif trade_type is TradeType.MARKET_SHORT:
        #     price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
        #     price = round(current_price * price_adjustment, base_precision)
        #     amount_held = self._exchange.portfolio.get(self._instrument, 0)
        #     # amount = round(amount_held * trade_amount, instrument_precision)
        #     # amount = round((self._exchange.balance * self._exchange.leverage * price) / 10000) + 5
        #     # amount = self.max_allowed_amount
        #     # print('Position Size => ', amount, '    USDT')

        return Trade(current_step, self._instrument, trade_type, amount, price)
    def get_trade(self, action: TradeActionUnion) -> Trade:
        """The trade type is determined by `action % len(TradeType)`, and
        the trade amount is determined by the multiplicity of the action.

        For example:
            0 = HOLD
            1 = LIMIT_BUY|0.25
            2 = MARKET_BUY|0.25
            5 = HOLD
            6 = LIMIT_BUY|0.5
            7 = MARKET_BUY|0.5
            etc.
        """
        product_idx = int(action / self._actions_per_instrument)
        product = self._products[product_idx]

        n_splits = int(self._actions_per_instrument / len(TradeType))
        trade_type = TradeType(action % len(TradeType))
        trade_amount = int(action / len(TradeType)) * \
            float(1 / n_splits) + (1 / n_splits)
        trade_amount = trade_amount - product_idx

        current_price = self._exchange.current_price(symbol=product)
        base_precision = self._exchange.base_precision
        instrument_precision = self._exchange.instrument_precision

        amount = self._exchange.instrument_balance(product)
        price = current_price

        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            price_adjustment = 1 + (self._max_allowed_slippage_percent / 100)
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            amount = round(
                self._exchange.balance * 0.99 * trade_amount / price,
                instrument_precision)

        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            price_adjustment = 1 - (self._max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount_held = self._exchange.portfolio.get(product, 0)
            amount = round(amount_held * trade_amount, instrument_precision)

        return Trade(product, trade_type, amount, price)
예제 #18
0
    def _execute_buy_order(self, order: 'Order', base_wallet: 'Wallet',
                           quote_wallet: 'Wallet',
                           current_price: float) -> Trade:
        price = self._contain_price(current_price)

        if order.type == TradeType.LIMIT and order.price < current_price:
            return None

        commission = Quantity(order.pair.base, order.size * self._commission,
                              order.path_id)
        base_size = self._contain_size(order.size - commission.size)

        if order.type == TradeType.MARKET:
            scale = order.price / price
            base_size = self._contain_size(scale * order.size -
                                           commission.size)

        base_wallet -= commission

        try:
            quantity = Quantity(order.pair.base, base_size, order.path_id)
            base_wallet -= quantity
        except InsufficientFundsForAllocation:
            balance = base_wallet.locked[order.path_id]
            quantity = Quantity(order.pair.base, balance.size, order.path_id)
            base_wallet -= quantity

        quote_size = (order.price / price) * (quantity.size / price)
        quote_wallet += Quantity(order.pair.quote, quote_size, order.path_id)

        trade = Trade(order_id=order.id,
                      exchange_id=self.id,
                      step=self.clock.step,
                      pair=order.pair,
                      side=TradeSide.BUY,
                      trade_type=order.type,
                      quantity=quantity,
                      price=price,
                      commission=commission)

        # self._slippage_model.adjust_trade(trade)

        return trade
예제 #19
0
def execute_buy_order(order: 'Order', base_wallet: 'Wallet',
                      quote_wallet: 'Wallet', current_price: float,
                      options: 'ExchangeOptions', exchange_id: str,
                      clock: 'Clock') -> 'Trade':
    price = contain_price(current_price, options)

    if order.type == TradeType.LIMIT and order.price.rate < current_price:
        return None

    commission = Quantity(order.pair.base, order.size * options.commission,
                          order.path_id)
    size = contain_size(order.size - commission.size, options)

    if order.type == TradeType.MARKET:
        scale = order.price.rate / price
        print(scale * order.size - commission.size)
        size = contain_size(scale * order.size - commission.size, options)

    base_wallet -= commission

    try:
        quantity = Quantity(order.pair.base, size, order.path_id)
        base_wallet -= quantity
    except InsufficientFunds:
        balance = base_wallet.locked[order.path_id]
        quantity = Quantity(order.pair.base, balance.size, order.path_id)
        base_wallet -= quantity

    quote_size = (order.price.rate / price) * (size / price)
    quote_wallet += Quantity(order.pair.quote, quote_size, order.path_id)

    trade = Trade(order_id=order.id,
                  exchange_id=exchange_id,
                  step=clock.step,
                  pair=order.pair,
                  side=TradeSide.BUY,
                  trade_type=order.type,
                  quantity=quantity,
                  price=price,
                  commission=commission)

    return trade
    def get_trade(self, current_step: int, action: TradeActionUnion) -> Trade:

        if abs(float(action)) > 0.8:
            amount = abs(self._exchange.total_position)
            if self._exchange.total_position > 0:
                trade_type = TradeType(2)
            else:
                trade_type = TradeType(1)
        else:
            amount = self.max_allowed_amount
            if np.sign(action) > 0:
                trade_type = TradeType(1)
            elif np.sign(action) < 0:
                trade_type = TradeType(2)
            else:
                trade_type = TradeType(0)

        current_price = self._exchange.current_price(symbol=self._instrument)
        # base_precision = self._exchange.base_precision

        price = current_price

        # amount = self._exchange.instrument_balance(self._instrument)
        # if trade_type is TradeType.MARKET_LONG:
        #     price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
        #     price = max(round(current_price * price_adjustment, base_precision), base_precision)
        #     # amount = round(self._exchange.balance * 0.99 *
        #     #                trade_amount / price, instrument_precision)
        #
        #     amount = round(trade_amount * self.max_allowed_amount, instrument_precision)
        #     # amount = round(trade_amount * (self._exchange.balance * self._exchange.leverage * price) * self.max_allowed_amount_percent / 100, instrument_precision)
        #
        # elif trade_type is TradeType.MARKET_SHORT:
        #     price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
        #     price = round(current_price * price_adjustment, base_precision)
        #     # amount_held = self._exchange.portfolio.get(self._instrument, 0)
        #     # amount = round(amount_held * trade_amount, instrument_precision)
        #
        #     amount = round(trade_amount * self.max_allowed_amount, instrument_precision)
        #     # amount = round(trade_amount * (self._exchange.balance * self._exchange.leverage * price) * self.max_allowed_amount_percent / 100, instrument_precision)

        return Trade(current_step, self._instrument, trade_type, amount, price)
    def get_trade(self, action: TradeActionUnion) -> Trade:
        """The trade type is determined by `action % len(TradeType)`, and the trade amount is determined by the multiplicity of the action.

        For example, 1 = LIMIT_BUY|0.25, 2 = MARKET_BUY|0.25, 6 = LIMIT_BUY|0.5, 7 = MARKET_BUY|0.5, etc.
        """
        #print('action is' + str(action))
        n_splits = self.n_actions / len(TradeType)
        #4 = 20 / 5
        trade_type = TradeType(action % len(TradeType))
        #action 除以 TradeType 的 余数? action = 10
        trade_amount = int(action / len(TradeType)) * float(1 / n_splits) + (
            1 / n_splits)
        #int(10 / 5) * (1/4) + (1/4) = 0.75
        #这个应该是指买入的percent?
        current_price = self._exchange.current_price(
            symbol=self.instrument_symbol)
        base_precision = self._exchange.base_precision
        instrument_precision = self._exchange.instrument_precision

        amount = self._exchange.instrument_balance(self.instrument_symbol)
        #现在持有的量
        price = current_price

        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            price = max(
                round(current_price * price_adjustment, base_precision),
                base_precision)
            amount = round(
                self._exchange.balance * 0.99 * trade_amount / price,
                instrument_precision)
            #99%的balance * 0.75 / 价格, 意思就是交易量是75%的现金

        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount_held = self._exchange.portfolio.get(self.instrument_symbol,
                                                       0)
            amount = round(amount_held * trade_amount, instrument_precision)

        return Trade(self.instrument_symbol, trade_type, amount, price)
예제 #22
0
    def execute_order(self, order: 'Order', portfolio: 'Portfolio'):
        if order.type == TradeType.LIMIT and order.side == TradeSide.BUY:
            executed_order = self._exchange.create_limit_buy_order(
                order.symbol, order.size, order.price)
        elif order.type == TradeType.MARKET and order.side == TradeSide.BUY:
            executed_order = self._exchange.create_market_buy_order(
                order.symbol, order.size)
        elif order.type == TradeType.LIMIT and order.side == TradeSide.SELL:
            executed_order = self._exchange.create_limit_sell_order(
                order.symbol, order.size, order.price)
        elif order.type == TradeType.MARKET and order.side == TradeSide.SELL:
            executed_order = self._exchange.create_market_sell_order(
                order.symbol, order.size)
        else:
            return order.copy()

        max_wait_time = time.time() + self._max_trade_wait_in_sec

        while order['status'] == 'open' and time.time() < max_wait_time:
            executed_order = self._exchange.fetch_order(order.id)

        if order['status'] == 'open':
            self._exchange.cancel_order(order.id)
            order.cancel(self._exchange)

        trade = Trade(order_id=order.id,
                      exchange_id=self.id,
                      step=order.step,
                      pair=order.pair,
                      side=order.side,
                      trade_type=order.type,
                      quantity=executed_order['filled'] * order.pair.base,
                      price=executed_order['price'],
                      commission=executed_order['commission'] *
                      order.pair.base)

        order.fill(self, trade)
    def get_trade(self, action: TradeActionUnion) -> Trade:
        trade_type = TradeType(action % len(TradeType))
        trade_amount = float(1 / (action % self.n_bins + 1))

        current_price = self._exchange.current_price(symbol=self.asset_symbol)
        base_precision = self._exchange.base_precision
        asset_precision = self._exchange.asset_precision

        amount = 0
        price = current_price

        if trade_type is TradeType.MARKET_BUY or trade_type is TradeType.LIMIT_BUY:
            price_adjustment = 1 + (self.max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount = round(self._exchange.balance * trade_amount / price,
                           asset_precision)

        elif trade_type is TradeType.MARKET_SELL or trade_type is TradeType.LIMIT_SELL:
            price_adjustment = 1 - (self.max_allowed_slippage_percent / 100)
            price = round(current_price * price_adjustment, base_precision)
            amount_held = self._exchange.portfolio.get(self.asset_symbol, 0)
            amount = round(amount_held * trade_amount, asset_precision)

        return Trade(self.asset_symbol, trade_type, amount, price)