Ejemplo n.º 1
0
def handle_data(context, data):
    cash = context.portfolio.cash
    target_hodl_value = TARGET_HODL_RATIO * context.portfolio.starting_cash
    reserve_value = RESERVE_RATIO * context.portfolio.starting_cash

    # Cancel any outstanding orders
    orders = get_open_orders(context.asset) or []
    for order in orders:
        cancel_order(order)

    # Stop buying after passing the reserve threshold
    if cash <= reserve_value:
        context.is_buying = False

    # Retrieve current asset price from pricing data
    price = data[context.asset].price

    # Check if still buying and could (approximately) afford another purchase
    if context.is_buying and cash > price:
        # Place order to make position in asset equal to target_hodl_value
        order_target_value(
            context.asset,
            target_hodl_value,
            limit_price=price * 1.1,
            stop_price=price * 0.9,
        )

    record(
        price=price,
        cash=cash,
        starting_cash=context.portfolio.starting_cash,
        leverage=context.account.leverage,
    )
Ejemplo n.º 2
0
def cancel_all_orders(context):
    # only orders placed/managed by the algo are cancelled
    orders = context.blotter.open_orders[context.SYMBOL]
    for o in orders:
        log.info(f"Cancelling order: {o.id}")
        try:
            cancel_order(o, context.SYMBOL)
        except Exception as e:
            log.info(f"Failed to cancel order because: {e}")
            finalize(context)
Ejemplo n.º 3
0
def rebalance(context, data):
    # To make market decisions, we're calculating the token's
    # moving average for the last 5 days.

    # We get the price history for the last 5 days.
    price_history = data.history(context.asset,
                                 fields='price',
                                 bar_count=5,
                                 frequency='1d')

    # Then we take an average of those 5 days.
    average_price = price_history.mean()

    # We also get the coin's current price.
    price = data.current(context.asset, 'price')

    # Cancel any outstanding orders
    orders = get_open_orders(context.asset) or []
    for order in orders:
        cancel_order(order)

    # If our coin is currently listed on a major exchange
    if data.can_trade(context.asset):
        # If the current price is 1% above the 5-day average price,
        # we open a long position. If the current price is below the
        # average price, then we want to close our position to 0 shares.
        if price > (1.01 * average_price):
            # Place the buy order (positive means buy, negative means sell)
            order_target_percent(context.asset, .99)
            log.info("Buying %s" % (context.asset.symbol))
        elif price < average_price:
            # Sell all of our shares by setting the target position to zero
            order_target_percent(context.asset, 0)
            log.info("Selling %s" % (context.asset.symbol))

    # Use the record() method to track up to five custom signals.
    # Record Apple's current price and the average price over the last
    # five days.
    cash = context.portfolio.cash
    leverage = context.account.leverage

    record(price=price,
           average_price=average_price,
           cash=cash,
           leverage=leverage)
Ejemplo n.º 4
0
def handle_data(context, data):
    context.i += 1

    starting_cash = context.portfolio.starting_cash
    target_hodl_value = context.TARGET_HODL_RATIO * starting_cash
    reserve_value = context.RESERVE_RATIO * starting_cash

    # Cancel any outstanding orders
    orders = get_open_orders(context.asset) or []
    for order in orders:
        cancel_order(order)

    # Stop buying after passing the reserve threshold
    cash = context.portfolio.cash
    if cash <= reserve_value:
        context.is_buying = False

    # Retrieve current asset price from pricing data
    price = data.current(context.asset, 'price')

    # Check if still buying and could (approximately) afford another purchase
    if context.is_buying and cash > price:
        print('buying')
        # Place order to make position in asset equal to target_hodl_value
        order_target_value(
            context.asset,
            target_hodl_value,
            limit_price=price * 1.1,
        )

    record(
        price=price,
        volume=data.current(context.asset, 'volume'),
        cash=cash,
        starting_cash=context.portfolio.starting_cash,
        leverage=context.account.leverage,
    )
Ejemplo n.º 5
0
def handle_data(context, data):
    
    # Cancel any outstanding orders
    orders = get_open_orders(context.asset) or []
    for order in orders:
        cancel_order(order)
    
    # Define base price and make initial trades to achieve target investment ratio of 0.5
    order_target_percent(
        context.asset,
        0.5,
    )
                       
    # Retrieve current asset price from pricing data
    price = data[context.asset].price
    
    #Compute portfolio cumulative return
    Portfolio_cumulative_return = (context.portfolio.portfolio_value/context.portfolio.starting_cash-1)*100
    # Save values for later inspection
    record(price=price,
           cash=context.portfolio.cash,
           leverage=context.account.leverage,
           Portfolio_cumulative_return=Portfolio_cumulative_return
    )
