def get_trading_signals_figure(order_reader: OrderReader, entity_id: str, provider: str, level): entity_type, _, _ = decode_entity_id(entity_id) security_factor = TechnicalFactor(entity_type=entity_type, entity_ids=[entity_id], level=level, provider=provider) if pd_is_not_null(security_factor.data_df): print(security_factor.data_df.tail()) # generate the annotation df order_reader.move_on(timeout=0) df = order_reader.data_df.copy() if pd_is_not_null(df): df['value'] = df['order_price'] df['flag'] = df['order_type'].apply(lambda x: order_type_flag(x)) df['color'] = df['order_type'].apply(lambda x: order_type_color(x)) print(df.tail()) data, layout = security_factor.draw(render=None, figures=go.Candlestick, annotation_df=df) return go.Figure(data=data, layout=layout)
def on_trading_close(self, timestamp): self.logger.info('on_trading_close:{}'.format(timestamp)) self.latest_account['value'] = 0 self.latest_account['all_value'] = 0 for position in self.latest_account['positions']: # use qfq for stock entity_type, _, _ = decode_entity_id(position['entity_id']) data_schema = get_kdata_schema(entity_type, level=self.level) kdata = get_kdata(provider=self.provider, level=self.level, entity_id=position['entity_id'], order=data_schema.timestamp.desc(), end_timestamp=timestamp, limit=1) # use qfq for stock if entity_type == 'stock': closing_price = kdata['qfq_close'][0] else: closing_price = kdata['close'][0] position['available_long'] = position['long_amount'] position['available_short'] = position['short_amount'] if closing_price: if (position['long_amount'] is not None) and position['long_amount'] > 0: position['value'] = position['long_amount'] * closing_price self.latest_account['value'] += position['value'] elif (position['short_amount'] is not None) and position['short_amount'] > 0: position['value'] = 2 * (position['short_amount'] * position['average_short_price']) position[ 'value'] -= position['short_amount'] * closing_price self.latest_account['value'] += position['value'] else: self.logger.warning( 'could not refresh close value for position:{},timestamp:{}' .format(position['entity_id'], timestamp)) # remove the empty position self.latest_account['positions'] = [ position for position in self.latest_account['positions'] if position['long_amount'] > 0 or position['short_amount'] > 0 ] self.latest_account['all_value'] = self.latest_account[ 'value'] + self.latest_account['cash'] self.latest_account['closing'] = True self.latest_account['timestamp'] = to_pd_timestamp(timestamp) self.logger.info('on_trading_close:{},latest_account:{}'.format( timestamp, self.latest_account)) self.persist_account(timestamp)
def get_trading_meta(entity_id=None, entity_type=None, exchange=None): if entity_id: entity_type, exchange, _ = decode_entity_id(entity_id) if entity_type == 'future': return {'trading_t': 0, 'could_short': True} if entity_type == 'coin': return {'trading_t': 0, 'could_short': True} if entity_type == 'stock': return {'trading_t': 1, 'could_short': False}
def on_trading_signal(self, trading_signal: TradingSignal): self.logger.debug('trader:{} received trading signal:{}'.format( self.trader_name, trading_signal)) entity_id = trading_signal.entity_id current_timestamp = trading_signal.the_timestamp order_type = AccountService.trading_signal_to_order_type( trading_signal.trading_signal_type) trading_level = trading_signal.trading_level.value if order_type: try: kdata = get_kdata(provider=self.provider, entity_id=entity_id, level=trading_level, start_timestamp=current_timestamp, end_timestamp=current_timestamp, limit=1) if kdata is not None and not kdata.empty: # use qfq for stock entity_type, _, _ = decode_entity_id(kdata['entity_id'][0]) if entity_type == 'stock': the_price = kdata['qfq_close'][0] else: the_price = kdata['close'][0] if the_price: self.order(entity_id=entity_id, current_price=the_price, current_timestamp=current_timestamp, order_pct=trading_signal.position_pct, order_money=trading_signal.order_money, order_type=order_type) else: self.logger.warning( 'ignore trading signal,wrong kdata,entity_id:{},timestamp:{},kdata:{}' .format(entity_id, current_timestamp, kdata.to_dict(orient='records'))) else: self.logger.warning( 'ignore trading signal,could not get kdata,entity_id:{},timestamp:{}' .format(entity_id, current_timestamp)) except Exception as e: self.logger.exception(e)
def __init__(self, entity_ids: 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: str = 'joinquant', level: Union[str, IntervalLevel] = IntervalLevel.LEVEL_1DAY, trader_name: str = None, real_time: bool = False, kdata_use_begin_time: bool = False) -> None: assert self.entity_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.selectors: List[TargetSelector] = [] self.entity_ids = entity_ids self.exchanges = exchanges self.codes = codes # FIXME:handle this case gracefully if self.entity_ids: entity_type, exchange, code = decode_entity_id(self.entity_ids[0]) if not self.entity_type: self.entity_type = entity_type if not self.exchanges: self.exchanges = [exchange] self.provider = provider # make sure the min level selector correspond to the provider and level self.level = IntervalLevel(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(entity_ids=entity_ids, entity_type=self.entity_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([IntervalLevel(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', '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 get_trader_detail_figures(trader_domain: business.Trader, account_reader: AccountReader, order_reader: OrderReader): graph_list = [] if account_reader: account_data, account_layout = account_reader.data_drawer().draw_line(render=None, keep_ui_state=False) for trader_name in account_reader.trader_names: graph_list.append(dcc.Graph( id='{}-account'.format(trader_name), figure={ 'data': account_data, 'layout': account_layout })) order_reader.move_on(timeout=0) df_orders = order_reader.get_data_df().copy() if df_is_not_null(df_orders): grouped = df_orders.groupby('entity_id') for entity_id, order_df in grouped: entity_type, _, _ = decode_entity_id(entity_id) indicators = [] indicators_param = [] indicator_cols = [] if trader_domain.technical_factors: tech_factors = simplejson.loads(trader_domain.technical_factors) print(tech_factors) for factor in tech_factors: indicators += factor['indicators'] indicators_param += factor['indicators_param'] indicator_cols += factor['indicator_cols'] security_factor = TechnicalFactor(entity_type=entity_type, entity_ids=[entity_id], start_timestamp=trader_domain.start_timestamp, end_timestamp=trader_domain.end_timestamp, level=trader_domain.level, provider=trader_domain.provider, indicators=indicators, indicators_param=indicators_param) # generate the annotation df df = order_df.copy() if df_is_not_null(df): df['value'] = df['order_price'] df['flag'] = df['order_type'].apply(lambda x: order_type_flag(x)) df['color'] = df['order_type'].apply(lambda x: order_type_color(x)) print(df.tail()) data, layout = security_factor.draw_depth(render=None, annotation_df=df, height=620) if trader_domain.real_time: result = get_current_price(entity_ids=[entity_id]) bid_ask = result.get(entity_id) if bid_ask: graph_list.append(daq.LEDDisplay( id='ask', label=f'ask price', value=bid_ask[0], color="#00da3c" )) graph_list.append(daq.LEDDisplay( id='bid', label=f'bid price', value=bid_ask[1], color="#FF5E5E" )) graph_list.append( dcc.Graph( id='{}-{}-signals'.format(trader_domain.trader_name, entity_id), figure={ 'data': data, 'layout': layout } ) ) return graph_list