예제 #1
0
def coin_finished_timestamp(timestamp: pd.Timestamp, level: TradingLevel):
    timestamp = to_pd_timestamp(timestamp)

    if timestamp.microsecond != 0:
        return False

    return timestamp.minute % level.to_minute() == 0
예제 #2
0
파일: trader.py 프로젝트: zfsamzfsam/zvt
    def __init__(self,
                 security_type=SecurityType.stock,
                 exchanges=['sh', 'sz'],
                 codes=None,
                 start_timestamp=None,
                 end_timestamp=None,
                 provider=Provider.JOINQUANT,
                 trading_level=TradingLevel.LEVEL_1DAY,
                 trader_name=None) -> None:
        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()
        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = None

        self.security_type = security_type
        self.exchanges = exchanges
        self.codes = codes
        # make sure the min level selector correspond to the provider and level
        self.provider = provider
        self.trading_level = trading_level

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        self.account_service = SimAccountService(
            trader_name=self.trader_name,
            timestamp=self.start_timestamp,
            provider=self.provider,
            level=self.trading_level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_type=self.security_type,
                            exchanges=self.exchanges,
                            codes=self.codes,
                            start_timestamp=self.start_timestamp,
                            end_timestamp=self.end_timestamp)

        self.selectors_comparator = LimitSelectorsComparator(self.selectors)

        self.trading_level_asc = list(
            set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()
예제 #3
0
파일: common.py 프로젝트: tianjixuetu/zvt
def get_kdata_schema(security_type: Union[SecurityType, str],
                     level: Union[TradingLevel,
                                  str] = TradingLevel.LEVEL_1DAY):
    if type(level) == str:
        level = TradingLevel(level)
    if type(security_type) == str:
        security_type = SecurityType(security_type)

    # kdata schema rule
    # 1)name:{SecurityType.value.capitalize()}{TradingLevel.value.upper()}Kdata
    schema_str = '{}{}Kdata'.format(security_type.value.capitalize(),
                                    level.value.upper())

    return eval(schema_str)
예제 #4
0
파일: common.py 프로젝트: zfsamzfsam/zvt
def get_kdata_schema(security_type, level=TradingLevel.LEVEL_1DAY):
    if type(level) == str:
        level = TradingLevel(level)

    if SecurityType(security_type) == SecurityType.stock:
        if level == TradingLevel.LEVEL_1DAY:
            return StockDayKdata
        if level == TradingLevel.LEVEL_1HOUR:
            return Stock1HKdata

    if SecurityType(
            security_type
    ) == SecurityType.index and level == TradingLevel.LEVEL_1DAY:
        return IndexDayKdata
예제 #5
0
            'size': size,
            'level': self.level,
            'ccxt_level': self.ccxt_trading_level
        }


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--level',
                        help='trading level',
                        default='15m',
                        choices=[item.value for item in TradingLevel])
    parser.add_argument('--exchanges',
                        help='exchanges',
                        default='binance',
                        nargs='+',
                        choices=[item for item in COIN_EXCHANGES])
    parser.add_argument('--codes',
                        help='codes',
                        default='EOS/USDT',
                        nargs='+',
                        choices=[item for item in COIN_PAIRS])

    args = parser.parse_args()

    level = TradingLevel(args.level)

    init_process_log('coin_{}_kdata.log'.format(args.level))

    CoinKdataRecorder(codes=['EOS/USDT'], level=level).run()
