Skip to content

Commit 30e52fa

Browse files
committed
Add RSI Period
1 parent cd168db commit 30e52fa

File tree

5 files changed

+199
-23
lines changed

5 files changed

+199
-23
lines changed

finplotWindow.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,19 @@ def drawCandles(self):
6666
#self.createControlPanel(self.ax0.ax_widget)
6767
pass
6868

69-
def drawExternalsIndicators(self):
70-
71-
#if self.IndRsiActivated:
72-
self.rsi_indicator = rsi.Rsi(self.data)
69+
def drawRsi(self, period):
70+
self.rsi_indicator = rsi.Rsi(self.data, period)
7371
self.rsi_indicator.draw(self.ax_rsi)
72+
pass
7473

75-
#if self.IndStochasticActivated:
76-
self.stochastic_indicator = stochastic.Stochastic(self.data)
74+
def drawStochastic(self, period_k, period_d):
75+
self.stochastic_indicator = stochastic.Stochastic(self.data, period_k, period_d)
7776
self.stochastic_indicator.draw(self.ax_stochastic)
77+
pass
7878

79-
#if self.IndStochasticRsiActivated:
79+
def drawStochasticRsi(self, period, period_k, period_d, period_):
8080
self.stochasticRsi_indicator = stochasticRsi.StochasticRsi(self.data)
8181
self.stochasticRsi_indicator.draw(self.ax_stochasticRsi)
82-
8382
pass
8483

8584
#########
@@ -322,10 +321,6 @@ def refreshChart(self):
322321
def setChartData(self, data):
323322
self.data = data
324323

325-
# Calculate indicators only one time when setting chart data
326-
self.drawExternalsIndicators()
327-
pass
328-
329324
def resetChart(self):
330325

331326
# Remove all previous orders arrows and informations

indicatorParametersUI.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from PyQt5 import QtCore, QtWidgets, uic
2+
3+
import os
4+
5+
class IndicatorParametersUI(QtWidgets.QDialog):
6+
7+
def __init__(self, parent = None):
8+
super(IndicatorParametersUI, self).__init__()
9+
10+
self.setParent(parent)
11+
12+
# It does not finish by a "/"
13+
self.current_dir_path = os.path.dirname(os.path.realpath(__file__))
14+
15+
uic.loadUi( self.current_dir_path + "/ui/indicatorParameters.ui", self)
16+
17+
self.title = self.findChild(QtWidgets.QLabel, "title")
18+
self.parameterLayout = self.findChild(QtWidgets.QFormLayout, "parameterLayout")
19+
20+
# Move at the center of the window
21+
x = int(parent.sizeHint().width() / 2 - self.sizeHint().width())
22+
y = int(parent.sizeHint().height() / 2 - self.sizeHint().height())
23+
24+
self.move( x, y )
25+
26+
self.layout().setSizeConstraint( QtWidgets.QLayout.SetFixedSize )
27+
28+
pass
29+
30+
def setTitle(self, title):
31+
self.title = title
32+
pass
33+
34+
def addParameter(self, parameterName, defaultValue):
35+
lineEdit = QtWidgets.QLineEdit(parameterName, self)
36+
lineEdit.setObjectName(parameterName)
37+
lineEdit.setText(str(defaultValue))
38+
39+
self.parameterLayout.addRow(parameterName, lineEdit)
40+
41+
pass
42+
43+
def getValue(self, parameterName):
44+
lineEdit = self.findChild(QtWidgets.QLineEdit, parameterName)
45+
if lineEdit is not None:
46+
try:
47+
return int(lineEdit.text())
48+
except:
49+
try:
50+
return float(lineEdit.text())
51+
except:
52+
try:
53+
return lineEdit.text()
54+
except:
55+
return None
56+
else:
57+
return None

indicators/rsi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, dataFrames, rsi_periods=14):
1313
pass
1414

1515
def draw(self, ax, rsi_color = "magenta"):
16+
ax.reset()
1617
self.rsi_plot = fplt.plot(self.rsi_df, ax = ax, color=rsi_color, width=1 )
1718
pass
1819

ui/indicatorParameters.ui

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>Dialog</class>
4+
<widget class="QDialog" name="Dialog">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>400</width>
10+
<height>300</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Dialog</string>
15+
</property>
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="0" column="0">
18+
<widget class="QLabel" name="title">
19+
<property name="sizePolicy">
20+
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
21+
<horstretch>0</horstretch>
22+
<verstretch>0</verstretch>
23+
</sizepolicy>
24+
</property>
25+
<property name="minimumSize">
26+
<size>
27+
<width>0</width>
28+
<height>40</height>
29+
</size>
30+
</property>
31+
<property name="text">
32+
<string>Indicator</string>
33+
</property>
34+
<property name="alignment">
35+
<set>Qt::AlignCenter</set>
36+
</property>
37+
</widget>
38+
</item>
39+
<item row="1" column="0">
40+
<layout class="QFormLayout" name="parameterLayout"/>
41+
</item>
42+
<item row="2" column="0">
43+
<widget class="QDialogButtonBox" name="buttonBox">
44+
<property name="orientation">
45+
<enum>Qt::Horizontal</enum>
46+
</property>
47+
<property name="standardButtons">
48+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
49+
</property>
50+
</widget>
51+
</item>
52+
</layout>
53+
</widget>
54+
<resources/>
55+
<connections>
56+
<connection>
57+
<sender>buttonBox</sender>
58+
<signal>accepted()</signal>
59+
<receiver>Dialog</receiver>
60+
<slot>accept()</slot>
61+
<hints>
62+
<hint type="sourcelabel">
63+
<x>248</x>
64+
<y>254</y>
65+
</hint>
66+
<hint type="destinationlabel">
67+
<x>157</x>
68+
<y>274</y>
69+
</hint>
70+
</hints>
71+
</connection>
72+
<connection>
73+
<sender>buttonBox</sender>
74+
<signal>rejected()</signal>
75+
<receiver>Dialog</receiver>
76+
<slot>reject()</slot>
77+
<hints>
78+
<hint type="sourcelabel">
79+
<x>316</x>
80+
<y>260</y>
81+
</hint>
82+
<hint type="destinationlabel">
83+
<x>286</x>
84+
<y>274</y>
85+
</hint>
86+
</hints>
87+
</connection>
88+
</connections>
89+
</ui>

