python_PyQt5日周月K线纵向对齐显示_2_显示工具

news2024/9/26 5:17:25

目录

写在前面:

结果显示:

代码:

计算日数据、周数据,月数据,并返回

生成提示信息数据,同时将日周月合并到一个DataFrame中

返回K线图和成交量柱状图的数据

主界面,显示日周月对齐的K线图

使用方法


写在前面:

“PyQt5日周月K线纵向对齐显示”,将分三篇博文描述

1 数据处理。将数据处理成适合图形显示的格式。(已写,请看往期博文)

2 显示工具开发。用pyqtgraph开发

3 聚焦某段图形

结果显示:

日周月,K线图与成交量柱状图,共6个图拼接在一起,滚动显示,横坐标对齐

代码:

在前面博文中有介绍了主要数据处理的逻辑,这里直接上代码。

计算日数据、周数据,月数据,并返回

def temp_000():
    junxian = 20
    columns_list = ['row_i', 'tradeDate', 'openPrice', 'highestPrice', 'lowestPrice', 'closePrice',
                               'turnoverVol', 'turnoverValue','ma','vol_ma','value_ma']
    file_path = r'E:/temp003/600941.xlsx'
    df = pd.read_excel(file_path,engine='openpyxl')
    df['row_i'] = [i for i in range(len(df))]
    df['o_date'] = pd.to_datetime(df['tradeDate'])
    df['ma'] = talib.MA(df['closePrice'], timeperiod=junxian)
    df['vol_ma'] = talib.MA(df['turnoverVol'], timeperiod=junxian)
    df['value_ma'] = talib.MA(df['turnoverValue'], timeperiod=junxian)
    week_group = df.resample('W-FRI', on='o_date')
    month_group = df.resample('M', on='o_date')

    week_df = week_group.last()
    week_df['row_i'] = week_group.last()['row_i']
    week_df['openPrice'] = week_group.first()['openPrice']
    week_df['lowestPrice'] = week_group.min()['lowestPrice']
    week_df['highestPrice'] = week_group.max()['highestPrice']
    week_df['turnoverVol'] = week_group.sum()['turnoverVol']
    week_df['turnoverValue'] = week_group.sum()['turnoverValue']
    week_df = week_df.loc[:, columns_list].copy()
    week_df.dropna(axis=0, how='any', subset=['closePrice'], inplace=True)
    week_df['ma'] = talib.MA(week_df['closePrice'], timeperiod=junxian)
    week_df['vol_ma'] = talib.MA(week_df['turnoverVol'], timeperiod=junxian)
    week_df['value_ma'] = talib.MA(week_df['turnoverValue'], timeperiod=junxian)

    month_df = month_group.last()
    month_df['row_i'] = month_group.last()['row_i']
    month_df['openPrice'] = month_group.first()['openPrice']
    month_df['lowestPrice'] = month_group.min()['lowestPrice']
    month_df['highestPrice'] = month_group.max()['highestPrice']
    month_df['turnoverVol'] = month_group.sum()['turnoverVol']
    month_df['turnoverValue'] = month_group.sum()['turnoverValue']
    month_df = month_df.loc[:, columns_list].copy()
    month_df.dropna(axis=0, how='any', subset=['closePrice'], inplace=True)
    month_df['ma'] = talib.MA(month_df['closePrice'], timeperiod=junxian)
    month_df['vol_ma'] = talib.MA(month_df['turnoverVol'], timeperiod=junxian)
    month_df['value_ma'] = talib.MA(month_df['turnoverValue'], timeperiod=junxian)

    daily_df = df.loc[:, columns_list].copy()
    return daily_df, week_df, month_df
    # daily_df.to_excel(r'E:/temp009/day.xlsx',engine='openpyxl')
    # week_df.to_excel(r'E:/temp009/week.xlsx',engine='openpyxl')
    # month_df.to_excel(r'E:/temp009/month.xlsx',engine='openpyxl')
    return daily_df,week_df,month_df

生成提示信息数据,同时将日周月合并到一个DataFrame中