예제 #6
0
class Trader(Constructor):
    logger = logging.getLogger(__name__)

    security_type: SecurityType = None

    def __init__(self,
                 security_list: List[str] = None,
                 exchanges: List[str] = ['sh', 'sz'],
                 codes: List[str] = None,
                 start_timestamp: Union[str, pd.Timestamp] = None,
                 end_timestamp: Union[str, pd.Timestamp] = None,
                 provider: Union[str, Provider] = Provider.JOINQUANT,
                 level: Union[str, TradingLevel] = TradingLevel.LEVEL_1DAY,
                 trader_name: str = None,
                 real_time: bool = False,
                 kdata_use_begin_time: bool = False) -> None:

        assert self.security_type is not None

        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()

        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = []

        self.security_list = security_list

        self.exchanges = exchanges
        self.codes = codes

        # FIXME:handle this case gracefully
        if self.security_list:
            security_type, exchange, code = decode_security_id(self.security_list[0])
            if not self.security_type:
                self.security_type = security_type
            if not self.exchanges:
                self.exchanges = [exchange]

        self.provider = Provider(provider)
        # make sure the min level selector correspond to the provider and level
        self.level = TradingLevel(level)
        self.real_time = real_time

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        if real_time:
            logger.info(
                'real_time mode, end_timestamp should be future,you could set it big enough for running forever')
            assert self.end_timestamp >= now_pd_timestamp()

        self.kdata_use_begin_time = kdata_use_begin_time

        self.account_service = SimAccountService(trader_name=self.trader_name,
                                                 timestamp=self.start_timestamp,
                                                 provider=self.provider,
                                                 level=self.level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_list=security_list, security_type=self.security_type, exchanges=self.exchanges,
                            codes=self.codes, start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp)

        self.selectors_comparator = self.init_selectors_comparator()

        self.trading_level_asc = list(set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()

        self.session = get_db_session('zvt', StoreCategory.business)
        trader = get_trader(session=self.session, trader_name=self.trader_name, return_type='domain', limit=1)

        if trader:
            self.logger.warning("trader:{} has run before,old result would be deleted".format(self.trader_name))
            self.session.query(business.Trader).filter(business.Trader.trader_name == self.trader_name).delete()
            self.session.commit()
        self.on_start()

    def on_start(self):
        if not self.selectors:
            raise Exception('please setup self.selectors in init_selectors at first')

        # run all the selectors
        technical_factors = []
        for selector in self.selectors:
            # run for the history data at first
            selector.run()

            for factor in selector.filter_factors:
                if isinstance(factor, TechnicalFactor):
                    technical_factors.append(factor)

        technical_factors = simplejson.dumps(technical_factors, for_json=True)

        if self.security_list:
            security_list = json.dumps(self.security_list)
        else:
            security_list = None

        if self.exchanges:
            exchanges = json.dumps(self.exchanges)
        else:
            exchanges = None

        if self.codes:
            codes = json.dumps(self.codes)
        else:
            codes = None

        trader_domain = business.Trader(id=self.trader_name, timestamp=self.start_timestamp,
                                        trader_name=self.trader_name,
                                        security_type=security_list, exchanges=exchanges, codes=codes,
                                        start_timestamp=self.start_timestamp,
                                        end_timestamp=self.end_timestamp, provider=self.provider.value,
                                        level=self.level.value,
                                        real_time=self.real_time, kdata_use_begin_time=self.kdata_use_begin_time,
                                        technical_factors=technical_factors)
        self.session.add(trader_domain)
        self.session.commit()

    def init_selectors(self, security_list, security_type, exchanges, codes, start_timestamp, end_timestamp):
        """
        implement this to init selectors

        """
        raise NotImplementedError

    def init_selectors_comparator(self):
        """
        overwrite this to set selectors_comparator

        """
        return LimitSelectorsComparator(self.selectors)

    def add_trading_signal_listener(self, listener):
        if listener not in self.trading_signal_listeners:
            self.trading_signal_listeners.append(listener)

    def remove_trading_signal_listener(self, listener):
        if listener in self.trading_signal_listeners:
            self.trading_signal_listeners.remove(listener)

    def handle_targets_slot(self, timestamp):
        """
        this function would be called in every cycle, you could overwrite it for your custom algorithm to select the
        targets of different levels

        the default implementation is selecting the targets in all levels

        :param timestamp:
        :type timestamp:
        """
        long_selected = None
        short_selected = None
        for level in self.trading_level_desc:
            targets = self.targets_slot.get_targets(level=level)
            if targets:
                long_targets = set(targets[0])
                short_targets = set(targets[1])

                if not long_selected:
                    long_selected = long_targets
                else:
                    long_selected = long_selected & long_targets

                if not short_selected:
                    short_selected = short_targets
                else:
                    short_selected = short_selected & short_targets

        self.logger.debug('timestamp:{},long_selected:{}'.format(timestamp, long_selected))

        self.logger.debug('timestamp:{},short_selected:{}'.format(timestamp, short_selected))

        self.send_trading_signals(timestamp=timestamp, long_selected=long_selected, short_selected=short_selected)

    def send_trading_signals(self, timestamp, long_selected, short_selected):
        # current position
        account = self.account_service.latest_account
        current_holdings = [position['security_id'] for position in account['positions'] if
                            position['available_long'] > 0]

        if long_selected:
            # just long the security not in the positions
            longed = long_selected - set(current_holdings)
            if longed:
                position_pct = 1.0 / len(longed)
                order_money = account['cash'] * position_pct

                for security_id in longed:
                    trading_signal = TradingSignal(security_id=security_id,
                                                   the_timestamp=timestamp,
                                                   trading_signal_type=TradingSignalType.trading_signal_open_long,
                                                   trading_level=self.level,
                                                   order_money=order_money)
                    for listener in self.trading_signal_listeners:
                        listener.on_trading_signal(trading_signal)

        # just short the security in current_holdings and short_selected
        if short_selected:
            shorted = set(current_holdings) & short_selected

            for security_id in shorted:
                trading_signal = TradingSignal(security_id=security_id,
                                               the_timestamp=timestamp,
                                               trading_signal_type=TradingSignalType.trading_signal_close_long,
                                               position_pct=1.0,
                                               trading_level=self.level)
                for listener in self.trading_signal_listeners:
                    listener.on_trading_signal(trading_signal)

    def on_finish(self):
        # show the result
        pass

    def run(self):
        # iterate timestamp of the min level,e.g,9:30,9:35,9.40...for 5min level
        # timestamp represents the timestamp in kdata
        for timestamp in iterate_timestamps(security_type=self.security_type, exchange=self.exchanges[0],
                                            start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp,
                                            level=self.level):

            if not is_trading_date(security_type=self.security_type, exchange=self.exchanges[0], timestamp=timestamp):
                continue
            if self.real_time:
                # all selector move on to handle the coming data
                if self.kdata_use_begin_time:
                    real_end_timestamp = timestamp + pd.Timedelta(seconds=self.level.to_second())
                else:
                    real_end_timestamp = timestamp

                waiting_seconds, _ = self.level.count_from_timestamp(real_end_timestamp,
                                                                     one_day_trading_minutes=get_one_day_trading_minutes(
                                                                         security_type=self.security_type))
                # meaning the future kdata not ready yet,we could move on to check
                if waiting_seconds and (waiting_seconds > 0):
                    # iterate the selector from min to max which in finished timestamp kdata
                    for level in self.trading_level_asc:
                        if (is_in_finished_timestamps(security_type=self.security_type, exchange=self.exchanges[0],
                                                      timestamp=timestamp, level=level)):
                            for selector in self.selectors:
                                if selector.level == level:
                                    selector.move_on(timestamp, self.kdata_use_begin_time, timeout=waiting_seconds + 20)

            # on_trading_open to setup the account
            if self.level == TradingLevel.LEVEL_1DAY or (
                    self.level != TradingLevel.LEVEL_1DAY and is_open_time(security_type=self.security_type,
                                                                           exchange=self.exchanges[0],
                                                                           timestamp=timestamp)):
                self.account_service.on_trading_open(timestamp)

            # the time always move on by min level step and we could check all level targets in the slot
            self.handle_targets_slot(timestamp=timestamp)

            for level in self.trading_level_asc:
                # in every cycle, all level selector do its job in its time
                if (is_in_finished_timestamps(security_type=self.security_type, exchange=self.exchanges[0],
                                              timestamp=timestamp, level=level)):
                    long_targets, short_targets = self.selectors_comparator.make_decision(timestamp=timestamp,
                                                                                          trading_level=level)

                    self.targets_slot.input_targets(level, long_targets, short_targets)

            # on_trading_close to calculate date account
            if self.level == TradingLevel.LEVEL_1DAY or (
                    self.level != TradingLevel.LEVEL_1DAY and is_close_time(security_type=self.security_type,
                                                                            exchange=self.exchanges[0],
                                                                            timestamp=timestamp)):
                self.account_service.on_trading_close(timestamp)

        self.on_finish()

    @classmethod
    def get_constructor_meta(cls):
        meta = super().get_constructor_meta()
        meta.metas['security_type'] = marshal_object_for_ui(cls.security_type)
        return meta
예제 #7
0
    def __init__(self,
                 security_list: List[str] = None,
                 exchanges: List[str] = ['sh', 'sz'],
                 codes: List[str] = None,
                 start_timestamp: Union[str, pd.Timestamp] = None,
                 end_timestamp: Union[str, pd.Timestamp] = None,
                 provider: Union[str, Provider] = Provider.JOINQUANT,
                 level: Union[str, TradingLevel] = TradingLevel.LEVEL_1DAY,
                 trader_name: str = None,
                 real_time: bool = False,
                 kdata_use_begin_time: bool = False) -> None:

        assert self.security_type is not None

        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()

        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = []

        self.security_list = security_list

        self.exchanges = exchanges
        self.codes = codes

        # FIXME:handle this case gracefully
        if self.security_list:
            security_type, exchange, code = decode_security_id(self.security_list[0])
            if not self.security_type:
                self.security_type = security_type
            if not self.exchanges:
                self.exchanges = [exchange]

        self.provider = Provider(provider)
        # make sure the min level selector correspond to the provider and level
        self.level = TradingLevel(level)
        self.real_time = real_time

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        if real_time:
            logger.info(
                'real_time mode, end_timestamp should be future,you could set it big enough for running forever')
            assert self.end_timestamp >= now_pd_timestamp()

        self.kdata_use_begin_time = kdata_use_begin_time

        self.account_service = SimAccountService(trader_name=self.trader_name,
                                                 timestamp=self.start_timestamp,
                                                 provider=self.provider,
                                                 level=self.level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_list=security_list, security_type=self.security_type, exchanges=self.exchanges,
                            codes=self.codes, start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp)

        self.selectors_comparator = self.init_selectors_comparator()

        self.trading_level_asc = list(set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()

        self.session = get_db_session('zvt', StoreCategory.business)
        trader = get_trader(session=self.session, trader_name=self.trader_name, return_type='domain', limit=1)

        if trader:
            self.logger.warning("trader:{} has run before,old result would be deleted".format(self.trader_name))
            self.session.query(business.Trader).filter(business.Trader.trader_name == self.trader_name).delete()
            self.session.commit()
        self.on_start()
예제 #8
0
파일: rules.py 프로젝트: woolf-wen/zvt
def coin_finished_timestamp(timestamp: pd.Timestamp, level: TradingLevel):
    timestamp = to_pd_timestamp(timestamp)

    return timestamp.minute % level.to_minute() == 0
예제 #9
0
    def __init__(self,
                 security_list: List[str] = None,
                 security_type: Union[str, SecurityType] = SecurityType.stock,
                 exchanges: List[str] = ['sh', 'sz'],
                 codes: List[str] = None,
                 start_timestamp: Union[str, pd.Timestamp] = None,
                 end_timestamp: Union[str, pd.Timestamp] = None,
                 provider: Union[str, Provider] = Provider.JOINQUANT,
                 level: Union[str, TradingLevel] = TradingLevel.LEVEL_1DAY,
                 trader_name: str = None,
                 real_time: bool = False,
                 kdata_use_begin_time: bool = False) -> None:
        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()

        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = None

        self.security_list = security_list
        self.security_type = SecurityType(security_type)
        self.exchanges = exchanges
        self.codes = codes

        self.provider = provider
        # make sure the min level selector correspond to the provider and level
        self.level = TradingLevel(level)
        self.real_time = real_time

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        if real_time:
            logger.info(
                'real_time mode, end_timestamp should be future,you could set it big enough for running forever'
            )
            assert self.end_timestamp >= now_pd_timestamp()

        self.kdata_use_begin_time = kdata_use_begin_time

        self.account_service = SimAccountService(
            trader_name=self.trader_name,
            timestamp=self.start_timestamp,
            provider=self.provider,
            level=self.level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_list=security_list,
                            security_type=self.security_type,
                            exchanges=self.exchanges,
                            codes=self.codes,
                            start_timestamp=self.start_timestamp,
                            end_timestamp=self.end_timestamp)

        self.selectors_comparator = self.init_selectors_comparator()

        self.trading_level_asc = list(
            set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()
예제 #10
0
class Trader(Constructor):
    logger = logging.getLogger(__name__)

    def __init__(self,
                 security_list: List[str] = None,
                 security_type: Union[str, SecurityType] = SecurityType.stock,
                 exchanges: List[str] = ['sh', 'sz'],
                 codes: List[str] = None,
                 start_timestamp: Union[str, pd.Timestamp] = None,
                 end_timestamp: Union[str, pd.Timestamp] = None,
                 provider: Union[str, Provider] = Provider.JOINQUANT,
                 level: Union[str, TradingLevel] = TradingLevel.LEVEL_1DAY,
                 trader_name: str = None,
                 real_time: bool = False,
                 kdata_use_begin_time: bool = False) -> None:
        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()

        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = None

        self.security_list = security_list
        self.security_type = SecurityType(security_type)
        self.exchanges = exchanges
        self.codes = codes

        self.provider = provider
        # make sure the min level selector correspond to the provider and level
        self.level = TradingLevel(level)
        self.real_time = real_time

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        if real_time:
            logger.info(
                'real_time mode, end_timestamp should be future,you could set it big enough for running forever'
            )
            assert self.end_timestamp >= now_pd_timestamp()

        self.kdata_use_begin_time = kdata_use_begin_time

        self.account_service = SimAccountService(
            trader_name=self.trader_name,
            timestamp=self.start_timestamp,
            provider=self.provider,
            level=self.level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_list=security_list,
                            security_type=self.security_type,
                            exchanges=self.exchanges,
                            codes=self.codes,
                            start_timestamp=self.start_timestamp,
                            end_timestamp=self.end_timestamp)

        self.selectors_comparator = self.init_selectors_comparator()

        self.trading_level_asc = list(
            set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()

    def init_selectors(self, security_list, security_type, exchanges, codes,
                       start_timestamp, end_timestamp):
        """
        implement this to init selectors

        """
        raise NotImplementedError

    def init_selectors_comparator(self):
        """
        overwrite this to set selectors_comparator

        """
        return LimitSelectorsComparator(self.selectors)

    def add_trading_signal_listener(self, listener):
        if listener not in self.trading_signal_listeners:
            self.trading_signal_listeners.append(listener)

    def remove_trading_signal_listener(self, listener):
        if listener in self.trading_signal_listeners:
            self.trading_signal_listeners.remove(listener)

    def handle_targets_slot(self, timestamp):
        """
        this function would be called in every cycle, you could overwrite it for your custom algorithm to select the
        targets of different levels

        the default implementation is selecting the targets in all levels

        :param timestamp:
        :type timestamp:
        """
        selected = None
        for level in self.trading_level_desc:
            targets = self.targets_slot.get_targets(level=level)
            if not targets:
                targets = set()

            if not selected:
                selected = targets
            else:
                selected = selected & targets

        if selected:
            self.logger.debug('timestamp:{},selected:{}'.format(
                timestamp, selected))

        self.send_trading_signals(timestamp=timestamp, selected=selected)

    def send_trading_signals(self, timestamp, selected):
        # current position
        account = self.account_service.latest_account
        current_holdings = [
            position['security_id'] for position in account['positions']
            if position['available_long'] > 0
        ]

        if selected:
            # just long the security not in the positions
            longed = selected - set(current_holdings)
            if longed:
                position_pct = 1.0 / len(longed)
                order_money = account['cash'] * position_pct

                for security_id in longed:
                    trading_signal = TradingSignal(
                        security_id=security_id,
                        the_timestamp=timestamp,
                        trading_signal_type=TradingSignalType.
                        trading_signal_open_long,
                        trading_level=self.level,
                        order_money=order_money)
                    for listener in self.trading_signal_listeners:
                        listener.on_trading_signal(trading_signal)

        # just short the security not in the selected but in current_holdings
        if selected:
            shorted = set(current_holdings) - selected
        else:
            shorted = set(current_holdings)

        for security_id in shorted:
            trading_signal = TradingSignal(
                security_id=security_id,
                the_timestamp=timestamp,
                trading_signal_type=TradingSignalType.
                trading_signal_close_long,
                position_pct=1.0,
                trading_level=self.level)
            for listener in self.trading_signal_listeners:
                listener.on_trading_signal(trading_signal)

    def on_finish(self):
        # show the result
        pass

    def run(self):
        # iterate timestamp of the min level,e.g,9:30,9:35,9.40...for 5min level
        # timestamp represents the timestamp in kdata
        for timestamp in iterate_timestamps(
                security_type=self.security_type,
                exchange=self.exchanges[0],
                start_timestamp=self.start_timestamp,
                end_timestamp=self.end_timestamp,
                level=self.level):
            if self.real_time:
                # all selector move on to handle the coming data
                if self.kdata_use_begin_time:
                    real_end_timestamp = timestamp + pd.Timedelta(
                        seconds=self.level.to_second())
                else:
                    real_end_timestamp = timestamp

                waiting_seconds, _ = self.level.count_from_timestamp(
                    real_end_timestamp,
                    one_day_trading_minutes=get_one_day_trading_minutes(
                        security_type=self.security_type))
                # meaning the future kdata not ready yet,we could move on to check
                if waiting_seconds and (waiting_seconds > 0):
                    # iterate the selector from min to max which in finished timestamp kdata
                    for level in self.trading_level_asc:
                        if (is_in_finished_timestamps(
                                security_type=self.security_type,
                                exchange=self.exchanges[0],
                                timestamp=timestamp,
                                level=level)):
                            for selector in self.selectors:
                                if selector.level == level:
                                    selector.move_on(timestamp,
                                                     self.kdata_use_begin_time)

            # on_trading_open to setup the account
            if self.level == TradingLevel.LEVEL_1DAY or (
                    self.level != TradingLevel.LEVEL_1DAY
                    and is_open_time(security_type=self.security_type,
                                     exchange=self.exchanges[0],
                                     timestamp=timestamp)):
                self.account_service.on_trading_open(timestamp)

            # the time always move on by min level step and we could check all level targets in the slot
            self.handle_targets_slot(timestamp=timestamp)

            for level in self.trading_level_asc:
                # in every cycle, all level selector do its job in its time
                if (is_in_finished_timestamps(security_type=self.security_type,
                                              exchange=self.exchanges[0],
                                              timestamp=timestamp,
                                              level=level)):
                    df = self.selectors_comparator.make_decision(
                        timestamp=timestamp, trading_level=level)
                    if not df.empty:
                        selected = set(df['security_id'].to_list())
                    else:
                        selected = {}

                    self.targets_slot.input_targets(level, selected)

            # on_trading_close to calculate date account
            if self.level == TradingLevel.LEVEL_1DAY or (
                    self.level != TradingLevel.LEVEL_1DAY
                    and is_close_time(security_type=self.security_type,
                                      exchange=self.exchanges[0],
                                      timestamp=timestamp)):
                self.account_service.on_trading_close(timestamp)

        self.on_finish()
예제 #11
0
파일: trader.py 프로젝트: woolf-wen/zvt
    def __init__(self, security_list=None, security_type=SecurityType.stock, exchanges=['sh', 'sz'], codes=None,
                 start_timestamp=None,
                 end_timestamp=None,
                 provider=Provider.JOINQUANT,
                 trading_level=TradingLevel.LEVEL_1DAY,
                 trader_name=None,
                 real_time=False,
                 kdata_use_begin_time=False) -> None:
        """

        :param security_list:
        :type security_list:
        :param security_type:
        :type security_type:
        :param exchanges:
        :type exchanges:
        :param codes:
        :type codes:
        :param start_timestamp:
        :type start_timestamp:
        :param end_timestamp:
        :type end_timestamp:
        :param provider:
        :type provider:
        :param trading_level:
        :type trading_level:
        :param trader_name:
        :type trader_name:
        :param real_time:
        :type real_time:
        :param kdata_use_begin_time: true means the interval [timestamp,timestamp+level),false means [timestamp-level,timestamp)
        :type kdata_use_begin_time: bool

        """
        if trader_name:
            self.trader_name = trader_name
        else:
            self.trader_name = type(self).__name__.lower()

        self.trading_signal_listeners = []
        self.state_listeners = []

        self.selectors: List[TargetSelector] = None

        self.security_list = security_list
        self.security_type = security_type
        self.exchanges = exchanges
        self.codes = codes

        self.provider = provider
        # make sure the min level selector correspond to the provider and level
        self.trading_level = trading_level
        self.real_time = real_time

        if start_timestamp and end_timestamp:
            self.start_timestamp = to_pd_timestamp(start_timestamp)
            self.end_timestamp = to_pd_timestamp(end_timestamp)
        else:
            assert False

        if real_time:
            logger.info(
                'real_time mode, end_timestamp should be future,you could set it big enough for running forever')
            assert self.end_timestamp >= now_pd_timestamp()

        self.kdata_use_begin_time = kdata_use_begin_time

        self.account_service = SimAccountService(trader_name=self.trader_name,
                                                 timestamp=self.start_timestamp,
                                                 provider=self.provider,
                                                 level=self.trading_level)

        self.add_trading_signal_listener(self.account_service)

        self.init_selectors(security_list=security_list, security_type=self.security_type, exchanges=self.exchanges,
                            codes=self.codes, start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp)

        self.selectors_comparator = LimitSelectorsComparator(self.selectors)

        self.trading_level_asc = list(set([TradingLevel(selector.level) for selector in self.selectors]))
        self.trading_level_asc.sort()

        self.trading_level_desc = list(self.trading_level_asc)
        self.trading_level_desc.reverse()

        self.targets_slot: TargetsSlot = TargetsSlot()