Beispiel #1
0
def sanitize_orders(predictor: Predictor, _locals: _Locals) -> None:
    """
    Ensure the provided positions are appropriate for the requested symbol subset.

    :param predictor:   The Predictor associated with the current Period.
    :type predictor:    hokohoko.entities.Predictor

    :param _locals:     Variables local to the current Period.
    :type _locals:      _Locals

    """
    # 1. Mark if a symbol and direction combination has been seen.
    filtered = {s: [False, False] for s in _locals.subset_filter}
    for i, o in predictor.account.orders.items():
        if o.symbol_id in filtered:
            if o.direction in (Direction.BUY, Direction.DONT_BUY):
                filtered[o.symbol_id][0] = True
            if o.direction in (Direction.SELL, Direction.DONT_SELL):
                filtered[o.symbol_id][1] = True

    for s, f in filtered.items():
        if not f[0]:
            predictor.place_order(Order(s, Direction.DONT_BUY))
        if not f[1]:
            predictor.place_order(Order(s, Direction.DONT_SELL))
Beispiel #2
0
    def on_bar(self, bars: Iterable[Bar]) -> None:
        orders = []
        for b in bars:

            # 0. Update history. These are first-order differences of the average value for the Bar.
            average = (b.open + b.high + b.low + b.close) / 4
            average_diff = np.array(
                [average - self.last_averages[b.symbol_id]])
            self.histories[b.symbol_id] = np.concatenate(
                [average_diff, self.histories[b.symbol_id]])
            self.last_averages[b.symbol_id] = average

            # Requires a minimum of 129 values to work (7:2 training:validation ratio)
            if len(self.histories[b.symbol_id]) < 129:
                continue

            # 1. Normalise history into [-1,1].
            norm = self.histories[b.symbol_id] / np.max(
                np.abs(self.histories[b.symbol_id]))

            # 2. Get inputs - 5 moving averages plus the current value.
            data = []
            for i in range(len(norm) - 120):
                d = np.array([[0]] * 6, dtype=np.float64)
                for j in range(len(self._mas)):
                    d[j][0] = np.average(norm[1 + i:self._mas[j] + 1 + i])
                data.append((d, norm[i]))

            # 3. Send into NN.
            split = int(len(data) * 2 / 9)
            self.anns[b.symbol_id].grad_descent(data[:-split], self._limit,
                                                self._alpha, self._tolerance,
                                                data[-split:])

            # 4. Make prediction. (Apply Strategy 1).
            req = np.array([[0]] * 6, dtype=np.float64)
            for j in range(len(self._mas)):
                req[j][0] = np.average(norm[:self._mas[j]])
            pred = (self.anns[b.symbol_id].feed_forward(req) *
                    np.max(np.abs(self.histories[b.symbol_id])) +
                    average)[0][0]
            if pred > self.last_predictions[b.symbol_id] and pred > b.close:
                # if pred > b.close:
                # print("BUY")
                orders.append(
                    Order(b.symbol_id, Direction.BUY, None, pred, None))
            elif pred < self.last_predictions[b.symbol_id] and pred < b.close:
                # elif pred < b.close:
                orders.append(
                    Order(b.symbol_id, Direction.SELL, None, pred, None))
                # print("SELL")
            else:
                # print("DONT")
                pred = 0
            self.last_predictions[b.symbol_id] = pred

        self.place_orders(orders)
Beispiel #3
0
    def on_bar(self, bars: Iterable[Bar]) -> None:
        orders = []

        for b in bars:
            # 100 pips.
            orders.append(Order(b.symbol_id, Direction.BUY, None, b.close + 0.01, None))
            orders.append(Order(b.symbol_id, Direction.SELL, None, b.close - 0.01, None))

        self.place_orders(orders)
