diff --git a/dexbot/__init__.py b/dexbot/__init__.py
index 850505a32..e6d0c4f45 100644
--- a/dexbot/__init__.py
+++ b/dexbot/__init__.py
@@ -1 +1 @@
-__version__ = '0.1.10'
+__version__ = '0.1.12'
diff --git a/dexbot/controllers/create_worker_controller.py b/dexbot/controllers/create_worker_controller.py
index 6e556a216..28ae5cbf7 100644
--- a/dexbot/controllers/create_worker_controller.py
+++ b/dexbot/controllers/create_worker_controller.py
@@ -124,17 +124,21 @@ def get_account(worker_data):
return worker_data['account']
@staticmethod
- def get_target_amount(worker_data):
- return worker_data['target']['amount']
+ def get_amount(worker_data):
+ return worker_data.get('amount', 0)
@staticmethod
- def get_target_center_price(worker_data):
- return worker_data['target']['center_price']
+ def get_amount_relative(worker_data):
+ return worker_data.get('amount_relative', False)
@staticmethod
- def get_target_center_price_dynamic(worker_data):
- return worker_data['target']['center_price_dynamic']
+ def get_center_price(worker_data):
+ return worker_data.get('center_price', 0)
@staticmethod
- def get_target_spread(worker_data):
- return worker_data['target']['spread']
+ def get_center_price_dynamic(worker_data):
+ return worker_data.get('center_price_dynamic', True)
+
+ @staticmethod
+ def get_spread(worker_data):
+ return worker_data.get('spread', 5)
diff --git a/dexbot/strategies/relative_orders.py b/dexbot/strategies/relative_orders.py
index a595b3390..3320c4cd4 100644
--- a/dexbot/strategies/relative_orders.py
+++ b/dexbot/strategies/relative_orders.py
@@ -1,6 +1,5 @@
from dexbot.basestrategy import BaseStrategy
from dexbot.queue.idle_queue import idle_add
-
from bitshares.amount import Amount
@@ -19,16 +18,17 @@ def __init__(self, *args, **kwargs):
self.error_onMarketUpdate = self.error
self.error_onAccount = self.error
- self.target = self.worker.get("target", {})
- self.is_center_price_dynamic = self.target["center_price_dynamic"]
+ self.is_center_price_dynamic = self.worker["center_price_dynamic"]
if self.is_center_price_dynamic:
self.center_price = None
else:
- self.center_price = self.target["center_price"]
+ self.center_price = self.worker["center_price"]
+
+ self.is_relative_order_size = self.worker['amount_relative']
+ self.order_size = float(self.worker['amount'])
self.buy_price = None
self.sell_price = None
- self.calculate_order_prices()
self.initial_balance = self['initial_balance'] or 0
self.worker_name = kwargs.get('name')
@@ -36,12 +36,35 @@ def __init__(self, *args, **kwargs):
self.check_orders()
+ @property
+ def amount_quote(self):
+ """""
+ Get quote amount, calculate if order size is relative
+ """""
+ if self.is_relative_order_size:
+ quote_balance = float(self.balance(self.market["quote"]))
+ return quote_balance * (self.order_size / 100)
+ else:
+ return self.order_size
+
+ @property
+ def amount_base(self):
+ """""
+ Get base amount, calculate if order size is relative
+ """""
+ if self.is_relative_order_size:
+ base_balance = float(self.balance(self.market["base"]))
+ # amount = % of balance / buy_price = amount combined with calculated price to give % of balance
+ return base_balance * (self.order_size / 100) / self.buy_price
+ else:
+ return self.order_size
+
def calculate_order_prices(self):
if self.is_center_price_dynamic:
self.center_price = self.calculate_center_price
- self.buy_price = self.center_price * (1 - (self.target["spread"] / 2) / 100)
- self.sell_price = self.center_price * (1 + (self.target["spread"] / 2) / 100)
+ self.buy_price = self.center_price * (1 - (self.worker["spread"] / 2) / 100)
+ self.sell_price = self.center_price * (1 + (self.worker["spread"] / 2) / 100)
def error(self, *args, **kwargs):
self.cancel_all()
@@ -50,7 +73,6 @@ def error(self, *args, **kwargs):
def update_orders(self):
self.log.info('Change detected, updating orders')
- amount = self.target['amount']
# Recalculate buy and sell order prices
self.calculate_order_prices()
@@ -60,42 +82,46 @@ def update_orders(self):
order_ids = []
+ amount_base = self.amount_base
+ amount_quote = self.amount_quote
+
# Buy Side
- if float(self.balance(self.market["base"])) < self.buy_price * amount:
+ if float(self.balance(self.market["base"])) < self.buy_price * amount_base:
self.log.critical(
- 'Insufficient buy balance, needed {} {}'.format(self.buy_price * amount, self.market['base']['symbol'])
+ 'Insufficient buy balance, needed {} {}'.format(self.buy_price * amount_base,
+ self.market['base']['symbol'])
)
self.disabled = True
else:
buy_transaction = self.market.buy(
self.buy_price,
- Amount(amount=amount, asset=self.market["quote"]),
+ Amount(amount=amount_base, asset=self.market["quote"]),
account=self.account,
returnOrderId="head"
)
buy_order = self.get_order(buy_transaction['orderid'])
- self.log.info('Placed a buy order for {} {} @ {}'.format(amount,
- self.market["quote"]['symbol'],
+ self.log.info('Placed a buy order for {} {} @ {}'.format(self.buy_price * amount_base,
+ self.market["base"]['symbol'],
self.buy_price))
if buy_order:
self['buy_order'] = buy_order
order_ids.append(buy_transaction['orderid'])
# Sell Side
- if float(self.balance(self.market["quote"])) < amount:
+ if float(self.balance(self.market["quote"])) < amount_quote:
self.log.critical(
- "Insufficient sell balance, needed {} {}".format(amount, self.market['quote']['symbol'])
+ "Insufficient sell balance, needed {} {}".format(amount_quote, self.market['quote']['symbol'])
)
self.disabled = True
else:
sell_transaction = self.market.sell(
self.sell_price,
- Amount(amount=amount, asset=self.market["quote"]),
+ Amount(amount=amount_quote, asset=self.market["quote"]),
account=self.account,
returnOrderId="head"
)
sell_order = self.get_order(sell_transaction['orderid'])
- self.log.info('Placed a sell order for {} {} @ {}'.format(amount,
+ self.log.info('Placed a sell order for {} {} @ {}'.format(amount_quote,
self.market["quote"]['symbol'],
self.sell_price))
if sell_order:
diff --git a/dexbot/views/create_worker.py b/dexbot/views/create_worker.py
index 4ac723965..bca589b0b 100644
--- a/dexbot/views/create_worker.py
+++ b/dexbot/views/create_worker.py
@@ -23,8 +23,23 @@ def __init__(self, controller):
self.ui.save_button.clicked.connect(self.handle_save)
self.ui.cancel_button.clicked.connect(self.reject)
self.ui.center_price_dynamic_checkbox.stateChanged.connect(self.onchange_center_price_dynamic_checkbox)
+ self.ui.relative_order_size_checkbox.stateChanged.connect(self.onchange_relative_order_size_checkbox)
self.worker_data = {}
+ def onchange_relative_order_size_checkbox(self):
+ checkbox = self.ui.relative_order_size_checkbox
+ if checkbox.isChecked():
+ self.ui.amount_input.setSuffix('%')
+ self.ui.amount_input.setDecimals(2)
+ self.ui.amount_input.setMaximum(100.00)
+ self.ui.amount_input.setValue(10.00)
+ self.ui.amount_input.setMinimumWidth(151)
+ else:
+ self.ui.amount_input.setSuffix('')
+ self.ui.amount_input.setDecimals(8)
+ self.ui.amount_input.setMaximum(1000000000.000000)
+ self.ui.amount_input.setValue(0.000000)
+
def onchange_center_price_dynamic_checkbox(self):
checkbox = self.ui.center_price_dynamic_checkbox
if checkbox.isChecked():
@@ -96,12 +111,12 @@ def handle_save(self):
ui = self.ui
spread = float(ui.spread_input.text()[:-1]) # Remove the percentage character from the end
- target = {
- 'amount': float(ui.amount_input.text()),
- 'center_price': float(ui.center_price_input.text()),
- 'center_price_dynamic': bool(ui.center_price_dynamic_checkbox.isChecked()),
- 'spread': spread
- }
+
+ # If order size is relative, remove percentage character in the end
+ if ui.relative_order_size_checkbox.isChecked():
+ amount = float(ui.amount_input.text()[:-1])
+ else:
+ amount = ui.amount_input.text()
base_asset = ui.base_asset_input.currentText()
quote_asset = ui.quote_asset_input.text()
@@ -112,7 +127,11 @@ def handle_save(self):
'market': '{}/{}'.format(quote_asset, base_asset),
'module': worker_module,
'strategy': strategy,
- 'target': target
+ 'amount': amount,
+ 'amount_relative': bool(ui.relative_order_size_checkbox.isChecked()),
+ 'center_price': float(ui.center_price_input.text()),
+ 'center_price_dynamic': bool(ui.center_price_dynamic_checkbox.isChecked()),
+ 'spread': spread
}
self.worker_name = ui.worker_name_input.text()
self.accept()
diff --git a/dexbot/views/edit_worker.py b/dexbot/views/edit_worker.py
index 480c4c72b..533db183b 100644
--- a/dexbot/views/edit_worker.py
+++ b/dexbot/views/edit_worker.py
@@ -20,10 +20,19 @@ def __init__(self, controller, worker_name, config):
self.base_asset_input.addItems(self.controller.base_assets)
self.quote_asset_input.setText(self.controller.get_quote_asset(worker_data))
self.account_name.setText(self.controller.get_account(worker_data))
- self.amount_input.setValue(self.controller.get_target_amount(worker_data))
- self.center_price_input.setValue(self.controller.get_target_center_price(worker_data))
- center_price_dynamic = self.controller.get_target_center_price_dynamic(worker_data)
+ if self.controller.get_amount_relative(worker_data):
+ self.order_size_input_to_relative()
+ self.relative_order_size_checkbox.setChecked(True)
+ else:
+ self.order_size_input_to_static()
+ self.relative_order_size_checkbox.setChecked(False)
+
+ self.amount_input.setValue(float(self.controller.get_amount(worker_data)))
+
+ self.center_price_input.setValue(self.controller.get_center_price(worker_data))
+
+ center_price_dynamic = self.controller.get_center_price_dynamic(worker_data)
if center_price_dynamic:
self.center_price_input.setEnabled(False)
self.center_price_dynamic_checkbox.setChecked(True)
@@ -31,12 +40,36 @@ def __init__(self, controller, worker_name, config):
self.center_price_input.setEnabled(True)
self.center_price_dynamic_checkbox.setChecked(False)
- self.spread_input.setValue(self.controller.get_target_spread(worker_data))
+ self.spread_input.setValue(self.controller.get_spread(worker_data))
self.save_button.clicked.connect(self.handle_save)
self.cancel_button.clicked.connect(self.reject)
self.center_price_dynamic_checkbox.stateChanged.connect(self.onchange_center_price_dynamic_checkbox)
+ self.center_price_dynamic_checkbox.stateChanged.connect(self.onchange_center_price_dynamic_checkbox)
+ self.relative_order_size_checkbox.stateChanged.connect(self.onchange_relative_order_size_checkbox)
self.worker_data = {}
+ def order_size_input_to_relative(self):
+ input_field = self.amount_input
+ input_field.setSuffix('%')
+ input_field.setDecimals(2)
+ input_field.setMaximum(100.00)
+ input_field.setMinimumWidth(151)
+
+ def order_size_input_to_static(self):
+ input_field = self.amount_input
+ input_field.setSuffix('')
+ input_field.setDecimals(8)
+ input_field.setMaximum(1000000000.000000)
+ input_field.setMinimumWidth(151)
+
+ def onchange_relative_order_size_checkbox(self):
+ if self.relative_order_size_checkbox.isChecked():
+ self.order_size_input_to_relative()
+ self.amount_input.setValue(10.00)
+ else:
+ self.order_size_input_to_static()
+ self.amount_input.setValue(0.000000)
+
def onchange_center_price_dynamic_checkbox(self):
checkbox = self.center_price_dynamic_checkbox
if checkbox.isChecked():
@@ -96,12 +129,12 @@ def handle_save(self):
return
spread = float(self.spread_input.text()[:-1]) # Remove the percentage character from the end
- target = {
- 'amount': float(self.amount_input.text()),
- 'center_price': float(self.center_price_input.text()),
- 'center_price_dynamic': bool(self.center_price_dynamic_checkbox.isChecked()),
- 'spread': spread
- }
+
+ # If order size is relative, remove percentage character in the end
+ if self.relative_order_size_checkbox.isChecked():
+ amount = float(self.amount_input.text()[:-1])
+ else:
+ amount = self.amount_input.text()
base_asset = self.base_asset_input.currentText()
quote_asset = self.quote_asset_input.text()
@@ -112,7 +145,11 @@ def handle_save(self):
'market': '{}/{}'.format(quote_asset, base_asset),
'module': worker_module,
'strategy': strategy,
- 'target': target
+ 'amount': amount,
+ 'amount_relative': bool(self.relative_order_size_checkbox.isChecked()),
+ 'center_price': float(self.center_price_input.text()),
+ 'center_price_dynamic': bool(self.center_price_dynamic_checkbox.isChecked()),
+ 'spread': spread
}
self.worker_name = self.worker_name_input.text()
self.accept()
diff --git a/dexbot/views/ui/create_worker_window.ui b/dexbot/views/ui/create_worker_window.ui
index aba78c846..b19e4458d 100644
--- a/dexbot/views/ui/create_worker_window.ui
+++ b/dexbot/views/ui/create_worker_window.ui
@@ -7,7 +7,7 @@
0
0
418
- 507
+ 529
@@ -235,11 +235,11 @@
8
- 999999999.998999953269958
+ 1000000000.000000000000000
- -
+
-
@@ -267,7 +267,7 @@
- -
+
-
false
@@ -304,7 +304,7 @@
- -
+
-
@@ -332,7 +332,7 @@
- -
+
-
@@ -360,7 +360,7 @@
- -
+
-
Calculate center price dynamically
@@ -370,6 +370,13 @@
+ -
+
+
+ Relative order size
+
+
+
diff --git a/dexbot/views/ui/edit_worker_window.ui b/dexbot/views/ui/edit_worker_window.ui
index fd4b61ea6..354ce3da0 100644
--- a/dexbot/views/ui/edit_worker_window.ui
+++ b/dexbot/views/ui/edit_worker_window.ui
@@ -7,7 +7,7 @@
0
0
400
- 459
+ 486
@@ -252,11 +252,11 @@
8
- 999999999.998999953269958
+ 1000000000.000000000000000
- -
+
-
@@ -284,7 +284,7 @@
- -
+
-
false
@@ -321,7 +321,14 @@
- -
+
-
+
+
+ Calculate center price dynamically
+
+
+
+ -
@@ -349,7 +356,7 @@
- -
+
-
@@ -377,10 +384,10 @@
- -
-
+
-
+
- Calculate center price dynamically
+ Relative order size