From b5058d497930449292de904065ca7410353ca9db Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:30:04 -0500 Subject: [PATCH 01/13] made SMA calculation function public --- src/StockBench/indicators/sma/trigger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StockBench/indicators/sma/trigger.py b/src/StockBench/indicators/sma/trigger.py index 81c805a..ca7ff31 100644 --- a/src/StockBench/indicators/sma/trigger.py +++ b/src/StockBench/indicators/sma/trigger.py @@ -77,12 +77,12 @@ def __add_sma(self, length: int, data_manager: DataManager): price_data = data_manager.get_column_data(data_manager.CLOSE) - sma_values = SMATrigger.__calculate_sma(length, price_data) + sma_values = SMATrigger.calculate_sma(length, price_data) data_manager.add_column(column_title, sma_values) @staticmethod - def __calculate_sma(length: int, price_data: list) -> list: + def calculate_sma(length: int, price_data: list) -> list: """Calculates the SMA values for a list of price values.""" price_values = [] sma_values = [] From 52edaf9c2dd28c12b27e0492fecbd6053347ad80 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:31:14 -0500 Subject: [PATCH 02/13] used SMA indicator to calculate SMA in EMA trigger --- src/StockBench/indicators/ema/trigger.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/StockBench/indicators/ema/trigger.py b/src/StockBench/indicators/ema/trigger.py index bc696ad..55de6dd 100644 --- a/src/StockBench/indicators/ema/trigger.py +++ b/src/StockBench/indicators/ema/trigger.py @@ -3,6 +3,7 @@ from StockBench.indicator.trigger import Trigger from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager +from StockBench.indicators.sma.sma import SMATrigger log = logging.getLogger() @@ -85,7 +86,7 @@ def __calculate_ema(length: int, price_data: list) -> list: k = 2 / (length + 1) # get the initial ema value (uses sma of length days) - previous_ema = EMATrigger.__calculate_sma(length, price_data[0:length])[-1] + previous_ema = SMATrigger.calculate_sma(length, price_data[0:length])[-1] ema_values = [] for i in range(len(price_data)): @@ -96,19 +97,3 @@ def __calculate_ema(length: int, price_data: list) -> list: ema_values.append(ema_point) previous_ema = ema_point return ema_values - - @staticmethod - def __calculate_sma(length: int, price_data: list) -> list: - """Calculates the SMA values for a list of price values.""" - price_values = [] - sma_values = [] - for day in price_data: - if len(price_values) < length: - price_values.append(float(day)) - else: - price_values.pop(0) - sma_values.pop(0) - price_values.append(float(day)) - avg = round(statistics.mean(price_values), 3) - sma_values.append(avg) - return sma_values From 7bf9f29db9d7cbf20a3da1237d30cbe94ce46fd8 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:31:31 -0500 Subject: [PATCH 03/13] made EMA calculation function public --- src/StockBench/indicators/ema/trigger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StockBench/indicators/ema/trigger.py b/src/StockBench/indicators/ema/trigger.py index 55de6dd..af573f9 100644 --- a/src/StockBench/indicators/ema/trigger.py +++ b/src/StockBench/indicators/ema/trigger.py @@ -76,12 +76,12 @@ def __add_ema(self, length: int, data_manager: DataManager): price_data = data_manager.get_column_data(data_manager.CLOSE) - ema_values = EMATrigger.__calculate_ema(length, price_data) + ema_values = EMATrigger.calculate_ema(length, price_data) data_manager.add_column(column_title, ema_values) @staticmethod - def __calculate_ema(length: int, price_data: list) -> list: + def calculate_ema(length: int, price_data: list) -> list: """Calculates the EMA values for a list of price values""" k = 2 / (length + 1) From 92710277dd8ec59848812fe78f8a16f943c6204e Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:34:10 -0500 Subject: [PATCH 04/13] used EMA indicator calculation in MACD trigger --- src/StockBench/indicators/macd/trigger.py | 41 ++--------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/src/StockBench/indicators/macd/trigger.py b/src/StockBench/indicators/macd/trigger.py index b0f3b44..d2f6e8c 100644 --- a/src/StockBench/indicators/macd/trigger.py +++ b/src/StockBench/indicators/macd/trigger.py @@ -1,10 +1,10 @@ import logging import statistics -from StockBench.constants import * from StockBench.indicator.trigger import Trigger from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager from StockBench.position.position import Position +from StockBench.indicators.ema.ema import EMATrigger log = logging.getLogger() @@ -71,9 +71,9 @@ def check_trigger(self, rule_key, rule_value, data_manager, position, current_da def __calculate_macd(self, price_data: list) -> list: """Calculate MACD values for a list of price values""" - large_ema_length_values = MACDTrigger.__calculate_ema(self.LARGE_EMA_LENGTH, price_data) + large_ema_length_values = EMATrigger.calculate_ema(self.LARGE_EMA_LENGTH, price_data) - small_ema_length_values = MACDTrigger.__calculate_ema(self.SMALL_EMA_LENGTH, price_data) + small_ema_length_values = EMATrigger.calculate_ema(self.SMALL_EMA_LENGTH, price_data) if len(large_ema_length_values) != len(small_ema_length_values): raise StrategyIndicatorError(f'{self.indicator_symbol} value lists for {self.indicator_symbol} must be the ' @@ -89,38 +89,3 @@ def __calculate_macd(self, price_data: list) -> list: macd_values.append(round(small_ema_length_values[i] - large_ema_length_values[i], 3)) return macd_values - - @staticmethod - def __calculate_ema(length: int, price_data: list) -> list: - """Calculates the EMA values for a list of price values.""" - k = 2 / (length + 1) - - previous_ema = MACDTrigger.__calculate_sma(length, price_data[0:length])[-1] - - ema_values = [] - for i in range(len(price_data)): - if i < length: - ema_values.append(None) - else: - ema = round((k * (float(price_data[i]) - previous_ema)) + previous_ema, 3) - ema_values.append(ema) - previous_ema = ema - return ema_values - - @staticmethod - def __calculate_sma(length: int, price_data: list) -> list: - """Calculates the SMA values for a list of price values.""" - price_values = [] - sma_values = [] - all_sma_values = [] - for element in price_data: - if len(price_values) < length: - price_values.append(float(element)) - else: - price_values.pop(0) - sma_values.pop(0) - price_values.append(float(element)) - avg = round(statistics.mean(price_values), 3) - sma_values.append(avg) - all_sma_values.append(avg) - return all_sma_values From 8f0232cc77e167a27694fdeb9c3ce0dcba700aed Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:34:29 -0500 Subject: [PATCH 05/13] made MACD calculation function public --- src/StockBench/indicators/macd/trigger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StockBench/indicators/macd/trigger.py b/src/StockBench/indicators/macd/trigger.py index d2f6e8c..2b58121 100644 --- a/src/StockBench/indicators/macd/trigger.py +++ b/src/StockBench/indicators/macd/trigger.py @@ -43,7 +43,7 @@ def add_to_data(self, rule_key, rule_value, side, data_manager): price_data = data_manager.get_column_data(data_manager.CLOSE) - data_manager.add_column(self.indicator_symbol, self.__calculate_macd(price_data)) + data_manager.add_column(self.indicator_symbol, self.calculate_macd(price_data)) def check_trigger(self, rule_key, rule_value, data_manager, position, current_day_index) -> bool: """Trigger logic for EMA. @@ -69,7 +69,7 @@ def check_trigger(self, rule_key, rule_value, data_manager, position, current_da return Trigger.basic_trigger_check(indicator_value, operator, trigger_value) - def __calculate_macd(self, price_data: list) -> list: + def calculate_macd(self, price_data: list) -> list: """Calculate MACD values for a list of price values""" large_ema_length_values = EMATrigger.calculate_ema(self.LARGE_EMA_LENGTH, price_data) From 45da8e3a5225c997fd4b3d9072c7ab0783f9577d Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:34:57 -0500 Subject: [PATCH 06/13] removed unused import --- src/StockBench/indicators/macd/trigger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/StockBench/indicators/macd/trigger.py b/src/StockBench/indicators/macd/trigger.py index 2b58121..12ec175 100644 --- a/src/StockBench/indicators/macd/trigger.py +++ b/src/StockBench/indicators/macd/trigger.py @@ -1,5 +1,4 @@ import logging -import statistics from StockBench.indicator.trigger import Trigger from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager From 9b0d7031b4fbec97ff6187d44576b1751f65ad03 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:35:42 -0500 Subject: [PATCH 07/13] removed unused import --- src/StockBench/indicators/ema/trigger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/StockBench/indicators/ema/trigger.py b/src/StockBench/indicators/ema/trigger.py index af573f9..2fee3f8 100644 --- a/src/StockBench/indicators/ema/trigger.py +++ b/src/StockBench/indicators/ema/trigger.py @@ -1,5 +1,4 @@ import logging -import statistics from StockBench.indicator.trigger import Trigger from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager From b07dfa7f2d64e223f65293d5e41b51950ebbdaaa Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:35:59 -0500 Subject: [PATCH 08/13] removed unused import --- src/StockBench/indicators/sma/trigger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/StockBench/indicators/sma/trigger.py b/src/StockBench/indicators/sma/trigger.py index ca7ff31..b0544cd 100644 --- a/src/StockBench/indicators/sma/trigger.py +++ b/src/StockBench/indicators/sma/trigger.py @@ -1,6 +1,5 @@ import logging import statistics -from StockBench.constants import * from StockBench.indicator.trigger import Trigger from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager From 4c33ad0ea9bd16dfae37bd1a8385db013c6743c7 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:36:39 -0500 Subject: [PATCH 09/13] made RSI calculation function public --- src/StockBench/indicators/rsi/trigger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StockBench/indicators/rsi/trigger.py b/src/StockBench/indicators/rsi/trigger.py index b796b4e..51e9100 100644 --- a/src/StockBench/indicators/rsi/trigger.py +++ b/src/StockBench/indicators/rsi/trigger.py @@ -82,12 +82,12 @@ def __add_rsi_column(self, length: int, data_manager: DataManager): price_data = data_manager.get_column_data(data_manager.CLOSE) - rsi_values = RSITrigger.__calculate_rsi(length, price_data) + rsi_values = RSITrigger.calculate_rsi(length, price_data) data_manager.add_column(self.indicator_symbol, rsi_values) @staticmethod - def __calculate_rsi(length: int, price_data: list) -> list: + def calculate_rsi(length: int, price_data: list) -> list: """Calculate the RSI values for a list of price values.""" first_day_value = 0 gain = [] From 9491c17e33dcaba826e48d574bb84c3b9abf5030 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sat, 21 Dec 2024 23:37:23 -0500 Subject: [PATCH 10/13] made stochastic calculation function public --- src/StockBench/indicators/stochastic/trigger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StockBench/indicators/stochastic/trigger.py b/src/StockBench/indicators/stochastic/trigger.py index d9c39cb..ef70d11 100644 --- a/src/StockBench/indicators/stochastic/trigger.py +++ b/src/StockBench/indicators/stochastic/trigger.py @@ -85,12 +85,12 @@ def __add_stochastic_column(self, length: int, data_manager: DataManager): low_data = data_manager.get_column_data(data_manager.LOW) close_data = data_manager.get_column_data(data_manager.CLOSE) - stochastic_values = StochasticTrigger.__stochastic_oscillator(length, high_data, low_data, close_data) + stochastic_values = StochasticTrigger.stochastic_oscillator(length, high_data, low_data, close_data) data_manager.add_column(self.indicator_symbol, stochastic_values) @staticmethod - def __stochastic_oscillator(length: int, high_data: list, low_data: list, close_data: list) -> list: + def stochastic_oscillator(length: int, high_data: list, low_data: list, close_data: list) -> list: """Calculate the stochastic values for a list of price values.""" past_length_days_high = [] past_length_days_low = [] From 99e66b39d2008556e0667839720577a0cd622303 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sun, 22 Dec 2024 12:42:44 -0500 Subject: [PATCH 11/13] removed unused import --- src/StockBench/indicators/stochastic/trigger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/StockBench/indicators/stochastic/trigger.py b/src/StockBench/indicators/stochastic/trigger.py index ef70d11..564caa9 100644 --- a/src/StockBench/indicators/stochastic/trigger.py +++ b/src/StockBench/indicators/stochastic/trigger.py @@ -1,7 +1,6 @@ import logging from StockBench.constants import * from StockBench.indicator.trigger import Trigger -from StockBench.indicator.exceptions import StrategyIndicatorError from StockBench.simulation_data.data_manager import DataManager from StockBench.position.position import Position From aa45da5a8ff89e913b68a9549d74194b7d4db09c Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sun, 22 Dec 2024 12:44:49 -0500 Subject: [PATCH 12/13] pep8 fix --- src/StockBench/gui/studio/strategy_studio.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/StockBench/gui/studio/strategy_studio.py b/src/StockBench/gui/studio/strategy_studio.py index 415b3e3..aa075bb 100644 --- a/src/StockBench/gui/studio/strategy_studio.py +++ b/src/StockBench/gui/studio/strategy_studio.py @@ -55,10 +55,10 @@ def on_save_btn_clicked(self): self.on_save_as_btn_clicked() def on_save_as_btn_clicked(self): - fileName, _ = QFileDialog.getSaveFileName(self, "QFileDialog.getSaveFileName()", "", "JSON (*.json)") - if fileName is not None and fileName != '': + file_name, _ = QFileDialog.getSaveFileName(self, "QFileDialog.getSaveFileName()", "", "JSON (*.json)") + if file_name is not None and file_name != '': # only save the file if the user picked a location - self.__save_json_file(fileName) + self.__save_json_file(file_name) def __set_geometry(self, config_pos, config_width): # place the strategy studio to the right of the config window From 6d503e34c98034f6f13097e78736c4ec80ad0d00 Mon Sep 17 00:00:00 2001 From: jocon15 Date: Sun, 22 Dec 2024 12:46:13 -0500 Subject: [PATCH 13/13] removed verbose docstring for typed signature --- .../singular/singular_charting_engine.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/StockBench/charting/singular/singular_charting_engine.py b/src/StockBench/charting/singular/singular_charting_engine.py index e097e5e..a4244b7 100644 --- a/src/StockBench/charting/singular/singular_charting_engine.py +++ b/src/StockBench/charting/singular/singular_charting_engine.py @@ -29,17 +29,7 @@ class SingularChartingEngine(ChartingEngine): def build_indicator_chart(df: DataFrame, symbol: str, available_indicators: List[IndicatorInterface], show_volume: bool, save_option=ChartingEngine.TEMP_SAVE) -> str: - """Multi-plot chart for singular simulation indicators. - - Args: - df: The full DataFrame post-simulation. - symbol: The symbol the simulation was run on. - available_indicators: The list of indicators. - save_option: Save the chart. - - Return: - (str): The filepath of the chart - """ + """Multi-plot chart for singular simulation indicators.""" subplot_objects, subplot_types = SingularChartingEngine.__get_subplot_objects_and_types(df, available_indicators) @@ -56,9 +46,9 @@ def build_indicator_chart(df: DataFrame, symbol: str, available_indicators: List def build_account_value_bar_chart(df: DataFrame, symbol: str, save_option=ChartingEngine.TEMP_SAVE) -> str: """Builds a chart for duration of positions. - return: - str: The filepath of the built chart. - """ + return: + str: The filepath of the built chart. + """ rows = 1 cols = 1