之前尝试使用mplfinance库做了K线图的呈现。感觉不是很理想,又找到了这个pyQtgraph库,网络上已经有一些人做了K线图的呈现,但是并不满意。主要是对于经常看盘的人来说,图形呈现的特征很重要,这就不得不说一下普通坐标系和对数坐标系的影响了!
大多数现有的看盘软件呢,都有坐标设置,右键Y轴坐标尺的位置,就可以选择了。通常有普通坐标和对数坐标之分,我一直使用对数坐标,这个很关键。在对数坐标下,其实股票或者期货的K线图,长期的趋势才是正确的,如果用普通坐标,那么其实会影响到我们的大脑发现价格走势运动中的规律。关键问题在什么地方呢?
关键问题在对数坐标下图形,没有被扭曲,看盘的人都明白,人脑是这个世界上最强的学习系统和分析系统,尤其是图形分析方面至今任何计算机所不能及。而普通坐标系的情况下,看盘软件直接用价格数据去画K线图,会导致什么呢?同样是涨10%的幅度,普通坐标系中,同一副图里,价格低的区间里和价格高的区间里,K线的长度是不同的。这就违背了我们看盘的基本原则,看盘的核心目的是从价格走势的图中发现规律,而K线的长短,对我们视觉的直观直觉就是涨落的幅度,普通坐标系会导致低价区涨落的幅度看上去小,而高价区的涨落幅度看上去大!但是对数坐标则不同,对数坐标,将价格取e为底的对数,然后再绘图,它确保了整个图形上,涨跌幅度一致的K线,其长度是一致的。同样涨跌10%,在低价区的K线大小和高价区的K线大小一致,这样不会给我们的大脑传递错误信号,更有利于我们的大脑来分析图形中可能蕴含的规律。
废话不多说。先上代码!这组代码着实折腾了好长时间!Candlestick也就是俗称的日本蜡烛图,是pyQtgraph里的自定义图形呈现实例。不清楚根本的原因,只是发现如果使用setLogMode设置y轴为log对数坐标系,对自定义图形不起作用。这个后面再研究吧。依据官方示例,修改了一个对比效果,大家可以看看差别。
import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import numpy
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):
self.picture = QtGui.QPicture()
p = QtGui.QPainter(self.picture)
p.setPen(pg.mkPen('w'))
w = (self.data[1][0] - self.data[0][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):
return QtCore.QRectF(self.picture.boundingRect())
data = [ ## 数据对应关系 (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16),
(7., 1.0, 1.3, 0.5, 1.5),#这里把官方示例的数据缩小10倍,为的是能明显开出K线的差别
(8., 1.3, 1.7, 0.9, 2.0),
(9., 1.7, 1.4, 1.1, 2.3),
(10., 1.4, 1.5, 0.5, 1.9),
(11., 1.5, 0.9, 0.8, 2.2),
(12., 0.9, 1.5, 0.8, 1.6),
]
item = CandlestickItem(data) #原始数据,对应(0,0)幅图
npdata=numpy.array(data)
logYdata=numpy.log(npdata[:,1:])
logYdata=numpy.insert(logYdata,0,values=npdata[:,0],axis=1)
logYdata=list(map(tuple,logYdata))
item2 =CandlestickItem(logYdata) #把原始数据里Y轴相关的数据,全部预先用log对数化处理一下,对应(0,1)
item3= CandlestickItem(data) #原始数据,对应第三幅图(1,0)
item4 =CandlestickItem(logYdata) #验证一下,是不是setLogMode在自定义组件的时候,得自己去实现(1,1)
w=pg.GraphicsWindow()
w.setWindowTitle(‘pyqtgraph example: customGraphicsItem’)
plt = w.addPlot(0,0, title=“X轴/Y轴普通坐标系”)
plt.addItem(item)
plt.showGrid(True, True)
plt2 = w.addPlot(0,1, title=“Y轴数据Log对数化处理”)
plt2.addItem(item2)
plt2.showGrid(True, True)
plt3 = w.addPlot(1,0, title=“Y轴设置为对数坐标模式”)
plt3.addItem(item3)
plt3.showGrid(True, True)
plt3.setLogMode(False, True)
plt4 = w.addPlot(1,1, title=“数据和坐标系都是对数模式”)
plt4.addItem(item4)
plt4.showGrid(True, True)
plt4.setLogMode(False, True)
if name == ‘main’:
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, ‘PYQT_VERSION’):
QtGui.QApplication.instance().exec_()
看看效果吧!
先说明一下,也许看文章的朋友不太懂布局管理器,这里面4幅图,使用了布局管理器来布局,当前用的是默认的gridlayout,网格布局管理器。用(行号,列号)来描述图形组件的位置,在头脑中把整个界面想成n行,n列的几大块儿,我这里是2行2列一共4大块,行和列的编号都是从0开始,所以分别就是(0,0)到(1,1)了。如下图:
很明显可以看出来,由于K线图形是自定义的图形,所以单单设置setLogMode是没用的,图形不会发生变化。所以我估计还是需要再看看官方文档,自定义的图形组件里,估计要实现相关的logMode的方法,把数据对数化处理了才行。就像(0,1)和(1,1)。看到对数化后的效果了么?价格涨了10倍以后,和价格涨10倍以前,涨跌幅度相同的情况下,K线的大小是一样的!这点很重要。对看盘做分析,寻找规律的人来说至关重要!!
原文链接:https://blog.csdn.net/supperman_009/article/details/107450953?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-4.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-4.nonecase&request_id=5f209da8f769fa6e5f5d4593