Beispiel #4
0
    def on_bar(self, bars: Iterable[Bar]) -> None:
        orders = []

        for b in bars:
            diff = b.close - b.open
            if diff > 0:
                orders.append(
                    Order(symbol_id=b.symbol_id,
                          direction=Direction.BUY,
                          open_bid=None,
                          take_profit=b.close + diff,
                          stop_loss=None))
            elif diff < 0:
                orders.append(
                    Order(symbol_id=b.symbol_id,
                          direction=Direction.SELL,
                          open_bid=None,
                          take_profit=b.close + diff,
                          stop_loss=None))

        self.place_orders(orders)
Beispiel #5
0
    def on_bar(self, bars: List[Bar]) -> None:
        """
        This implementation picks a random direction for each symbol. Predictors provide access to
        a deterministic RNG source (themselves), so all random calls should be self.random(),
        self.randint(), etc.

        :param bars:    The latest bar in the data. This is an array of the selected currencies.
        :type bars:     A list containing one or more hokohoko.entities.Bar[s].

        """

        # To ensure simulation matches benchmarking conditions, we need to close all pending orders.
        # This is not strictly required, but this demonstrates how to do it correctly.
        # self.account.pending.clear()
        # position_ids = list(self.account.positions)
        # for pid in position_ids:
        #     self.close_order(pid)

        orders = []

        for b in bars:
            self._middle[b.symbol_id].extend([b.high, b.low])
            while len(self._middle[b.symbol_id]) > 500:
                self._middle[b.symbol_id].popleft()

            middle = np.mean(self._middle[b.symbol_id])
            stdev = np.std(self._middle[b.symbol_id])

            if b.open > middle + stdev:
                direction = Direction.SELL
                take_profit = b.close - 0.01
                stop_loss = b.close + 0.0003
            elif b.open < middle - stdev:
                direction = Direction.BUY
                take_profit = b.close + 0.01
                stop_loss = b.close - 0.0003
            else:
                direction = Direction.DONT_BUY
                take_profit = 0.0
                stop_loss = 0.0

            if __debug__:
                print(middle, b.open, direction.name)

            orders.append(
                Order(symbol_id=b.symbol_id,
                      direction=direction,
                      open_bid=None,
                      take_profit=take_profit,
                      stop_loss=None))
        self.place_orders(orders)
Beispiel #6
0
    def on_bar(self, bars: Iterable[Bar]) -> None:
        orders = []

        for b in bars:
            t = self.random()
            if t >= 0.51:
                direction = Direction.BUY
            elif t <= 0.49:
                direction = Direction.SELL
            else:
                direction = Direction.DONT_BUY

            orders.append(
                Order(symbol_id=b.symbol_id,
                      direction=direction,
                      open_bid=None,
                      take_profit=None,
                      stop_loss=None))
        self.place_orders(orders)
Beispiel #7
0
    def on_bar(self, bars: List[Bar]) -> None:
        """
        This routine is where data is provided to the Predictor, and it
        processes it's own logic.  Predictions are indicated to Hokohoko
        by placing Orders, with TAKE_PROFIT indicating the prediction,
        and STOP_LOSSES the predicted amount of drawdown required to
        achieve the TAKE_PROFIT.

        This implementation picks a random direction for each symbol.
        hokohoko.entities.Predictor inherits from Random, so all
        Predictors have access to a deterministic RNG source through
        self. Seeding is controlled by Hokohoko.  Example random calls
        include self.random() and self.randint(), etc.

        :param bars:    The latest bar in the data. This is a list of
                        the selected currencies.  This list is always in
                        the same order - that is, the order of the
                        currencies list provided in self.symbol_ids[].
        :type bars:     List[hokohoko.entities.Bar].

        """

        orders = []

        for b in bars:
            if self.random() > 0.5:
                direction = Direction.BUY
            else:
                direction = Direction.SELL

            orders.append(Order(
                symbol_id=b.symbol_id,
                direction=direction,
                open_bid=None,
                take_profit=None,
                stop_loss=None
            ))
        self.place_orders(orders)