-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement different triggers to reset orders #273
Implement different triggers to reset orders #273
Conversation
- Always reset orders whether it was a filled, expired or manually cancelled order detected - Reset on partial fill (with % threshold, optional) - Allow to define custom order expiration time - Reset orders on market trade (optional) - Reset orders on center price change threshold (optional) - Also disable log message about correct orders to remove log noise - Writing of a trade log entry is disabled because we cannot properly distinguish an expired order from a filled one Closes: Codaone#226, Codaone#270
dexbot/strategies/relative_orders.py
Outdated
if need_update: | ||
self.update_orders() | ||
else: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of logging "Orders correct on market" is that it's used as a status for the worker in the GUI.
In a case where the strategy is initialized but no action is required to be done after it, a status message "Initializing Relative Orders" will get stuck on the GUI and that will just confuse the user.
I implemented a fix for this here 347eedf#diff-472e57ad5bbb88571e326e56670648b7R173 but I think it's going to take a while until I can merge that to master, so could just copy the change from there?
dexbot/strategies/relative_orders.py
Outdated
@@ -108,7 +157,7 @@ def calculate_order_prices(self): | |||
self.sell_price = self.center_price * math.sqrt(1 + self.spread) | |||
|
|||
def update_orders(self): | |||
self.log.info('Change detected, updating orders') | |||
#self.log.debug('Change detected, updating orders') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't leave unneeded comments lying around. Changing this to debug is fine.
dexbot/strategies/relative_orders.py
Outdated
self.write_order_log(self.worker_name, order) | ||
need_update = True | ||
self.log.debug('Could not found order on the market, it was filled, expired or cancelled') | ||
# FIXME: writing a log entry is disabled because we cannot distinguish an expired order |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to disable order expiration setting for now, so that order logging isn't totally broken
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also inform users that trades.csv will be useless if they use order expiration. Order expiration is a useful tool otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that's fine then it only needs an if statement to check if order expiration setting is on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suits me
dexbot/strategies/relative_orders.py
Outdated
|
||
# Check for conflicting settings | ||
if self.is_reset_on_price_change and not self.is_center_price_dynamic: | ||
self.log.error('reset_on_price_change requires Dynamic Center Price') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the human readable format for the names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikakoi do you mean human readable format inside the log message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Just change the message to 'Reset orders on center price change' requires 'Dynamic center price'
or something
dexbot/strategies/relative_orders.py
Outdated
if self.is_reset_on_price_change and not self.is_center_price_dynamic: | ||
self.log.error('reset_on_price_change requires Dynamic Center Price') | ||
self.disabled = True | ||
self.update_orders() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you changed check_orders() to update_orders()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because relative orders strategy is supposed to remove orders on exit, we can assume on initializing that we don't have any orders anyway, so there is no sense in checking something that should not be exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well you can actually keep the orders on the market with relative orders on exit. If you simply quit the program when relative orders is running, it leaves the orders on the market.
I just feel it's a waste to cancel those orders on start up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. Furthermore, we can add an option into GUI like "Keep orders on exit" to let the user decide should the bot keep orders or not.
As described by @mikakoi: The point of logging "Orders correct on market" is that it's used as a status for the worker in the GUI. In a case where the strategy is initialized but no action is required to be done after it, a status message "Initializing Relative Orders" will get stuck on the GUI and that will just confuse the user. Code part is from 347eedf Closes: Codaone#270
There are maybe old orders from previous run, so give a chance to them.
We still need to cancel old orders on startup when "Reset orders on center price change" is active. We don't know what the center price was before.
OK, updated the PR with proposed fixes. |
dexbot/strategies/relative_orders.py
Outdated
delta = datetime.now() - self.last_check | ||
|
||
# Only allow to check orders whether minimal time passed | ||
if delta < timedelta(seconds=self.min_check_interval): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check doesn't work on initialization as self.last_check is set in the constructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, we don't need it on initialization, this check is for rate-limiting only.
self.log.info("Orders correct on market") | ||
if need_update: | ||
self.update_orders() | ||
elif self.initializing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you could just check for event == 'init', since you're passing that in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not work because 'init' event is passed during initialization only, and thus code under if need_update
will be used in 99% times. On the next check an event will be a real market event, not 'init'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the point of the log message is to display it only during initialization, it doesn't matter if it doesn't get ran after that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During initialization there will be another message "Done placing orders" whether everything fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well not really, if in the initialization phase the worker doesn't need to place any orders so it doesn't print the message. But it's fine since already removed the event parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So no further changes required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, merged the changes already
dexbot/strategies/relative_orders.py
Outdated
# be correct | ||
|
||
if (self.is_reset_on_market_trade and | ||
isinstance(event, FilledOrder)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be evaluated true if dynamic center price is on
dexbot/strategies/relative_orders.py
Outdated
ConfigElement('reset_on_partial_fill', 'bool', True, 'Reset orders on partial fill', | ||
'Reset orders when buy or sell order is partially filled', None), | ||
ConfigElement('partial_fill_threshold', 'float', 30, 'Fill threshold', | ||
'Fill threshold to reset orders', (0, 100, 2, '%')), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should say Order fill threshold to reset orders
to be more descriptive
dexbot/strategies/relative_orders.py
Outdated
@@ -1,8 +1,11 @@ | |||
import math | |||
from datetime import datetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use from datetime import datetime, timedelta
This is option is actually not needed because it's duplicating behavior of "Reset on center price change" with "threshold = 0"
check_orders() are called from __init__(), so it will not work because initial "self.last_check = now"
Always reset orders whether it was a filled, expired or manually
cancelled order detected
Reset on partial fill (with % threshold, optional)
Allow to define custom order expiration time
Reset orders on market trade (optional)
Reset orders on center price change threshold (optional)
Also disable log message about correct orders to remove log noise
Writing of a trade log entry is disabled because we cannot properly
distinguish an expired order from a filled one
Closes: #226, #270