Skip to content

Commit 47cb053

Browse files
committed
add support for auto precision
1 parent 233ed90 commit 47cb053

File tree

10 files changed

+183
-203
lines changed

10 files changed

+183
-203
lines changed

UI/configuration.ui

Lines changed: 140 additions & 180 deletions
Large diffs are not rendered by default.

algobot/algodict.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def get_interface_dictionary(parent, caller: int = None):
4848
'ticker': parent.configuration.simulationTickerLineEdit,
4949
'interval': parent.configuration.simulationIntervalComboBox,
5050
'lowerIntervalCheck': parent.configuration.lowerIntervalSimulationCheck,
51-
'precision': parent.configuration.simulationPrecisionSpinBox,
51+
'precision': parent.configuration.simulationPrecisionComboBox,
5252
}
5353
},
5454
LIVE: {
@@ -89,7 +89,7 @@ def get_interface_dictionary(parent, caller: int = None):
8989
'ticker': parent.configuration.tickerLineEdit,
9090
'interval': parent.configuration.intervalComboBox,
9191
'lowerIntervalCheck': parent.configuration.lowerIntervalCheck,
92-
'precision': parent.configuration.precisionSpinBox,
92+
'precision': parent.configuration.precisionComboBox,
9393
}
9494
},
9595
BACKTEST: {
@@ -104,7 +104,7 @@ def get_interface_dictionary(parent, caller: int = None):
104104
'configuration': {
105105
'mainTab': parent.configuration.backtestMainTab,
106106
'mainConfigurationTabWidget': parent.configuration.backtestConfigurationTabWidget,
107-
'precision': parent.configuration.backtestPrecisionSpinBox,
107+
'precision': parent.configuration.backtestPrecisionComboBox,
108108
'ticker': parent.configuration.backtestTickerLineEdit,
109109
'interval': parent.configuration.backtestIntervalComboBox,
110110
},

algobot/graph_helpers.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,10 @@ def setup_average_graph_plots(gui: QMainWindow, graph: PlotWidget, trader, color
172172
for option in trader.strategies['movingAverage'].get_params():
173173
initialAverage, finalAverage, initialName, finalName = option.get_option_info(trader)
174174
initialPlotDict = get_plot_dictionary(gui=gui, graph=graph, color=colors[colorCounter % len(colors)],
175-
y=initialAverage,
176-
name=initialName, timestamp=currentDateTimestamp)
175+
y=initialAverage, name=initialName, timestamp=currentDateTimestamp)
177176
secondaryPlotDict = get_plot_dictionary(gui=gui, graph=graph,
178177
color=colors[(colorCounter + 1) % len(colors)],
179-
y=finalAverage,
180-
name=finalName, timestamp=currentDateTimestamp)
178+
y=finalAverage, name=finalName, timestamp=currentDateTimestamp)
181179
colorCounter += 2
182180
append_plot_to_graph(gui, graph, [initialPlotDict, secondaryPlotDict])
183181

algobot/helpers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import logging
3+
import math
34
import os
45
import platform
56
import re
@@ -8,6 +9,7 @@
89
from datetime import datetime
910
from typing import Dict, List, Tuple, Union
1011

12+
from binance import Client
1113
from dateutil import parser
1214

1315
from algobot.enums import BACKTEST, LIVE, OPTIMIZER, SIMULATION
@@ -362,6 +364,14 @@ def load_from_csv(path: str, descending: bool = True) -> list:
362364
return data
363365

364366

367+
def parse_precision(precision: str, symbol: str) -> int:
368+
if precision == "Auto":
369+
symbol_info = Client().get_symbol_info(symbol)
370+
tickSize = float(symbol_info['filters'][0]['tickSize'])
371+
precision = abs(round(math.log(tickSize, 10)))
372+
return int(precision)
373+
374+
365375
def write_json_file(filePath: str = 'secret.json', **kwargs):
366376
"""
367377
Writes JSON file with **kwargs provided.

algobot/interface/config_utils/slot_utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ def load_strategy_slots(config_obj):
138138
tab.addTab(tabWidget, strategyName)
139139

140140

141+
def load_precision_combo_boxes(config_obj):
142+
combo_boxes = [config_obj.precisionComboBox, config_obj.simulationPrecisionComboBox,
143+
config_obj.backtestPrecisionComboBox, config_obj.optimizerPrecisionComboBox]
144+
precisions = ["Auto"] + [str(x) for x in range(2, 16)]
145+
[combo_box.addItems(precisions) for combo_box in combo_boxes]
146+
147+
141148
def load_interval_combo_boxes(config_obj):
142149
"""
143150
This function currently only handles combo boxes for backtester/optimizer interval logic. It'll update the
@@ -228,6 +235,7 @@ def load_slots(config_obj):
228235
c.graphPlotSpeedSpinBox.valueChanged.connect(c.update_graph_speed)
229236
c.enableHoverLine.stateChanged.connect(c.enable_disable_hover_line)
230237

238+
load_precision_combo_boxes(c)
231239
load_interval_combo_boxes(c) # Primarily used for backtester/optimizer interval changer logic.
232240
load_loss_slots(c) # These slots are based on the ordering.
233241
load_take_profit_slots(c)

algobot/interface/config_utils/user_config_utils.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def save_backtest_settings(config_obj):
108108
'ticker': config_obj.backtestTickerLineEdit.text(),
109109
'interval': config_obj.backtestIntervalComboBox.currentIndex(),
110110
'startingBalance': config_obj.backtestStartingBalanceSpinBox.value(),
111-
'precision': config_obj.backtestPrecisionSpinBox.value(),
111+
'precision': config_obj.backtestPrecisionComboBox.currentIndex(),
112112
'marginTrading': config_obj.backtestMarginTradingCheckBox.isChecked(),
113113
}
114114

@@ -125,7 +125,7 @@ def save_optimizer_settings(config_obj):
125125
'strategyIntervalStart': config_obj.optimizerStrategyIntervalCombobox.currentIndex(),
126126
'strategyIntervalEnd': config_obj.optimizerStrategyIntervalEndCombobox.currentIndex(),
127127
'startingBalance': config_obj.optimizerStartingBalanceSpinBox.value(),
128-
'precision': config_obj.optimizerPrecisionSpinBox.value(),
128+
'precision': config_obj.optimizerPrecisionComboBox.currentIndex(),
129129
'drawdownPercentage': config_obj.drawdownPercentageSpinBox.value(),
130130
'marginTrading': config_obj.optimizerMarginTradingCheckBox.isChecked()
131131
}
@@ -140,7 +140,7 @@ def save_live_settings(config_obj):
140140
'type': LIVE,
141141
'ticker': config_obj.tickerLineEdit.text(),
142142
'interval': config_obj.intervalComboBox.currentIndex(),
143-
'precision': config_obj.precisionSpinBox.value(),
143+
'precision': config_obj.precisionComboBox.currentIndex(),
144144
'usRegion': config_obj.usRegionRadio.isChecked(),
145145
'otherRegion': config_obj.otherRegionRadio.isChecked(),
146146
'isolatedMargin': config_obj.isolatedMarginAccountRadio.isChecked(),
@@ -159,7 +159,7 @@ def save_simulation_settings(config_obj):
159159
'ticker': config_obj.simulationTickerLineEdit.text(),
160160
'interval': config_obj.simulationIntervalComboBox.currentIndex(),
161161
'startingBalance': config_obj.simulationStartingBalanceSpinBox.value(),
162-
'precision': config_obj.simulationPrecisionSpinBox.value(),
162+
'precision': config_obj.simulationPrecisionComboBox.currentIndex(),
163163
'lowerInterval': config_obj.lowerIntervalSimulationCheck.isChecked(),
164164
}
165165

@@ -203,7 +203,7 @@ def load_live_settings(config_obj, config):
203203
"""
204204
config_obj.tickerLineEdit.setText(str(config['ticker']))
205205
config_obj.intervalComboBox.setCurrentIndex(config['interval'])
206-
config_obj.precisionSpinBox.setValue(config['precision'])
206+
config_obj.precisionComboBox.setCurrentIndex(config['precision'])
207207
config_obj.usRegionRadio.setChecked(config['usRegion'])
208208
config_obj.otherRegionRadio.setChecked(config['otherRegion'])
209209
config_obj.isolatedMarginAccountRadio.setChecked(config['isolatedMargin'])
@@ -220,7 +220,7 @@ def load_simulation_settings(config_obj, config):
220220
config_obj.simulationTickerLineEdit.setText(str(config['ticker']))
221221
config_obj.simulationIntervalComboBox.setCurrentIndex(config['interval'])
222222
config_obj.simulationStartingBalanceSpinBox.setValue(config['startingBalance'])
223-
config_obj.simulationPrecisionSpinBox.setValue(config['precision'])
223+
config_obj.simulationPrecisionComboBox.setCurrentIndex(config['precision'])
224224
config_obj.lowerIntervalSimulationCheck.setChecked(config['lowerInterval'])
225225

226226

@@ -233,7 +233,7 @@ def load_backtest_settings(config_obj, config):
233233
config_obj.backtestTickerLineEdit.setText(str(config['ticker']))
234234
config_obj.backtestIntervalComboBox.setCurrentIndex(config['interval'])
235235
config_obj.backtestStartingBalanceSpinBox.setValue(config['startingBalance'])
236-
config_obj.backtestPrecisionSpinBox.setValue(config['precision'])
236+
config_obj.backtestPrecisionComboBox.setCurrentIndex(config['precision'])
237237
config_obj.backtestMarginTradingCheckBox.setChecked(config['marginTrading'])
238238

239239

@@ -248,7 +248,7 @@ def load_optimizer_settings(config_obj, config):
248248
config_obj.optimizerStrategyIntervalCombobox.setCurrentIndex(config['strategyIntervalStart'])
249249
config_obj.optimizerStrategyIntervalEndCombobox.setCurrentIndex(config['strategyIntervalEnd'])
250250
config_obj.optimizerStartingBalanceSpinBox.setValue(config['startingBalance'])
251-
config_obj.optimizerPrecisionSpinBox.setValue(config['precision'])
251+
config_obj.optimizerPrecisionComboBox.setCurrentIndex(config['precision'])
252252
config_obj.drawdownPercentageSpinBox.setValue(config['drawdownPercentage'])
253253

254254

@@ -270,7 +270,7 @@ def copy_settings_to_simulation(config_obj):
270270
"""
271271
config_obj.simulationIntervalComboBox.setCurrentIndex(config_obj.intervalComboBox.currentIndex())
272272
config_obj.simulationTickerLineEdit.setText(config_obj.tickerLineEdit.text())
273-
config_obj.simulationPrecisionSpinBox.setValue(config_obj.precisionSpinBox.value())
273+
config_obj.simulationPrecisionComboBox.setCurrentIndex(config_obj.precisionComboBox.currentIndex())
274274

