示例#1
0
    def product(self):
        """
        从数据库中取出数据
        """
        conn = MySql().get_connection()  # 得到连接
        # 构造查询条件
        query_params = " where ctime >= '%s'" % (self.__start_time,)
        query_params += " and ctime < '%s'" % (self.__end_time,)

        coll = "%s_%s" % (self.__symbol, self.__config.time_frame)

        cur = conn.cursor(pymysql.cursors.DictCursor)

        cur.execute("select * from %s " % coll + query_params + " limit %d " % self.__maxsize)
        # print(cur.fetchall())
        for row in cur.fetchall():
            bar = Bar(self.__symbol)
            bar.close = row["close"]
            bar.timestamp = int(row["ctime"])
            bar.high = row["high"]
            bar.low = row["low"]
            bar.open = row["open"]
            bar.volume = row["volume"]
            bar.time_frame = self.__config.time_frame
            self.__dq.put(bar)
            self.__start_time = bar.timestamp + tf2s(self.__config.time_frame)
        cur.close()
        # 如果开始时间距结束时间的距离不超过当前时间尺度,证明数据查询完成
        if (cur.rownumber == 0) or self.__end_time - self.__start_time <= tf2s(self.__config.time_frame):
            self._finished = True
示例#2
0
class Bar(DictLike):
    """K线数据对象(开高低收成交量时间)"""
    __slots__ = [
        "symbol", "open", "high", "low", "close", "volume", "timestamp",
        "time_frame"
    ]
    __keys__ = __slots__ + ['datetime', "close_time"]
    datetime = property(lambda self: datetime.fromtimestamp(self.timestamp))
    close_time = property(lambda self: self.timestamp + tf2s(self.time_frame))

    def __init__(self, symbol):
        self.symbol = symbol
        self.time_frame = None
        self.open = 0
        self.high = 0
        self.low = 0
        self.close = 0
        self.volume = 0
        self.timestamp = 0

    def to_event(self):
        event = Event(EVENT_SYMBOL_BAR_RAW[self.symbol][self.time_frame],
                      data=self)
        return event

    @classmethod
    def get_keys(cls):
        """
        :return: field names in print order use for create dataframe
        """
        return cls.__keys__
示例#3
0
 def float_pnl_frequency(self):
     if not self._is_backtest:
         return 1
     if self.min_time_frame in ['M1', 'M5']:
         return 1
     time = tf2s(self.min_time_frame)
     result = 2 * 60 * 60 // time  # 统计频率为2H一次
     if result == 0:
         return 1
     else:
         return result
示例#4
0
 def float_pnl_frequency(self):
     if self.config.running_mode == RunningMode.runtime:
         return 1
     if self.min_time_frame in ['M1', 'M5']:
         return 1
     time = tf2s(self.min_time_frame)
     result = 2 * 60 * 60 // time  # 统计频率为2H一次
     if result == 0:
         return 1
     else:
         return result
示例#5
0
    def product(self):
        """
        从数据库中取出数据
        """
        try:
            conn = MySql().get_connection()  # 得到连接
            # 构造查询条件
            query_params = " where ctime >= '%s'" % (self.__start_time, )
            query_params += " and ctime < '%s'" % (self.__end_time, )

            coll = "%s_%s" % (self.__symbol, self.config.time_frame)

            cur = conn.cursor(pymysql.cursors.DictCursor)

            cur.execute("select * from %s " % coll + query_params +
                        " limit %d " % self.__maxsize)
            # print(cur.fetchall())
            for row in cur.fetchall():
                bar = Bar(self.__symbol)
                bar.close = row["close"]
                bar.timestamp = int(row["ctime"])
                bar.high = row["high"]
                bar.low = row["low"]
                bar.open = row["open"]
                bar.volume = row["volume"]
                # volume maybe None in mysql
                if bar.volume is None:
                    bar.volume = 0
                bar.time_frame = self.config.time_frame
                self.__dq.put(bar)
                self.__start_time = bar.timestamp + tf2s(
                    self.config.time_frame)
            cur.close()
            # 如果开始时间距结束时间的距离不超过当前时间尺度,证明数据查询完成
            if (cur.rownumber
                    == 0) or self.__end_time - self.__start_time <= tf2s(
                        self.config.time_frame):
                self.stop()
        except:
            self.logger.error('\n' + traceback.format_exc())
            self.stop()
示例#6
0
 def update_bar(self, bar):
     symbol = bar.symbol
     time_frame = bar.time_frame
     self.current_time = bar.close_time if not self.current_time else max(self.current_time, bar.close_time)
     last_time = self._data[time_frame]['timestamp'][symbol][0] \
         if self._data[time_frame]['timestamp'][symbol] else 0
     if bar.timestamp - last_time >= tf2s(time_frame):  # 当last_time = 0时,该条件显然成立
         for field in ['open', 'high', 'low', 'close', 'datetime', 'timestamp', 'volume']:
             self._data[time_frame][field][symbol].appendleft(getattr(bar, field))
         self._engine.put_event(Event(EVENT_SYMBOL_BAR_COMPLETED[symbol][time_frame]))
     else:
         for field in ['open', 'high', 'low', 'close', 'datetime', 'timestamp', 'volume']:
             self._data[time_frame][field][symbol][0] = getattr(bar, field)
         self._engine.put_event(Event(EVENT_SYMBOL_BAR_UPDATE[symbol][time_frame]))
示例#7
0
 def on_bar(self, event):
     if self._running:
         bar = event.content['data']
         symbol = bar.symbol
         time_frame = bar.time_frame
         self.current_time = bar.close_time if not self.current_time else max(self.current_time, bar.close_time)
         last_time = self._data[time_frame]['timestamp'][symbol][0] \
             if self._data[time_frame]['timestamp'][symbol] else 0
         if bar.timestamp - last_time >= tf2s(time_frame):  # 当last_time = 0时,该条件显然成立
             for field in ['open', 'high', 'low', 'close', 'datetime', 'timestamp', 'volume']:
                 self._data[time_frame][field][symbol].appendleft(getattr(bar, field))
             self._engine.put_event(Event(EVENT_SYMBOL_BAR_COMPLETED[symbol][time_frame]))
         else:
             for field in ['open', 'high', 'low', 'close', 'datetime', 'timestamp', 'volume']:
                 self._data[time_frame][field][symbol][0] = getattr(bar, field)
             self._engine.put_event(Event(EVENT_SYMBOL_BAR_UPDATE[symbol][time_frame]))
示例#8
0
 def update_bar(self, bar: Bar):
     symbol = bar.symbol
     time_frame = bar.time_frame
     quotation = self._data_view.find(symbol, time_frame)
     self.current_time = bar.close_time if not self.current_time else max(self.current_time, bar.close_time)
     last_time = quotation.timestamp[0] if quotation.timestamp else 0
     if self.config.trading_mode == TradingMode.on_tick:
         quotation.tick_open = bar.open
     if bar.timestamp - last_time >= tf2s(time_frame):  # 当last_time = 0时,该条件显然成立
         for field in ['open', 'high', 'low', 'close', 'datetime', 'timestamp', 'volume']:
             getattr(quotation, field).appendleft(getattr(bar, field))
         self._engine.put_event(Event(EVENT_SYMBOL_BAR_COMPLETED[symbol][time_frame]))
     else:
         quotation.high[0] = max(quotation.high[0], bar.high)
         quotation.low[0] = min(quotation.low[0], bar.low)
         quotation.volume[0] += bar.volume
         for field in ["datetime", "timestamp", "close"]:
             getattr(quotation, field)[0] = getattr(bar, field)
         self._engine.put_event(Event(EVENT_SYMBOL_BAR_UPDATE[symbol][time_frame]))
示例#9
0
 def __send_order_to_broker(self, order):
     if self.__is_backtest:
         time_frame = self.engine.strategys[order.strategy].signals[order.signal].get_time_frame()
         time_ = self.engine.data[time_frame]["timestamp"][order.symbol][0] + tf2s(time_frame)
         order.time_done = int(time_)
         order.time_done_msc = int((time_ - int(time_)) * (10 ** 6))
         order.volume_current = order.volume_initial
         deal = self.__deal_factory(order.symbol, order.strategy, order.signal)
         deal.volume = order.volume_current
         deal.time = order.time_done
         deal.time_msc = order.time_done_msc
         deal.type = 1 - ((order.type & 1) << 1)  # 参见ENUM_ORDER_TYPE和ENUM_DEAL_TYPE的定义
         deal.price = self.engine.data[time_frame]["close"][order.symbol][0]
         # TODO加入手续费等
         order.deal = deal.get_id()
         deal.order = order.get_id()
         return [deal], {}
         # TODO 市价单成交
     else:
         pass
