def draw(df, xf, yf, tf, title='New Stock Chart'): ''' Draw hight stock chart by pandas.DataFrame Args: df: dataFrame xf: field name of dataFrame to x coordinate, the value of x must be unique datetime. yf: field name of dataFrame to y coordinate. tf: field name of dataFrame to line title. ''' uniques = df[tf].unique() # log.debug(str(uniques)) c = Highstock() for unique in uniques: sel_df = df[df[tf] == unique] sel_df = sel_df.loc[:, [xf, yf]] xyl = xy(sel_df) c.add_data_set(xyl, series_type='line', name=unique) options = { 'title': { 'text': title }, } c.set_dict_options(options) c.save_file() log.info('Successful completion of drawing.')
def plot(self, plt_type='all'): self.getsecID(sec=1) if not exist: return self.etf + ' ceased trading' #這邊廢code很多QQ #為避免error,先創一堆空的dict(相信這邊有更好的寫法XD) nav_data = dict() price_data = dict() volume_data = dict() nav_data[self.etf] = dict() price_data[self.etf] = dict() volume_data[self.etf] = dict() if plt_type == 'all': nav_data = self.data(data_type='nav') price_data = self.data(data_type='price') volume_data = self.data(data_type='volume') elif plt_type == 'nav': nav_data = self.data(data_type='nav') elif plt_type == 'price': price_data = self.data(data_type='price') else: return 'Sorry, plt_type should be nav, price or all' #用highchart裡的hichstock畫圖 H = Highstock() nav_high_data = [[ datetime.strptime(i, "%Y-%m-%d"), nav_data[list(nav_data.keys())[0]][i] ] for i in nav_data[list(nav_data.keys())[0]]] price_high_data = [[ datetime.strptime(i, "%Y-%m-%d"), price_data[list(price_data.keys())[0]][i] ] for i in price_data[list(price_data.keys())[0]]] volume_high_data = [[ datetime.strptime(i, "%Y-%m-%d"), volume_data[list(volume_data.keys())[0]][i] ] for i in volume_data[list(volume_data.keys())[0]]] if plt_type == 'all': H.add_data_set(price_high_data, 'line', 'price', id='dataseries', color='#969696', tooltip={'valueDecimals': 4}) H.add_data_set(nav_high_data, 'line', 'nav', id='dataseries', tooltip={'valueDecimals': 4}) H.add_data_set(volume_high_data, 'column', 'Volume', yAxis=1, color='#969696') elif plt_type == 'nav': H.add_data_set(nav_high_data, 'line', 'nav', id='dataseries', tooltip={'valueDecimals': 4}) elif plt_type == 'price': H.add_data_set(price_high_data, 'line', 'price', id='dataseries', color='#969696', tooltip={'valueDecimals': 4}) options = { 'rangeSelector': { 'selected': 4 }, 'title': { 'text': self.etf.upper() }, 'tooltip': { 'style': { 'width': '200px' }, 'shared': True, 'pointFormat': '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>', }, 'yAxis': [{ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'USD' }, 'height': '60%', 'lineWidth': 0.5 }, { 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'Volume' }, 'top': '65%', 'height': '35%', 'offset': 0, 'lineWidth': 2 }], #'plotOptions': {'series': {'compare': 'percent'}}, } H.set_dict_options(options) return H
H.add_data_set(data, 'line', 'USD to EUR', id='dataseries') H.add_data_set(data2, 'flags', onSeries='dataseries', shape='circlepin', width=16) options = { 'rangeSelector': { 'selected': 0 }, 'title': { 'text': 'USD to EUR exchange rate' }, 'tooltip': { 'style': { 'width': '200px' }, 'valueDecimals': 4, 'shared': True }, 'yAxis': { 'title': { 'text': 'Exchange rate' } }, } H.set_dict_options(options) H.htmlcontent
names = ["MSFT", "AAPL", "GOOG"] for name in names: data_url = "http://www.highcharts.com/samples/data/jsonp.php?filename=" + name.lower() + "-c.json&callback=?" data = jsonp_loader(data_url, sub_d=r"(\/\*.*\*\/)") H.add_data_set(data, "line", name) options = { "rangeSelector": {"selected": 4}, "yAxis": { "labels": { "formatter": "function () {\ return (this.value > 0 ? ' + ' : '') + this.value + '%';\ }" }, "plotLines": [{"value": 0, "width": 2, "color": "silver"}], }, "plotOptions": {"series": {"compare": "percent"}}, "tooltip": { "pointFormat": '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>', "valueDecimals": 2, }, } H.set_dict_options(options) H.htmlcontent
def plot(self, title=False, width=600, height=300, load_js=None, js_sources=[]): chart_height = (height + 50) * self.number_of_candlestick_charts - 50 + 200 H = Highstock(width=width, height=chart_height) groupingUnits = [ ['hour', [60]], ] with open( os.path.join(os.path.dirname(os.path.abspath(__file__)), "files/load.jinja")) as f: load_tempate = jinja2.Template(f.read()) options = { 'rangeSelector': { 'buttons': [{ 'type': 'minute', 'count': 180, 'text': '3h' }, { 'type': 'minute', 'count': 360, 'text': '6h' }, { 'type': 'minute', 'count': 720, 'text': '12h' }, { 'type': 'minute', 'count': 60 * 24, 'text': '1d' }, { 'type': 'minute', 'count': 60 * 48, 'text': '2d' }, { 'type': 'second', 'count': 1, 'text': '1s' }, { 'type': 'second', 'count': 10, 'text': '10s' }], 'selected': 4, 'inputEnabled': False }, 'plotOptions': { 'series': { 'turboThreshold:': 0, 'dataGrouping': { 'enabled': False, }, 'animation': False, }, 'scatter': { 'turboThreshold:': 0, 'marker': { 'radius': 5, 'symbol': 'circle', 'states': { 'hover': { 'enabled': True, 'lineColor': 'rgb(100,100,100)' } } }, 'tooltip': { 'pointFormat': '{series.name} x:{point.x}, y:{point.y}' #'pointFormatter': """ #function () { debugger; } #""" }, 'states': { 'hover': { 'marker': { 'enabled': False } } }, }, }, 'navigator': { 'enabled': True, 'height': 20 }, 'chart': { 'animation': False, }, 'title': { 'text': '', 'style': { 'display': 'none' } }, 'legend': { 'enabled': True, }, 'yAxis': [] } if title: options['title'] = {'text': title} if load_js: load_js = load_tempate.render(symbols=self.symbols) options['event']['load'] = load_js idx = -1 current_y = -height for chart_type, symbol, data, is_new_chart in self.symbols: if is_new_chart: idx += 1 current_y += height + 50 options['yAxis'].append({ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'y' }, 'top': '%dpx' % (current_y), 'height': '%dpx' % (height), 'lineWidth': 2, 'offset': 0, }) if chart_type == 'candlestick': H.add_data_set(data, chart_type, symbol, yAxis=idx, dataGrouping={}) elif chart_type == 'line': H.add_data_set(data, chart_type, symbol, yAxis=idx, dataGrouping={}) elif chart_type == 'scatter': H.add_data_set(data, chart_type, symbol, yAxis=idx, dataGrouping={}, turboThreshold=0) H.set_dict_options(options) H.add_JSscript(self.theme, "head") for js_source in js_sources: H.add_JSsource(js_source) return H
def plot(self, title=False, width=600, height=300, load_js=None, js_sources=[]): chart_height = (height + 50) * 1 - 50 + 200 H = Highstock(width=width, height=chart_height) groupingUnits = [ ['hour', [60]], ] with open( os.path.join(os.path.dirname(os.path.abspath(__file__)), "files/load.jinja")) as f: load_tempate = jinja2.Template(f.read()) options = { 'rangeSelector': { 'buttons': [{ 'type': 'minute', 'count': 180, 'text': '3h' }, { 'type': 'minute', 'count': 360, 'text': '6h' }, { 'type': 'minute', 'count': 720, 'text': '12h' }, { 'type': 'minute', 'count': 60 * 24, 'text': '1d' }, { 'type': 'minute', 'count': 60 * 48, 'text': '2d' }, { 'type': 'second', 'count': 1, 'text': '1s' }, { 'type': 'second', 'count': 10, 'text': '10s' }], 'selected': 4, 'inputEnabled': False }, 'plotOptions': { 'series': { 'turboThreshold:': 0, 'dataGrouping': { 'enabled': False, }, 'animation': False } }, 'navigator': { 'enabled': True, 'height': 20 }, 'chart': { 'animation': False, }, 'legend': { 'enabled': True, }, 'yAxis': [], 'title': { 'text': '', 'style': { 'display': 'none' } }, } if title: options['title'] = {'text': title} if load_js: load_js = load_tempate.render(symbols=self.symbols) options['event']['load'] = load_js symbol_data = {} for idx, (symbol, data) in enumerate(self.symbols): symbol_data[symbol] = data options['yAxis'].append({ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'y' }, 'lineWidth': 2, 'offset': 0, }) H.add_data_set(data, 'line', symbol, dataGrouping={}) H.set_dict_options(options) H.add_JSscript(self.theme, "head") for js_source in js_sources: H.add_JSsource(js_source) return H
data = Load.FinData(dataset='TaiwanStockPrice', select='2330', date='2018-10-10') print(' change type of dataframe to highcharts ') data['date'] = date2millisecond(data['date']) list_data = [] for i in range(len(data)): tem = [ int(data.loc[i, 'date']), float(data.loc[i, 'max']), float(data.loc[i, 'min']) ] list_data.append(tem) chart.add_data_set(list_data, 'arearange', 'Temperatures') options = { 'rangeSelector': { 'selected': 2 }, 'title': { 'text': 'Temperature variation by day' }, } chart.set_dict_options(options) # This will generate and save a .html file at the location you assign chart.save_file()
def hc_candlestick_and_volume(data, title, theme=None): H = Highstock() ohlc = [] volume = [] groupingUnits = [['week', [1]], ['month', [1, 2, 3, 4, 6]]] for i in range(len(data)): ohlc.append([ data[i][0], # the date data[i][1], # open data[i][2], # high data[i][3], # low data[i][4] # close ]) volume.append([ data[i][0], # the date data[i][5] # the volume ]) options = { 'rangeSelector': { 'selected': 1 }, 'title': { 'text': title }, 'yAxis': [{ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'OHLC' }, 'height': '60%', 'lineWidth': 2 }, { 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'Volume' }, 'top': '65%', 'height': '35%', 'offset': 0, 'lineWidth': 2 }], } H.add_data_set(ohlc, 'candlestick', 'OHLC', dataGrouping={'units': groupingUnits}) H.add_data_set(volume, 'column', 'Volume', yAxis=1, dataGrouping={'units': groupingUnits}) H.set_dict_options(options) return hc_plot(H, title, theme)
def pplot_from_df(df, kind='line', stock=False, y_axes=None, debug=False, **kwargs): """ :param df: (pd.DataFrame): Column names become series names :param kind: (str or list): Use list of same length as number of cols for multiple plot types (e.g. ['line_w_col', 'column']) :param stock: :param y_axes: :param debug: (bool): Pretty prints options json :param kwargs: (): Plotting options such as resolution, labels, color, etc. :return: """ # If series given instead of DataFrame, convert: df = pd.DataFrame(df) # If no columns, do nothing: if df.shape[1] == 0: print("nothing to plot...") return # Create a color list for each line to plot: if 'colors' not in kwargs: kwargs['colors'] = map( lambda val: val.get_hex_l(), list(Color('#1492FB').range_to(Color('#27662A'), df.shape[1])) ) # Set y axis if y_axes is None: y_axes = [1] * df.shape[1] else: assert (len(y_axes) == df.shape[1]), "y_axes must be list of same length as dataframe columns" # Should also assert something about the values in this list... later # Create highcharts_df object: # (Use height and width if provided): if stock: hc_visualization = Highstock(**{key: kwargs.pop(key) for key in ['width', 'height'] if key in kwargs}) else: hc_visualization = Highchart(**{key: kwargs.pop(key) for key in ['width', 'height'] if key in kwargs}) # Set timeseries encoding automatically: if df.index.is_all_dates: # NOTE *** AFTER monthes, I finally figured out that certain types of option settings # were the cause of time not encoding properly. Basically, customer jinja-js like {x.point} functions # need to be created carefully with timestamps in mind. Also, data must be encoded as 32 bit datetime. # (e.g. df.index.map(lambda dt: dt.to_datetime()), or [(datetime.datetime(2016,9,28), $val), ...] hc_visualization.set_options('xAxis', {'type': 'datetime'}) # Set options (chart customization): options = get_highchart_options(**kwargs) if kind == 'line': for col_idx, col in enumerate(df.columns): hc_visualization = _highcharts_add_data_set(hc_visualization, df[col], col, kind, y_axes[col_idx]) elif kind == 'bar' or kind == 'column': # Add bar categories (dataframe index): options['xAxis']['categories'] = list(df.index) # Add grouped column/bar data: for col_idx, col in enumerate(df.columns): hc_visualization = _highcharts_add_data_set(hc_visualization, df[col], col, kind, y_axes[col_idx]) elif isinstance(kind, list): # Make sure the kind list is the right size: assert len(kind) == df.shape[1], "list kind must be the same length as df" # If columns in the list, map to line_w_col: if 'bar' in kind or 'column' in kind: kind = map(lambda a_kind: ("%s_w_col" % a_kind) if a_kind == 'line' else a_kind, kind) # Add categories: options['xAxis']['categories'] = list(df.index.values) # Add grouped data: for col_idx, col in enumerate(df.columns): hc_visualization = _highcharts_add_data_set(hc_visualization, df[col], col, kind[col_idx], y_axes[col_idx]) # Set options: hc_visualization.set_dict_options(options) # Print options json if debug mode is on: if debug: pp = pprint.PrettyPrinter(indent=1) pp.pprint(options) return hc_visualization
def hc_candlestick_and_volume(data, title, theme=None): H = Highstock() ohlc = [] volume = [] groupingUnits = [ ['week', [1]], ['month', [1, 2, 3, 4, 6]] ] for i in range(len(data)): ohlc.append( [ data[i][0], # the date data[i][1], # open data[i][2], # high data[i][3], # low data[i][4] # close ] ) volume.append( [ data[i][0], # the date data[i][5] # the volume ] ) options = { 'rangeSelector': { 'selected': 1 }, 'title': { 'text': title }, 'yAxis': [{ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'OHLC' }, 'height': '60%', 'lineWidth': 2 }, { 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'Volume' }, 'top': '65%', 'height': '35%', 'offset': 0, 'lineWidth': 2 }], } H.add_data_set(ohlc, 'candlestick', 'OHLC', dataGrouping = { 'units': groupingUnits }) H.add_data_set(volume, 'column', 'Volume', yAxis = 1, dataGrouping = { 'units': groupingUnits }) H.set_dict_options(options) return hc_plot(H, title, theme)
def creatChart(klines, symbol): filename = "%s_dayk" % symbol ohlc = [] volume = [] for line in klines: ohlc.append([ line[0], #open float(line[1]), #high float(line[2]), # low float(line[3]), # close float(line[4]) ]) volume.append([line[0], float(line[5])]) H = Highstock() groupingUnits = [['day', [1]]] options = { 'rangeSelector': { 'selected': 4 }, 'chart': { 'zoomType': 'x', 'reflow': True, 'height': 900 }, 'title': { 'text': '%s' % (symbol) }, 'subtitle': { 'text': filename }, 'yAxis': [{ 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'OHLC' }, 'height': '60%', 'lineWidth': 2 }, { 'labels': { 'align': 'right', 'x': -3 }, 'title': { 'text': 'Volume' }, 'top': '65%', 'height': '35%', 'offset': 0, 'lineWidth': 2 }], } H.add_data_set(ohlc, 'candlestick', symbol, dataGrouping={'units': groupingUnits}) H.add_data_set(volume, 'column', 'Volume', yAxis=1, dataGrouping={'units': groupingUnits}) H.set_dict_options(options) H.save_file(filename) print("===--- Completed ---===")
def main(argv): from highcharts import Highstock # 暂时这样避免其他脚本 import 出错 unittest() opts, args = parse_options(argv) #exchanges = ('binance', 'huobipro', 'okex', 'zb') #symbol = 'qtum/btc' #sdt = '2018-01-20 18-00-00' #edt = '2018-01-20 18-59-00' #folder = r'C:\Users\Eph\Desktop\CC\trade\ccxtbot\CCMarkets\data' exchanges = args symbol = opts.get('symbol') sdt = opts.get('start') edt = opts.get('stop') folder = opts.get('folder') prec = int(opts.get('prec', 8)) fname = opts.get('file', 'StockChart') verbose = opts.get('verbose', False) if not exchanges or not symbol or not sdt or not edt or not folder: usage(argv[0]) return 2 options = { 'chart': { 'height': '50%', # default None }, 'title': { 'text': 'Price Difference', }, "tooltip": { "xDateFormat": "%Y-%m-%d %H:%M:%S %A", # NOTE: BUG, 设置不生效 'pointFormat': '<span style="color:{point.color}">' + '\\u25CF'.decode('unicode-escape') + \ '</span> {series.name}: <b>{point.y}</b><br/>', 'padding': 1, # default 8 }, "legend": { "enabled": True }, "xAxis": { "type": "datetime" }, 'yAxis': { 'title': { 'text': '价格', }, 'opposite': True, # False 表示在左边显示,默认值为 True }, # 这是K线图的属性,不画K线图的话不需要 "plotOptions": { "candlestick": { "color": "#d75442", "upColor": "#6ba583" } }, "rangeSelector": { "buttons": [ { "type" : "hour", "count" : 1, "text" : "1h", }, { "type" : 'hour', "count" : 3, "text" : "3h" }, { "type" : "hour", "count" : 6, "text" : "6h" }, { "type" : "hour", "count" : 12, "text" : "12h" }, { "type" : "all", "text" : "All" } ], #"selected": 2, # 默认选择的索引号,从0开始,默认值为 undefined "inputEnabled": True, "inputBoxWidth": 150, # default 90 'inputDateFormat': '%Y/%m/%d %H:%M:%S', 'inputEditDateFormat': '%Y/%m/%d %H:%M:%S', }, } chart = Highstock() chart.set_options('global', {'timezoneOffset': -8 * 60}) chart.set_dict_options(options) #chart.set_options('chart', {'height': None}) chart.set_options( 'tooltip', { #'pointFormat': '<span style="color:{point.color}">' + '\\u25CF'.decode('unicode-escape') + \ #'</span> {series.name}: <b>{point.y:.%df}</b><br/>' % prec, 'valueDecimals': prec, 'valueSuffix': ' ' + symbol.replace('/', '_').upper().split('_')[1], }) ers = [] stats = {} for exchange in exchanges: inst = ExchangeRecords(exchange, symbol, sdt, edt, folder) ers.append(inst) stats[exchange] = {} stats[exchange]['records_count'] = 0 chart.set_options('subtitle', {'text': ers[0].symbol.replace('_', '/')}) # 'binance': {'Buy': x, 'Sell': y} all_records = {} loop_count = 0 # 标记哪个交易所已经拿完数据了 # {exchange: True/False, ...} ctl = {} for inst in ers: ctl[inst.exchange] = False while True: all_true = True for v in ctl.itervalues(): if not v: all_true = False break if ctl and all_true: break loop_count += 1 for inst in ers: record = inst.get_one_record() if record is None: ctl[inst.exchange] = True continue records_dict = all_records.setdefault(inst.exchange, {}) if not record: #ctl[inst.exchange] = True continue stats[inst.exchange]['records_count'] += 1 # 不需要小数点 t = int(int(float(record[0])) * 1000) #t += 3600*1000*8 # GMT+8 buy = records_dict.setdefault('buy', []) buy.append([t, float(record[1])]) sell = records_dict.setdefault('sell', []) sell.append([t, float(record[2])]) last = records_dict.setdefault('last', []) last.append([t, float(record[3])]) if verbose: print('loop_count:', loop_count) Log(json.dumps(stats, indent=4, sort_keys=True)) for exchange in exchanges: records_dict = all_records[exchange] chart.add_data_set(records_dict['buy'], series_type='line', name='%s buy' % exchange) chart.add_data_set(records_dict['sell'], series_type='line', name='%s sell' % exchange) chart.add_data_set(records_dict['last'], series_type='line', name='%s last' % exchange) # 后缀名值 .html chart.save_file(filename=fname) Log('Successfully write to the file:', fname + '.html')