예제 #1
0
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
예제 #2
0
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')