def temp_001(daily_df,week_df,month_df):
    week_df.rename(
        columns={'row_i': 'week_i', 'tradeDate': 'week_tradeDate', 'closePrice': 'week_close', 'openPrice': 'week_open',
                 'lowestPrice': 'week_low', 'highestPrice': 'week_high', 'turnoverVol': 'week_turnoverVol',
                 'turnoverValue': 'week_turnoverValue'}, inplace=True)
    month_df.rename(columns={'row_i': 'month_i', 'tradeDate': 'month_tradeDate', 'closePrice': 'month_close',
                             'openPrice': 'month_open', 'lowestPrice': 'month_low', 'highestPrice': 'month_high',
                             'turnoverVol': 'month_turnoverVol', 'turnoverValue': 'month_turnoverValue'}, inplace=True)

    three_df = pd.merge(daily_df, week_df, how='left', left_on='tradeDate', right_on='week_tradeDate')
    three_df.fillna(method='bfill', inplace=True)
    three_df = pd.merge(three_df, month_df, how='left', left_on='tradeDate', right_on='month_tradeDate')
    three_df.fillna(method='bfill', inplace=True)
    # three_df.to_excel(r'E:/temp009/111/three.xlsx',engine='openpyxl')
    res_map = {}
    for i, row in three_df.iterrows():
        row_i = row['row_i']
        res_map[str(row_i)] = {
            '日期': row['tradeDate'],
            '收盘价': row['closePrice'],
            '开盘价': row['openPrice'],
            '最高价': row['highestPrice'],
            '最低价': row['lowestPrice'],
            '成交量': row['turnoverVol'],
            '成交额': row['turnoverValue'],
            '周': row['week_tradeDate'],
            '周收盘价': row['week_close'],
            '周开盘价': row['week_open'],
            '周最高价': row['week_high'],
            '周最低价': row['week_low'],
            '周成交量': row['week_turnoverVol'],
            '周成交额': row['week_turnoverValue'],
            '月': row['month_tradeDate'],
            '月收盘价': row['month_close'],
            '月开盘价': row['month_open'],
            '月最高价': row['month_high'],
            '月最低价': row['month_low'],
            '月成交量': row['month_turnoverVol'],
            '月成交额': row['month_turnoverValue']
        }
    return res_map, three_df

返回K线图和成交量柱状图的数据

def temp_002(df):
    # 生成K线图和成交量柱状图
    k_height_num = 400
    vol_height_num = 100
    candle_data = df.loc[:, ['row_i', 'openPrice', 'closePrice', 'lowestPrice', 'highestPrice']].values.tolist()
    curve_data = {
        'x': df['row_i'].values.tolist(),
        'y': df['ma'].values.tolist()
    }
    one = {
        'height_num': k_height_num,
        'yMin': df['lowestPrice'].min(),
        'yMax': df['highestPrice'].max(),
        'data_list': [
            {
                'type': 'candle',
                'data': candle_data
            },
            {
                'type': 'curve',
                'data': curve_data
            }
        ]
    }
    bar_data = df.loc[:, ['row_i', 'openPrice', 'closePrice', 'turnoverVol']].values.tolist()
    curve_data2 = {
        'x': df['row_i'].values.tolist(),
        'y': df['vol_ma'].values.tolist()
    }
    two = {
        'height_num': vol_height_num,
        'yMin': 0,
        'yMax': df['turnoverVol'].max(),
        'data_list': [
            {
                'type': 'bar',
                'data': bar_data
            },
            {
                'type': 'curve',
                'data': curve_data2
            }
        ]
    }
    return one, two

K线控件、成交量bar控件

class CandlestickItem(pg.GraphicsObject):
    def __init__(self, data):
        pg.GraphicsObject.__init__(self)
        self.data = data  ## data must have fields: time, open, close, min, max
        self.generatePicture()

    def generatePicture(self):
        ## pre-computing a QPicture object allows paint() to run much more quickly,
        ## rather than re-drawing the shapes every time.
        self.picture = QtGui.QPicture()
        p = QtGui.QPainter(self.picture)
        p.setPen(pg.mkPen('d'))
        # w = (self.data[1][0] - self.data[0][0]) / 3.
        w = 0.3
        for (t, open, close, min, max) in self.data:
            p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
            if open < close:
                p.setBrush(pg.mkBrush('r'))
            else:
                p.setBrush(pg.mkBrush('g'))
            p.drawRect(QtCore.QRectF(t-w, open, w * 2, close - open))
        p.end()

    def paint(self, p, *args):
        p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        ## boundingRect _must_ indicate the entire area that will be drawn on
        ## or else we will get artifacts and possibly crashing.
        ## (in this case, QPicture does all the work of computing the bouning rect for us)
        return QtCore.QRectF(self.picture.boundingRect())