示例#10
0
 def on_tick(self, event: Event):
     if self._running:
         tick = event.content['data']
         symbol = tick.symbol
         for time_frame in {item[1] for item in self._data_view.get_keys() if item[0] == symbol}:
             bar_interval = tf2s(time_frame)
             if symbol not in self._tick_cache:
                 self._tick_cache[symbol] = {}
             if time_frame not in self._tick_cache[symbol]:
                 self._tick_cache[symbol][time_frame] = {
                     'open': tick.openPrice, 'high': tick.highPrice,
                     'low': tick.lastPrice, 'close': tick.lastPrice,
                     'volume': tick.volume, 'timestamp': tick.time // self.TICK_INTERVAL * self.TICK_INTERVAL,
                 }
             else:
                 dict_ = self._tick_cache[symbol][time_frame]
                 if tick.time - dict_['timestamp'] >= self.TICK_INTERVAL:  # bar_interval 能被TICK_INTERVAL整除
                     bar = Bar(symbol)
                     bar.time_frame = time_frame
                     bar.timestamp = dict_['timestamp'] // bar_interval * bar_interval
                     bar.open = dict_['open']
                     bar.high = dict_['high']
                     bar.low = dict_['low']
                     bar.close = dict_['close']
                     self.update_bar(bar)
                     dict_["open"] = tick.openPrice
                     dict_["high"] = tick.highPrice
                     dict_["low"] = tick.lowPrice
                     dict_["close"] = tick.lastPrice
                     dict_["volume"] = tick.volume
                     dict_["timestamp"] = tick.time // self.TICK_INTERVAL * self.TICK_INTERVAL
                 else:
                     dict_['low'] = min(dict_['low'], tick.lowPrice)
                     dict_['high'] = max(dict_['high'], tick.highPrice)
                     dict_['close'] = tick.lastPrice
                     dict_["volume"] += tick.volume
                     dict_['timestamp'] = tick.time // self.TICK_INTERVAL * self.TICK_INTERVAL
示例#11
0
 def __send_order_to_broker(self, order):
     # if order.volume_initial == 0:
     # return
     if order.volume_initial <= 0:
         return -1
     if self.__is_backtest:
         time_frame = self.engine.strategys[order.strategy].signals[order.signal].get_time_frame()
         position = self.engine.current_positions[order.symbol]
         symbol = self.engine.symbol_pool[order.symbol]
         volume = order.volume_initial
         margin = 0
         if position.type * (1 - (order.type << 1)) < 0:
             if symbol.code.startswith('USD'):  # 间接报价
                 base_price = 1
             elif symbol.code.endswith('USD'):  # 直接报价
                 base_price = position.price_current
             margin -= symbol.margin(min(position.volume, volume), commission=self.__config['commission'],
                                     base_price=base_price)
             volume -= position.volume
         if volume > 0:
             margin += symbol.margin(volume, commission=self.__config['commission'],
                                     base_price=self.engine.get_base_price(order.symbol, time_frame))
         if self.engine.capital_available - margin >= 0:
             time_ = self.engine.data[time_frame]["timestamp"][order.symbol][0] + tf2s(time_frame)
             order.time_done = int(time_)
             order.time_done_msc = int((time_ - int(time_)) * (10 ** 6))
             order.volume_current = order.volume_initial
             deal = self.__deal_factory(order.symbol, order.strategy, order.signal)
             deal.volume = order.volume_current
             deal.time = order.time_done
             deal.time_msc = order.time_done_msc
             deal.type = 1 - ((order.type & 1) << 1)  # 参见ENUM_ORDER_TYPE和ENUM_DEAL_TYPE的定义
             deal.price = self.engine.data[time_frame]["close"][order.symbol][0]
             # TODO加入手续费等
             order.deal = deal.get_id()
             deal.order = order.get_id()
             order_id = order.get_id()
         else:
             print('下单失败,保证金不足')
             return -1
     else:
         cash_old = self.engine.capital_cash
         order_id = self.engine.send_order_to_broker(order)
         if order_id != -1:
             res = self.engine.order_status()
             if res['ok']:
                 order_status = res.get('orders', [])
                 for state in order_status:
                     if state['id'] == order_id:
                         deal = self.__deal_factory(order.symbol, order.strategy, order.signal)
                         deal.type = 1 - ((order.type & 1) << 1)
                         deal.volume = round(state['quantity'] / 100000, 2)  # 换算成手,精确到mini手
                         deal.time = parse(state['created']).timestamp()
                         deal.price = state['avgPx']
                         deal.symbol = order.symbol
                         deal.order = order.get_id()
                         cash_now = self.engine.capital_cash
                         deal.profit = cash_now - cash_old
                         break
     if order_id != -1:
         self.__update_position(deal)  # TODO 加入事件引擎,支持异步
         self.__orders_done[order.get_id()] = order
         return order.get_id()
     else:
         return -1
示例#12
0
 def set_min_time_frame(self, time_frame):
     if not self._min_time_frame or tf2s(time_frame) < tf2s(self._min_time_frame):
         self._min_time_frame = time_frame
示例#13
0
 def min_time_frame(self, time_frame):
     if not self._min_time_frame or tf2s(time_frame) < tf2s(self._min_time_frame):
         self._min_time_frame = time_frame