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))
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)
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)
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)
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)
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)
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)