class VOLtickItem(pg.GraphicsObject):
    def __init__(self, data):
        pg.GraphicsObject.__init__(self)
        self.data = data  ## data must have fields: time,open,close, vol
        self.generatePicture()

    def generatePicture(self):
        self.picture = QtGui.QPicture()
        p = QtGui.QPainter(self.picture)
        p.setPen(pg.mkPen('d'))
        # w = (self.data[1][0] - self.data[0][0]) / 3.
        w = 0.3
        for (t,open,close, vol) in self.data:
            if open < close:
                p.setBrush(pg.mkBrush('r'))
            else:
                p.setBrush(pg.mkBrush('g'))
            p.drawRect(QtCore.QRectF(t - w, 0, w * 2, vol))
        p.end()

    def paint(self, p, *args):
        p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        ## boundingRect _must_ indicate the entire area that will be drawn on
        ## or else we will get artifacts and possibly crashing.
        ## (in this case, QPicture does all the work of computing the bouning rect for us)
        return QtCore.QRectF(self.picture.boundingRect())

主界面,显示日周月对齐的K线图

class ExampleWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_data()
        self.init_ui()
        pass
    def init_data(self):
        self.v_list = []
        self.vline_list = []
        self.hline_list = []
        self.label_list = []

        self.data_list = []
        self.show_map: Dict = {}
        self.mark_data_map: Dict = {}
        self.mark_item_map: Dict = {}

        self.graph_type_candle: str = 'candle'
        self.graph_type_curve: str = 'curve'
        self.graph_type_bar: str = 'bar'

        self.tip_show_yeah: bool = False
        pass
    def init_ui(self):
        self.setMinimumWidth(800)
        self.setMinimumHeight(600)
        origin_btn = QtWidgets.QPushButton('返回原位')
        origin_btn.clicked.connect(self.origin_btn_clicked)
        self.tip_checkbox = QtWidgets.QCheckBox('数据提示框')
        self.tip_checkbox.stateChanged.connect(self.tip_checkbox_stateChanged)

        layout1 = QtWidgets.QHBoxLayout()
        layout1.addWidget(origin_btn)
        layout1.addWidget(self.tip_checkbox)
        layout1.addStretch(1)

        self.pw_layout = QtWidgets.QVBoxLayout()
        self.scroll_area = QtWidgets.QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scroll_area.setViewportMargins(20,20,20,20)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(layout1)
        layout.addWidget(self.scroll_area)
        self.setLayout(layout)
        pass

    def focus_location(self,left_x:int,right_x:int,y_data:List):
        if self.v_list:
            v0 = self.v_list[0]
            v0.setXRange(min=left_x,max=right_x)
            for i,v in enumerate(self.v_list):
                y_node = y_data[i]
                v.setYRange(min=y_node[0],max=y_node[1])
        pass
    def restart_init(self):
        self.v_list.clear()
        self.vline_list.clear()
        self.hline_list.clear()
        self.label_list.clear()
        self.data_list.clear()
        self.show_map.clear()
        pass

    def origin_btn_clicked(self):
        if self.v_list:
            v0 = self.v_list[0]
            v0.enableAutoRange() # 还原到初始状态
        pass
    def tip_checkbox_stateChanged(self):
        if self.tip_checkbox.isChecked():
            self.tip_show_yeah = True
        else:
            self.tip_show_yeah = False
        pass
    def set_data(self,data:Dict):
        self.restart_init()
        self.show_map = data['show_map']
        self.data_list = data['data_list']
        self.fill_viewbox()
        pass
    def fill_viewbox(self):
        pw = pg.GraphicsLayoutWidget(show=False)
        h_i = 0
        for i,node in enumerate(self.data_list):
            '''
            height_num
            data_list:[
            {
            type:candle,curve,bar
            data:[]
            },
            {}
            ]
            '''
            v = pw.addViewBox(row=i, col=0)
            v.setMouseEnabled(x=True, y=False)
            v.setAutoVisible(x=False, y=True)
            height_num = node['height_num']
            node_yMin = node['yMin']
            node_yMax = node['yMax']
            pw.ci.layout.setRowMinimumHeight(i, height_num)
            v.setLimits(yMin=node_yMin, yMax=node_yMax)
            h_i += height_num
            if i>0:
                v.setXLink(self.v_list[0])
            node_data_list = node['data_list']
            for one in node_data_list:
                one_type = one['type']
                one_data = one['data']
                if one_type == self.graph_type_candle:
                    candle = CandlestickItem(one_data)
                    v.addItem(candle)
                elif one_type == self.graph_type_curve:
                    curve = pg.PlotCurveItem(x=one_data['x'],y=one_data['y'],pen=(0,0,255))
                    v.addItem(curve)
                    pass
                elif one_type == self.graph_type_bar:
                    bar = VOLtickItem(one_data)
                    v.addItem(bar)
                    pass
                else:
                    pass
                pass

            vLine = pg.InfiniteLine(angle=90, movable=False)
            hLine = pg.InfiniteLine(angle=0, movable=False)
            label = pg.TextItem()
            v.addItem(vLine, ignoreBounds=True)
            v.addItem(hLine, ignoreBounds=True)
            v.addItem(label, ignoreBounds=True)

            v.scene().sigMouseMoved.connect(self.mouseMoved)

            self.v_list.append(v)
            self.vline_list.append(vLine)
            self.hline_list.append(hLine)
            self.label_list.append(label)
            pass
        pw.setFixedHeight(h_i+50)
        self.fill_pw_widget(pw)
        pass

    def fill_pw_widget(self,pw):
        # print(pw.width(),pw.height())
        # 清空控件
        while self.pw_layout.count():
            item = self.pw_layout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            pass
        sc_child_widget = self.scroll_area.takeWidget()
        if sc_child_widget is not None:
            sc_child_widget.deleteLater()
        # for item in self.pw_widgets_list:
        #     self.pw_layout.addWidget(item)
        self.pw_layout.addWidget(pw)
        one_sc_child_widget = QtWidgets.QWidget()
        one_sc_child_widget.setLayout(self.pw_layout)
        self.scroll_area.setWidget(one_sc_child_widget)
        pass

    def mouseMoved(self,evt):
        pos = evt
        for la in self.label_list:
            la.setHtml("")
            la.setPos(-1, -1)
        for i,v in enumerate(self.v_list):
            if v.sceneBoundingRect().contains(pos):
                mousePoint = v.mapSceneToView(pos)
                index = int(mousePoint.x())
                hline = self.hline_list[i]
                hline.setPos(mousePoint.y())
                for hi,hl in enumerate(self.hline_list):
                    if hi!=i:
                        hl.setPos(-1)
                    pass
                for vl in self.vline_list:
                    vl.setPos(mousePoint.x())
                if self.tip_show_yeah and self.show_map.get(str(index)):
                    node_one = self.show_map[str(index)]
                    node_str = "<span style='font-size:12pt;color:red'>"

                    n_i = 1
                    for k,v in node_one.items():
                        if n_i%7 == 0:
                            node_str += f"{k}:{v}<br/>"
                        else:
                            node_str += f"{k}:{v}&nbsp;"
                        n_i += 1
                        pass
                    node_str += "</span>"
                    tip_label = self.label_list[i]
                    tip_label.setHtml(node_str)
                    tip_label.setPos(mousePoint.x(),mousePoint.y())
                    pass
                else:
                    for la in self.label_list:
                        la.setHtml("")
                        la.setPos(-1,-1)
                    pass
                break
            pass
        pass

    pass

