def __init__(self, main_df: pd.DataFrame = None, factor_df: pd.DataFrame = None, sub_df: pd.DataFrame = None, main_data: NormalData = None, factor_data: NormalData = None, sub_data: NormalData = None, annotation_df: pd.DataFrame = None) -> None: # 主图数据 if main_data is None: main_data = NormalData(main_df) self.main_data: NormalData = main_data # 主图因子 if factor_data is None: factor_data = NormalData(factor_df) self.factor_data: NormalData = factor_data # 副图数据 if sub_data is None: sub_data = NormalData(sub_df) self.sub_data: NormalData = sub_data # 主图的标记数据 self.annotation_df = annotation_df
def update_table_and_graph(page_current, page_size, sort_by, filter, intent, chart, rows, columns): if chart: property_map = {} for row in rows: property_map[row['property']] = { 'y_axis': row['y_axis'], 'chart': row['chart'] } dff = current_df if filter: filtering_expressions = filter.split(' && ') for filter_part in filtering_expressions: col_name, operator, filter_value = split_filter_part(filter_part) if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'): # these operators match pandas series operator method names dff = dff.loc[getattr(dff[col_name], operator)(filter_value)] elif operator == 'contains': dff = dff.loc[dff[col_name].str.contains(filter_value)] elif operator == 'datestartswith': # this is a simplification of the front-end filtering logic, # only works with complete fields in standard format dff = dff.loc[dff[col_name].str.startswith(filter_value)] # if sort_by: # dff = dff.sort_values( # [col['entity_id'] for col in sort_by], # ascending=[ # col['direction'] == 'asc' # for col in sort_by # ], # inplace=False # ) if intent in (IntentType.compare_self.value, IntentType.compare_to_other.value): graph_data, graph_layout = Drawer(NormalData(dff)).draw_compare(chart=chart, property_map=property_map, render=None, keep_ui_state=False) else: graph_data, graph_layout = Drawer(NormalData(dff)).draw(chart=chart, property_map=property_map, render=None, keep_ui_state=False) table_data = dff.iloc[page_current * page_size: (page_current + 1) * page_size ].to_dict('records') return table_data, \ dcc.Graph( id='chart-content', figure={ 'data': graph_data, 'layout': graph_layout } ) raise dash.exceptions.PreventUpdate()
def update_data_table(n_clicks, properties, codes: str, start_date, end_date): if n_clicks and properties: props = [] for prop in properties: props.append(json.loads(prop)) readers = properties_to_readers(properties=props, codes=codes, start_date=start_date, end_date=end_date) if readers: data_df = readers[0].data_df for reader in readers[1:]: if df_is_not_null(reader.data_df): data_df = data_df.join(reader.data_df, how='outer') global current_df current_df = data_df normal_data = NormalData(data_df) data_table = Drawer(data=normal_data).draw_data_table( id='data-table-content') # generate col setting table properties = normal_data.data_df.columns.to_list() df = pd.DataFrame( OrderedDict([('property', properties), ('y_axis', ['y1'] * len(properties)), ('chart', ['line'] * len(properties))])) # generate intents intents = normal_data.get_intents() intent_options = [{ 'label': intent.value, 'value': intent.value } for intent in intents] intent_value = intents[0].value return data_table, df.to_dict( 'records'), normal_data.get_table_type( ), intent_options, intent_value else: return 'no data,please reselect!', None, '', [{ 'label': 'compare_self', 'value': 'compare_self' }], 'compare_self' raise dash.exceptions.PreventUpdate()
def draw(self, render='html', file_name=None, width=None, height=None, title=None, keep_ui_state=True, annotation_df=None, target_type: TargetType = TargetType.open_long): if target_type == TargetType.open_long: df = self.open_long_df.copy() elif target_type == TargetType.open_short: df = self.open_short_df.copy() df['target_type'] = target_type.value if pd_is_not_null(df): drawer = Drawer(NormalData(df=df)) drawer.draw_table(render=render, file_name=file_name, width=width, height=height, title=title, keep_ui_state=keep_ui_state)
def load_data(self): if self.entity_ids: self.data_df = get_data(data_schema=self.data_schema, entity_ids=self.entity_ids, provider=self.provider, columns=self.columns, start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp, filters=self.filters, order=self.order, limit=self.limit, level=self.level, time_field=self.time_field, index=self.time_field) else: self.data_df = get_data(data_schema=self.data_schema, codes=self.codes, provider=self.provider, columns=self.columns, start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp, filters=self.filters, order=self.order, limit=self.limit, level=self.level, time_field=self.time_field, index=self.time_field) if self.trip_timestamp: if self.level == IntervalLevel.LEVEL_1DAY: self.data_df[self.time_field] = self.data_df[self.time_field].apply( lambda x: to_pd_timestamp(to_time_str(x))) if df_is_not_null(self.data_df): self.normal_data = NormalData(df=self.data_df, category_field=self.category_field, index_field=self.time_field, is_timeseries=True) self.data_df = self.normal_data.data_df for listener in self.data_listeners: listener.on_data_loaded(self.data_df)
def draw(self, chart='table', render='html', file_name=None, width=None, height=None, title=None, keep_ui_state=True, annotation_df=None, targets='open_long'): if targets == 'open_long': df = self.open_long_df.copy() elif targets == 'open_short': df = self.open_long_df.copy() df[targets] = targets df = df.reset_index() drawer = Drawer( NormalData(df=df, annotation_df=annotation_df, category_field=targets, index_field='timestamp', is_timeseries=True)) drawer.draw(chart=chart, render=render, file_name=file_name, width=width, height=height, title=title, keep_ui_state=keep_ui_state)
def on_finish(self): # show the result import plotly.io as pio pio.renderers.default = "browser" reader = AccountReader(trader_names=[self.trader_name]) drawer = Drawer(main_data=NormalData( reader.data_df.copy()[['trader_name', 'timestamp', 'all_value']], category_field='trader_name')) drawer.draw_line()
def update_chart_selector(intent): if intent: charts = NormalData.get_charts_by_intent(intent=intent) options = [ {'label': chart.value, 'value': chart.value} for chart in charts ] value = charts[0].value return options, value raise dash.exceptions.PreventUpdate()
def data_drawer(self) -> Drawer: # FIXME"refresh normal_data? self.normal_data = NormalData(df=self.data_df, category_field=self.category_field, index_field=self.time_field, is_timeseries=True) return Drawer(data=self.normal_data)
def move_on(self, to_timestamp: Union[str, pd.Timestamp] = None, timeout: int = 20) -> bool: """ get the data happened before to_timestamp,if not set,get all the data which means to now Parameters ---------- to_timestamp : timeout : the time waiting the data ready in seconds Returns ------- whether got data """ if not df_is_not_null(self.data_df): self.load_data() return False df = self.data_df.reset_index(level='timestamp') recorded_timestamps = df.groupby(level=0)['timestamp'].max() self.logger.info('level:{},current_timestamps:\n{}'.format( self.level, recorded_timestamps)) changed = False # FIXME:we suppose history data should be there at first start_time = time.time() for category, recorded_timestamp in recorded_timestamps.iteritems(): while True: category_filter = [self.category_column == category] if self.filters: filters = self.filters + category_filter else: filters = category_filter added = get_data(data_schema=self.data_schema, provider=self.provider, columns=self.columns, start_timestamp=recorded_timestamp, end_timestamp=to_timestamp, filters=filters, level=self.level) if df_is_not_null(added): would_added = added[ added['timestamp'] != recorded_timestamp].copy() if not would_added.empty: added = index_df_with_category_xfield( would_added, category_field=self.category_field, xfield=self.time_field) self.logger.info('category:{},added:\n{}'.format( category, added)) self.data_df = self.data_df.append(added) self.data_df = self.data_df.sort_index(level=[0, 1]) for listener in self.data_listeners: listener.on_category_data_added(category=category, added_data=added) changed = True # if got data,just move to another category break cost_time = time.time() - start_time if cost_time > timeout: self.logger.warning( 'category:{} level:{} getting data timeout,to_timestamp:{},now:{}' .format(category, self.level, to_timestamp, now_pd_timestamp())) break if changed: for listener in self.data_listeners: listener.on_data_changed(self.data_df) # update the normal_data too self.normal_data = NormalData(df=self.data_df, category_field=self.category_field, index_field=self.time_field, is_timeseries=True) return changed
align='left'), **kwargs) return self.show(plotly_data=data, plotly_layout=plotly_layout, annotation_df=annotation_df, render=render, file_name=file_name, width=width, height=height, title=title, keep_ui_state=keep_ui_state) def draw_data_table(self, id=None): cols = self.normal_data.data_df.index.names + self.normal_data.data_df.columns.tolist() df = self.normal_data.data_df.reset_index() return dash_table.DataTable( id=id, columns=[{'name': i, 'id': i} for i in cols], data=df.to_dict('records'), filter_action="native", sort_action="native", sort_mode='multi', row_selectable='multi', selected_rows=[], page_action='native', page_current=0, page_size=5, ) if __name__ == '__main__': for table_type in TableType: drawer = Drawer(data=NormalData(NormalData.sample(table_type=table_type))) drawer.draw_table()
{'id': 'property', 'name': 'property', 'editable': False}, {'id': 'y_axis', 'name': 'y_axis', 'presentation': 'dropdown'}, {'id': 'chart', 'name': 'chart', 'presentation': 'dropdown'} ], dropdown={ 'y_axis': { 'options': [ {'label': i, 'value': i} for i in ['y1', 'y2', 'y3', 'y4', 'y5'] ] }, 'chart': { 'options': [ {'label': chart_type.value, 'value': chart_type.value} for chart_type in NormalData.get_charts_by_intent(IntentType.compare_self) ] } }, editable=True ), ), html.Div(id='table-type-label', children=None), html.Div( [ html.Div([dcc.Dropdown(id='intent-selector')], style={'width': '50%', 'display': 'inline-block'}), html.Div([dcc.Dropdown(id='chart-selector')], style={'width': '50%', 'display': 'inline-block'}) ]
def result_drawer(self) -> Drawer: return Drawer( NormalData(df=self.result_df, index_field=self.time_field, is_timeseries=True))
def depth_drawer(self) -> Drawer: drawer = Drawer( NormalData(df=self.depth_df, index_field=self.time_field, is_timeseries=True)) return drawer
def draw_data_table(self, id=None): cols = self.normal_data.data_df.index.names + self.normal_data.data_df.columns.tolist( ) df = self.normal_data.data_df.reset_index() return dash_table.DataTable( id=id, columns=[{ 'name': i, 'id': i } for i in cols], data=df.to_dict('records'), filter_action="native", sort_action="native", sort_mode='multi', row_selectable='multi', selected_rows=[], page_action='native', page_current=0, page_size=5, ) if __name__ == '__main__': for table_type in TableType: drawer = Drawer( data=NormalData(NormalData.sample(table_type=table_type))) drawer.draw_table()
def pipe_drawer(self) -> Drawer: drawer = Drawer(NormalData(df=self.pipe_df)) return drawer
start_timestamp: Union[str, pd.Timestamp] = None, end_timestamp: Union[str, pd.Timestamp] = None, columns: List = None, filters: List = None, order: object = None, level: IntervalLevel = None, trader_names: List[str] = None) -> None: self.trader_names = trader_names self.filters = filters if self.trader_names: filter = [Order.trader_name == name for name in self.trader_names] if self.filters: self.filters += filter else: self.filters = filter super().__init__(SimAccount, None, None, None, None, None, the_timestamp, start_timestamp, end_timestamp, columns, filters, order, None, 'zvt', level, 'trader_name', 'timestamp', None) if __name__ == '__main__': reader = AccountReader(trader_names=['000338_ma_trader']) drawer = Drawer(main_data=NormalData( reader.data_df.copy()[['trader_name', 'timestamp', 'all_value']], category_field='trader_name')) drawer.draw_line()
def result_drawer(self) -> Drawer: return Drawer(NormalData(df=self.result_df))
bordercolor='#c7c7c7', borderwidth=1, bgcolor=color, opacity=0.8)) return annotations if __name__ == '__main__': df = get_data(data_schema=Stock1dKdata, provider='joinquant', entity_ids=['stock_sz_000001']) df1 = get_data(data_schema=Stock1dMaStateStats, provider='zvt', entity_ids=['stock_sz_000001'], columns=['current_count']) # print(df) # # drawer = Drawer(data=NormalData(df=df.loc[:, ['close']])) # drawer.draw_histogram(entity_in_subplot=True) drawer = Drawer(data=NormalData(df), sub_data=NormalData(df1[['current_count']])) drawer.draw_kline() # df1 = df.copy() # df1['entity_id'] = 'stock_china_stocks' # # drawer = Drawer(data=NormalData(df=df1.loc[:, ['entity_id', 'timestamp', 'total_count', 'current_count']])) # drawer.draw_histogram(entity_in_subplot=True)