Ejemplo n.º 6
0
    def _cancel_orders(self, order_list):
        if order_list is None or len(order_list) == 0:
            return True

        if self.is_live:
            depth = get_orderbook(order_list[0].asset)
            mkt_bidprc = depth['bids'][0]['rate']
            mkt_askprc = depth['asks'][0]['rate']

        cancelled = True
        for o in order_list:
            if o.filled != 0 and o.amount != o.filled:
                logging.warning('[cmx_order][cancel_orders] skip partial filled order: {}|{}|{}|{}'.format(o.id, o.limit, o.amount, o.filled))
                cancelled = False
                continue
            good_to_cancel = True
            if self.is_live:
                if o.amount > 0:
                    if o.limit >= mkt_bidprc:
                        logging.warning('[cmx_order][cancel_orders] skip bids that is making market: {}|{} >= {}|{}|{}'.format(
                                                                                                               o.id, 
                                                                                                               o.limit, 
                                                                                                               mkt_bidprc, 
                                                                                                               o.amount, 
                                                                                                               o.filled
                                                                                                               ))
                        good_to_cancel = False
                else:
                    if o.limit <= mkt_askprc:
                        logging.warning('[cmx_order][cancel_orders] skip asks that is making market: {}|{} <= {}|{}|{}'.format(
                                                                                                               o.id, 
                                                                                                               o.limit, 
                                                                                                               mkt_askprc, 
                                                                                                               o.amount, 
                                                                                                               o.filled
                                                                                                               ))
                        good_to_cancel = False

            try:
                if not good_to_cancel:
                    cancelled = False
                else:
                    if self.asset.exchange == 'binance' and self.is_live:
                        cancel_order(o, symbol = self.asset)
                    else:
                        cancel_order(o)
            except Exception as e:
                logging.warning(str(e))
                if self.cancel_failure_map.get(o.id):
                    self.cancel_failure_map[o.id] += 1
                else:
                    self.cancel_failure_map[o.id] = 1

                if self.is_live:
                    if self.cancel_failure_map[o.id] >= self.cancel_failure_threshold:
                        self.ignored_orderid.append(o.id)
                        logging.warning('[cmx_order][cancel_orders] failed to cancel order:{} in {} trials, ignore it.'.format(o.id, self.cancel_failure_threshold))
                    else:
                        logging.warning('[cmx_order][cancel_orders] failed to cancel order - id:{}|exchange:{}|symbol:{}|price:{}|qty:{}, will try {} times'\
                                 .format(o.id, o.sid.exchange, o.sid.symbol, o.limit, o.amount, \
                                         self.cancel_failure_threshold - self.cancel_failure_map[o.id]))
                else:
                    logging.warning('[cmx_order][cancel_orders] failed to cancel order - id:{}|exchange:{}|symbol:{}|price:{}|qty:{}, tried {} times'\
                                 .format(o.id, o.sid.exchange, o.sid.symbol, o.limit, o.amount, self.cancel_failure_map[o.id]))
                cancelled = False
        return cancelled
Ejemplo n.º 7
0
    def _process_data(self, context, data):
        """Called at each algo iteration

        Calculates indicators, processes signals, and
        records market and external data

        Arguments:
            context {pandas.Dataframe} -- Catalyst context object
            data {pandas.Datframe} -- Catalyst data object
        """
        # catalyst dumps pickle file after handle_data called
        # so this call uploads the state of
        # the previously compelted iteration

        self.state.i += 1
        self.log.info(f"Processing algo iteration - {self.state.i}")

        if not self.is_backtest and self.state.i > 1:
            outputs.upload_state_to_storage(self)

        else:
            self.log.debug("Skipping stats upload until catalyst writes to file")

        end = arrow.get(self.state.END)
        time_left = end.humanize(only_distance=True)
        self.log.debug(f"Stopping strategy in {time_left}")

        # the following called methods return:
        # True if the iteration should continued
        # False if the algo should not continue

        if not self._set_current_fields(context, data):
            return

        # To check to apply stop-loss, take-profit or keep position
        self.check_open_positions(context)

        # set date first for logging purposes
        self.current_date = get_datetime()

        if not self.fetch_history(context, data):
            return

        #  Filter minute frequency
        self._check_minute_freq(context, data)

        if self.in_job:

            job = get_current_job()
            job.meta["date"] = str(self.current_date)
            job.save_meta()

        for i in context.blotter.open_orders:
            msg = "Canceling unfilled open order {}".format(i)
            self.log.info(msg)
            self.notify(msg)
            cancel_order(i)

        if not self.fetch_history(context, data):
            return

        self._filter_fetched_history(context, data)

        # ## enqueue ml models as soon as data filtered
        if self._ml_models:
            self._enqueue_ml_calcs(context, data)

        else:
            for dataset, manager in self._datasets.items():
                manager.calculate(context)
                manager.record_data(context)

        for i in self._market_indicators:
            try:
                i.calculate(self.state.prices)
                i.record()
            except Exception as e:
                self.log.error(e)
                self.log.error("Error calculating {}, skipping...".format(i.name))

        for i in self._ml_models:
            i.record()

        self._extra_handle(context, data)
        self._count_signals(context, data)

        if context.frame_stats:
            pretty_output = stats_utils.get_pretty_stats(context.frame_stats)
            self.log.debug(pretty_output)
            if not self.is_backtest:
                outputs.save_stats_to_storage(self)

        self.state.dump_to_context(context)