使用方法

if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    app = QtWidgets.QApplication(sys.argv)
    main_window = ExampleWidget()
    # main_window.show()
    # app.exec()

    day_df,week_df,month_df = temp_000()
    k_tip_map, three_df = temp_001(day_df.copy(),week_df.copy(),month_df.copy())
    one,two = temp_002(day_df.copy())
    three,four = temp_002(week_df.copy())
    five,six = temp_002(month_df.copy())
    base_k_data = {
        'show_map': k_tip_map,
        'data_list': [one, two, three, four, five, six]
    }
    main_window.set_data(base_k_data)
    main_window.show()
    app.exec()
    pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1151571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【思考】为什么要有随机分析,为什么要有频域变换

问&#xff1a;为什么要有随机分析&#xff0c;为什么要有频域变换&#xff1f; 答&#xff1a;因为原有的时域方法很难描述一些信号或噪声。 例如这样一个信号 如果要写出时域公式&#xff0c;简直是太复杂了&#xff0c;怎么描述它呢。一是从0时刻开始指数衰减。二是可以说…

基于SpringBoot的科研工作量管理系统

目录 前言 一、技术栈 二、系统功能介绍 管理员功能介绍 科研项目列表 项目论文信息管理 项目类型管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 四、系统测试 概要 系统测试的特点  系统功能测试 登录功能测试 添加项目类型功能测试 测试结果分…

微信一次性群发1000条消息:高效沟通的秘诀

在当今数字化时代&#xff0c;微信作为一款广受欢迎的社交应用程序&#xff0c;为人们提供了便捷的沟通方式。在微信中&#xff0c;一次性群发1000条消息似乎是一个不可能完成的任务&#xff0c;因为微信自带的群发功能是只能一次性最多群发200人的&#xff0c;那么有没有什么工…

uni-app打包之如何生成自由证书

我是使用Android Studio来直接生成。超级简单 第一步 打开 Android Studio 找到下面图片 第二步 选 Android App Bund 然后Next 第三步 选择创建新的 第四步 填写对应的 信息 密码最好都是一样的 第五步 点击ok 即可创建成功。 uniapp打包时候勾选文件 &#xff08;如果公…

C语言 指针进阶笔记

p和*p: 如图&#xff0c;p是指针&#xff0c;指针存放着地址&#xff0c;打印出来应该是数组的值 *p是指针里里面的元素 #include<stdio.h> int main() {int a1;int b2;int c3;int p[3]{a,b,c};printf("%d",*p); return 0; } 那么现在的打印结果应该为数组的…

线程是如何创建的

线程不是一个完全由内核实现的机制&#xff0c;它是由内核态和用户态合作完成的。pthread_create 不是一个系统调用&#xff0c;是 Glibc 库的一个函数&#xff0c;所以我们还要去 Glibc 里面去找线索。 首先处理的是线程的属性参数。例如前面写程序的时候&#xff0c;我们设置…

一些关于weex编译apk的环境配置记录,成功打包weex app

背景 使用weex编译安卓app。老是会遇到一些配置问题&#xff0c;导致编译apk异常。 最后重新下载Android studio&#xff0c;配置好环境&#xff0c;再使用官网的命令&#xff0c;就编译成功了&#xff0c;下面是记录。 编译成功的环境 Java版本&#xff1a;jdk1.8.0_241 And…

深度学习_2 数据操作

数据操作 机器学习包括的核心组件有&#xff1a; 可以用来学习的数据&#xff08;data&#xff09;&#xff1b;如何转换数据的模型&#xff08;model&#xff09;&#xff1b;一个目标函数&#xff08;objective function&#xff09;&#xff0c;用来量化模型的有效性&…

AB试验(七)利用Python模拟A/B试验

AB试验&#xff08;七&#xff09;利用Python模拟A/B试验 到现在&#xff0c;我相信大家理论已经掌握了&#xff0c;轮子也造好了。但有的人是不是总感觉还差点什么&#xff1f;没错&#xff0c;还缺了实战经验。对于AB实验平台完善的公司 &#xff0c;这个经验不难获得&#…

记录一段帮朋友写的代码,使用牛顿-拉夫逊方法解方程

要求 已知公式&#xff1a; t G A B F r B r 2 2 F A 2 B G A F ln ⁡ ( r − A ) C o n s t t\frac{GAB}{F}r\frac{Br^2}{2F}\frac{A^2BGA}{F}\ln (r-A)Const tFGAB​r2FBr2​FA2BGA​ln(r−A)Const 其中 t 的值为0-1000&#xff0c;每间隔25取一次值A2.12941E-10B0.…

源码!游戏源码!大量游戏源码!!!知识星球

分享 不在游戏公司有段时间了&#xff0c;但是还一直在游戏圈&#xff0c;多年的游戏经验也做了一些总结&#xff0c;还有一些私货源码没有做分享&#xff0c;所以也跟着玩一玩知识星球。 源码来自哪 1、来自网上搜集 各种开源网站&#xff0c;比如github ,gitee平常会注意搜…

Windows内存取证-中等难度 -上篇

涉及的工具&#xff1a; SysInfoTools-ost-viewer-pro volatility_2.6_lin64_standalone VT在线工具 使用到的镜像文件&#xff1a; target1-1dd8701f.vmss target2-6186fe9f.vmss POS-01-c4e8f786.vmss 题干&#xff1a; 一名员工报告说&#xff0c;他的机器在收到一封可…

【深度学习docker】roop-unleashed的docker镜像,deepfake AI换脸

快速启动roop-unleashed 要求有支持CUDA11.8的显卡Linux Docker。 使用docker启动roop-unleashed&#xff1a; docker run -d --gpus all -p 7860:7860 kevinchina/deeplearning:roop-unleashed1访问&#xff1a; 制作工程使用的一些脚本 基础镜像&#xff1a; FROM nvidi…

基于SpringBoot的在线笔记系统

技术介绍 &#x1f525;采用技术&#xff1a;SpringSpringMVCMyBatisJSPMaven &#x1f525;开发语言&#xff1a;Java &#x1f525;JDK版本&#xff1a;JDK1.8 &#x1f525;服务器&#xff1a;tomcat &#x1f525;数据库&#xff1a;mysql &#x1f525;数据库开发工具&…

时间序列预测大模型-TimeGPT

时间序列预测领域正在经历一个非常激动人心的时期。仅在过去的三年里&#xff0c;我们就看到了许多重要的贡献&#xff0c;例如N-BEATS、N-HiTS、PatchTST和TimesNet。 与此同时&#xff0c;大型语言模型 (LLM)最近在 ChatGPT 等应用程序中广受欢迎&#xff0c;因为它们无需进…

LoadRunner实现接口测试

接口测试的原理是通过测试程序模拟浏览器向服务器发送请求报文&#xff0c;服务器接收请求报文后对相应的报文做出处理然后再把应答报文发送给浏览器&#xff0c;浏览器接收应答报文这一个过程。 LoadRunner是一种性能测试工具&#xff0c;但是它也可以用来做接口测试。开发人…

kubernetes实验挑战二(troubleshoot pv pvc )

This 2-Node Kubernetes cluster is broken! Troubleshoot, fix the cluster issues and then deploy the objects according to the given architecture diagram to unlock our Image Gallery!! 1、 kubeconfig /root/.kube/config, User ‘kubernetes-admin’ Cluster: S…

基于乌鸦算法的无人机航迹规划-附代码

基于乌鸦算法的无人机航迹规划 文章目录 基于乌鸦算法的无人机航迹规划1.乌鸦搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用乌鸦算法来优化无人机航迹规划。 1.乌鸦搜索算法 …

昂首资本严肃且专业地探讨波浪理论第一波

很多投资者已经了解了波浪理论第一波&#xff0c;今天昂首资本和各位投资者再加深一下理解&#xff0c;让我们严肃且专业地探讨一下第一波。 以小时价格图表举例&#xff0c;第一波的起始点存在一个看涨反转棒。请注意&#xff0c;这个棒形结构对应了比尔威廉姆斯交易策略三智…

识别flink的反压源头

背景 flink中最常见的问题就是反压&#xff0c;这种情况下我们要正确的识别导致反压的真正的源头&#xff0c;本文就简单看下如何正确识别反压的源头 反压的源头 首先我们必须意识到现实中轻微的反压是没有必要去优化的&#xff0c;因为这种情况下是由于偶尔的流量峰值,Task…