userInterface.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@
3131
import finplot as fplt
3232

3333
import backtrader as bt
34+
35+
# Ui made with Qt Designer
3436
import strategyTesterUI
3537
import strategyResultsUI
38+
import indicatorParametersUI
39+
40+
# Import Chart lib
3641
import finplotWindow
3742

43+
3844
import datetime
3945

4046
import qdarkstyle
@@ -65,8 +71,6 @@ def __init__(self,controller):
6571
# Set width/height of QSplitter
6672
self.app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
6773

68-
69-
7074
pass
7175

7276
#########
@@ -489,38 +493,46 @@ def createControlPanel(self):
489493
self.ResetPB.toggled.connect(self.resetChart)
490494
layout.addWidget(self.ResetPB)
491495

496+
# Spacer
497+
spacer = QtWidgets.QSpacerItem(50,20,QtWidgets.QSizePolicy.Minimum)
498+
layout.addSpacerItem(spacer)
499+
492500
# RSI
493501
self.RsiPB = QtWidgets.QPushButton(self.panel)
494502
self.RsiPB.setText("RSI")
495503
self.RsiPB.setCheckable(True)
496504
self.RsiPB.setMaximumWidth(100)
497-
self.RsiPB.toggled.connect(self.addRsi)
505+
self.RsiPB.toggled.connect(self.toogleRsi)
498506
layout.addWidget(self.RsiPB)
499507

500508
# Stochastic
501509
self.StochasticPB = QtWidgets.QPushButton(self.panel)
502510
self.StochasticPB.setText("Stochastic")
503511
self.StochasticPB.setCheckable(True)
504512
self.StochasticPB.setMaximumWidth(100)
505-
self.StochasticPB.toggled.connect(self.addStochastic)
513+
self.StochasticPB.toggled.connect(self.toogleStochastic)
506514
layout.addWidget(self.StochasticPB)
507515

508516
# Stochastic RSI
509517
self.StochasticRsiPB = QtWidgets.QPushButton(self.panel)
510518
self.StochasticRsiPB.setText("Stochastic RSI")
511519
self.StochasticRsiPB.setCheckable(True)
512520
self.StochasticRsiPB.setMaximumWidth(100)
513-
self.StochasticRsiPB.toggled.connect(self.addStochasticRsi)
521+
self.StochasticRsiPB.toggled.connect(self.toogleStochasticRsi)
514522
layout.addWidget(self.StochasticRsiPB)
515523

516524
# Ichimoku
517525
self.IchimokuPB = QtWidgets.QPushButton(self.panel)
518526
self.IchimokuPB.setText("Ichimoku")
519527
self.IchimokuPB.setCheckable(True)
520528
self.IchimokuPB.setMaximumWidth(100)
521-
self.IchimokuPB.toggled.connect(self.addIchimoku)
529+
self.IchimokuPB.toggled.connect(self.toogleIchimoku)
522530
layout.addWidget(self.IchimokuPB)
523531

532+
# Spacer
533+
spacer = QtWidgets.QSpacerItem(50,20,QtWidgets.QSizePolicy.Minimum)
534+
layout.addSpacerItem(spacer)
535+
524536
# Dark mode
525537
self.darkmodeCB = QtWidgets.QCheckBox(self.panel)
526538
self.darkmodeCB.setText('Dark mode')
@@ -557,20 +569,42 @@ def resetChart(self):
557569
pass
558570

559571
# indicators in external windows
560-
def addRsi(self):
561-
self.dock_rsi.show() if self.RsiPB.isChecked() else self.dock_rsi.hide()
572+
def toogleRsi(self):
573+
574+
if self.RsiPB.isChecked():
575+
# Show indicator parameter dialog
576+
paramDialog = indicatorParametersUI.IndicatorParametersUI(self.dock_chart)
577+
paramDialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint)
578+
paramDialog.setTitle("RSI Indicator parameters")
579+
paramDialog.addParameter("RSI Period", 14)
580+
#paramDialog.setStyleSheet("QDialog{ border: 1px solid green; }")
581+
paramDialog.adjustSize()
582+
583+
if (paramDialog.exec() == QtWidgets.QDialog.Accepted ):
584+
period = paramDialog.getValue("RSI Period")
585+
586+
self.fpltWindow.drawRsi( period )
587+
self.dock_rsi.show()
588+
else:
589+
# Cancel
590+
self.RsiPB.setChecked(False)
591+
self.dock_rsi.hide()
592+
593+
else:
594+
self.dock_rsi.hide()
595+
562596
pass
563597

564-
def addStochastic(self):
598+
def toogleStochastic(self):
565599
self.dock_stochastic.show() if self.StochasticPB.isChecked() else self.dock_stochastic.hide()
566600
pass
567601

568-
def addStochasticRsi(self):
602+
def toogleStochasticRsi(self):
569603
self.dock_stochasticRsi.show() if self.StochasticRsiPB.isChecked() else self.dock_stochasticRsi.hide()
570604
pass
571605

572606
# On chart indicators
573-
def addIchimoku(self):
607+
def toogleIchimoku(self):
574608
self.fpltWindow.setIndicator("Ichimoku", self.IchimokuPB.isChecked() )
575609
pass
576610

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy