-
|
Hi, I want to add the functionality to plot positions in my program like the image shows below. Currently I draw two independent rects using the add_rect function. The goal is to have it be all in one rect object, being able to adjust the take profit line and stop loss independently. Something similar as to tradingview's (image 2), but without the textboxes. I am thinking of two approaches,
Thanks in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
|
They are very similar, although the pyqtgraph one might contain more features. |
Beta Was this translation helpful? Give feedback.
-
|
I figured out a solution. Instead of creating two rectangles/ROIs, I instead extended the ROI class from pyqtgraph. It takes a given ratio, and depending on what type of position it is, it paints the tp and sl accordingly. class FinPosition(pg.ROI):
def __init__(self, ax, brush_tp, position_type, brush_sl, ratio=.5, *args, **kwargs):
self.ax = ax
self.brush_tp = brush_tp
self.brush_sl = brush_sl
self.position_type = position_type
if position_type == "long":
ratio=1-ratio
self.ratio = ratio
super().__init__(*args, **kwargs)
center = [0.5, ratio]
dy = -self.size()[1]*self.ratio
self.translate(0, dy, False)
if self.resizable:
self.addScaleHandle([1, 0.5], [0, 0.5])
self.addScaleHandle([0, 1], [0, center[1]])
self.addScaleHandle([0, 0], [0, center[1]])
def paint(self, p, *args):
r = QtCore.QRectF(0, 0, self.state['size'][0], self.state['size'][1]).normalized()
if self.position_type == "long":
first_brush = self.brush_sl
second_brush = self.brush_tp
elif self.position_type == "short":
first_brush = self.brush_tp
second_brush = self.brush_sl
else:
raise Exception(f"{self.position_type}: is not a valid position type. Must be 'long' or 'short'")
p.setPen(self.currentPen)
p.setBrush(first_brush)
p.translate(r.left(), r.top())
p.scale(r.width(), r.height())
p.scale(1, self.ratio)
p.drawRect(0, 0, 1, 1)
p.drawLine(0,1,1,1)
p.setBrush(second_brush)
p.translate(0, 1)
p.scale(1,(1-self.ratio)/self.ratio)
p.drawRect(0, 0, 1, 1)
def addScaleHandle(self, *args, **kwargs):
if self.resizable:
self.handleSize = 15
self.handlePen = pg.mkPen("blue")
super().addScaleHandle(*args, **kwargs)I also created a function to add positions, similary to the add_rect function. def add_position(p0, p1, position_type, ratio=.5, interactive=False, ax=None):
ax = fplt._create_plot(ax=ax, maximize=False)
x_pts = fplt._pdtime2index(ax, pd.Series([p0[0], p1[0]]))
ix = ax.vb.yscale.invxform
y0,y1 = sorted([p0[1], p1[1]])
pos = (x_pts[0], ix(y0))
size = (x_pts[1]-pos[0], ix(y1)-ix(y0))
tp_color = fplt.candle_bull_color+"80"
sl_color = fplt.candle_bear_color+"80"
brush_tp = pg.mkBrush(tp_color)
brush_sl = pg.mkBrush(sl_color)
rect = FinPosition(ax=ax, ratio=ratio, position_type=position_type, brush_tp=brush_tp, brush_sl=brush_sl, pos=pos, size=size, movable=interactive, resizable=interactive, rotatable=False)
rect.setZValue(0)
if interactive:
ax.vb.rois.append(rect)
rect.ax = ax
ax.addItem(rect)
return rect |
Beta Was this translation helpful? Give feedback.



I figured out a solution. Instead of creating two rectangles/ROIs, I instead extended the ROI class from pyqtgraph. It takes a given ratio, and depending on what type of position it is, it paints the tp and sl accordingly.