275275

276276
def copy_settings_to_backtest(config_obj):
@@ -280,7 +280,7 @@ def copy_settings_to_backtest(config_obj):
280280
"""
281281
config_obj.backtestIntervalComboBox.setCurrentIndex(config_obj.intervalComboBox.currentIndex())
282282
config_obj.backtestTickerLineEdit.setText(config_obj.tickerLineEdit.text())
283-
config_obj.backtestPrecisionSpinBox.setValue(config_obj.precisionSpinBox.value())
283+
config_obj.backtestPrecisionComboBox.setCurrentIndex(config_obj.precisionComboBox.currentIndex())
284284

285285

286286
def copy_strategy_settings(config_obj, fromCaller: int, toCaller: int, strategyName: str):

algobot/threads/backtestThread.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
55

66
from algobot.enums import BACKTEST
7+
from algobot.helpers import parse_precision
78
from algobot.interface.config_utils.calendar_utils import get_calendar_dates
89
from algobot.interface.config_utils.strategy_utils import get_strategies
910
from algobot.traders.backtester import Backtester
@@ -38,14 +39,15 @@ def get_configuration_details_to_setup_backtest(self) -> Dict[str, Any]:
3839
"""
3940
config = self.gui.configuration
4041
startDate, endDate = get_calendar_dates(config_obj=config)
42+
symbol = config.optimizer_backtest_dict[BACKTEST]['dataType']
4143

4244
return {
4345
'startingBalance': config.backtestStartingBalanceSpinBox.value(),
4446
'data': config.optimizer_backtest_dict[BACKTEST]['data'],
4547
'startDate': startDate,
4648
'endDate': endDate,
47-
'symbol': config.optimizer_backtest_dict[BACKTEST]['dataType'],
48-
'precision': config.backtestPrecisionSpinBox.value(),
49+
'symbol': symbol,
50+
'precision': parse_precision(config.backtestPrecisionComboBox.currentText(), symbol),
4951
'outputTrades': config.backtestOutputTradesCheckBox.isChecked(),
5052
'marginEnabled': config.backtestMarginTradingCheckBox.isChecked(),
5153
'strategies': get_strategies(config, BACKTEST),

algobot/threads/botThread.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def create_trader(self, caller):
111111
gui = self.gui
112112
configDict = gui.interfaceDictionary[caller]['configuration']
113113
symbol = configDict['ticker'].text()
114-
precision = configDict['precision'].value()
114+
precision = helpers.parse_precision(configDict['precision'].currentText(), symbol)
115115
prettyInterval = configDict['interval'].currentText()
116116
interval = helpers.convert_long_interval(prettyInterval)
117117

algobot/threads/optimizerThread.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
44

55
from algobot.enums import OPTIMIZER
6+
from algobot.helpers import parse_precision
67
from algobot.interface.config_utils.calendar_utils import get_calendar_dates
78
from algobot.traders.backtester import Backtester
89

@@ -32,14 +33,15 @@ def get_configuration_details(self) -> Dict[str, Any]:
3233
"""
3334
config = self.gui.configuration
3435
startDate, endDate = get_calendar_dates(config_obj=config, caller=OPTIMIZER)
36+
symbol = config.optimizer_backtest_dict[OPTIMIZER]['dataType']
3537

3638
return {
3739
'startingBalance': config.optimizerStartingBalanceSpinBox.value(),
3840
'data': config.optimizer_backtest_dict[OPTIMIZER]['data'],
3941
'startDate': startDate,
4042
'endDate': endDate,
41-
'symbol': config.optimizer_backtest_dict[OPTIMIZER]['dataType'],
42-
'precision': config.optimizerPrecisionSpinBox.value(),
43+
'symbol': symbol,
44+
'precision': parse_precision(config.optimizerPrecisionComboBox.currentText(), symbol),
4345
'marginEnabled': config.optimizerMarginTradingCheckBox.isChecked(),
4446
'strategies': [],
4547
'strategyInterval': config.optimizerStrategyIntervalCombobox.currentText(),

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.16
1+
1.17

0 commit comments

Comments
 (0)