Skip to content

Commit

Permalink
Merge pull request #2318 from Drakkar-Software/dev
Browse files Browse the repository at this point in the history
Master merge
  • Loading branch information
GuillaumeDSM authored Apr 23, 2023
2 parents b1b5069 + 2d7d293 commit 92247ba
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 26 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

*It is strongly advised to perform an update of your tentacles after updating OctoBot. (start.py tentacles --install --all)*

## [0.4.49] - 2023-04-23
### Updated
- [CCXT] Update to ccxt 3.0.74
- [Websockets] Reduce unordered candles warnings
### Fixed
- [Coinbase] Trading simulator mode and data collector
- [Binance] Order creation issues
- [Bybit] Order creation issues
- [Telegram] set risk command
- [TradingView] remove warning on empty line

## [0.4.48] - 2023-04-18
### Added
- [WebInterface] Add filters to PNL tab.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# OctoBot [0.4.48](https://octobot.click/gh-changelog)
# OctoBot [0.4.49](https://octobot.click/gh-changelog)
[![PyPI](https://img.shields.io/pypi/v/OctoBot.svg?logo=pypi)](https://octobot.click/gh-pypi)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/e07fb190156d4efb8e7d07aaa5eff2e1)](https://app.codacy.com/gh/Drakkar-Software/OctoBot?utm_source=github.com&utm_medium=referral&utm_content=Drakkar-Software/OctoBot&utm_campaign=Badge_Grade_Dashboard)
[![Downloads](https://pepy.tech/badge/octobot/month)](https://pepy.tech/project/octobot)
Expand Down
6 changes: 5 additions & 1 deletion exchanges_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ def __init__(self, exchange_manager, name):
self.exchange_manager = exchange_manager
self.name = name

def _clear_pending_state(order, *args, **kwargs):
if order.is_pending_creation():
order.state = personal_data.OpenOrderState(order, True)

self.get_internal_producer = mock.Mock(
return_value=mock.Mock(
update_order_from_exchange=mock.AsyncMock(),
update_order_from_exchange=mock.AsyncMock(side_effect=_clear_pending_state),
send=mock.AsyncMock(),
)
)
Expand Down
48 changes: 38 additions & 10 deletions exchanges_tests/abstract_authenticated_exchange_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#
# You should have received a copy of the GNU General Public
# License along with OctoBot. If not, see <https://www.gnu.org/licenses/>.
import asyncio
import contextlib
import decimal
import time
Expand Down Expand Up @@ -50,6 +51,7 @@ class AbstractAuthenticatedExchangeTester:
ORDER_PRICE_DIFF = 20 # % of price difference compared to current price for limit and stop orders
EXPECT_MISSING_ORDER_FEES_DUE_TO_ORDERS_TOO_OLD_FOR_RECENT_TRADES = False # when recent trades are limited and
# closed orders fees are taken from recent trades
EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION = False
OPEN_ORDERS_IN_CLOSED_ORDERS = False
MARKET_FILL_TIMEOUT = 15
OPEN_TIMEOUT = 15
Expand Down Expand Up @@ -78,12 +80,21 @@ async def inner_test_create_and_cancel_limit_orders(self):
symbol = None
price = self.get_order_price(await self.get_price(), False)
size = self.get_order_size(await self.get_portfolio(), price)
# # DEBUG tools, uncomment to create specific orders
# symbol = "ALGO/BUSD"
# market_status = self.exchange_manager.exchange.get_market_status(symbol)
# precision = market_status[trading_enums.ExchangeConstantsMarketStatusColumns.PRECISION.value]
# limits = market_status[trading_enums.ExchangeConstantsMarketStatusColumns.LIMITS.value]
# price = personal_data.decimal_adapt_price(
# market_status,
# decimal.Decimal("0.1810")
# )
# size = personal_data.decimal_adapt_quantity(
# market_status,
# decimal.Decimal("7")
# )
# # end debug tools
open_orders = await self.get_open_orders()
# DEBUG tools, uncomment to create specific orders
# price = decimal.Decimal("0.047445")
# size = decimal.Decimal("4619")
# symbol = "OM/USDT"
# end debug tools
buy_limit = await self.create_limit_order(price, size, trading_enums.TradeOrderSide.BUY, symbol=symbol)
self.check_created_limit_order(buy_limit, price, size, trading_enums.TradeOrderSide.BUY)
assert await self.order_in_open_orders(open_orders, buy_limit)
Expand Down Expand Up @@ -679,32 +690,49 @@ async def wait_for_fill(self, order):
def parse_is_filled(raw_order):
return personal_data.parse_order_status(raw_order) in {trading_enums.OrderStatus.FILLED,
trading_enums.OrderStatus.CLOSED}
return await self._get_order_until(order, parse_is_filled, self.MARKET_FILL_TIMEOUT)
return await self._get_order_until(order, parse_is_filled, self.MARKET_FILL_TIMEOUT, True)

def parse_order_is_not_pending(self, raw_order):
return personal_data.parse_order_status(raw_order) not in (trading_enums.OrderStatus.UNKNOWN, None)

async def wait_for_open(self, order):
await self._get_order_until(order, self.parse_order_is_not_pending, self.OPEN_TIMEOUT)
await self._get_order_until(order, self.parse_order_is_not_pending, self.OPEN_TIMEOUT, True)

async def wait_for_cancel(self, order):
return personal_data.create_order_instance_from_raw(
self.exchange_manager.trader,
await self._get_order_until(order, personal_data.parse_is_cancelled, self.CANCEL_TIMEOUT)
await self._get_order_until(order, personal_data.parse_is_cancelled, self.CANCEL_TIMEOUT, False)
)

async def wait_for_edit(self, order, edited_quantity):
def is_edited(row_order):
return decimal.Decimal(str(row_order[trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value])) \
== edited_quantity
await self._get_order_until(order, is_edited, self.EDIT_TIMEOUT)
await self._get_order_until(order, is_edited, self.EDIT_TIMEOUT, False)

async def _get_order_until(self, order, validation_func, timeout):
async def _get_order_until(self, order, validation_func, timeout, can_order_be_not_found_on_exchange):
allow_not_found_order_on_exchange = \
can_order_be_not_found_on_exchange \
and self.exchange_manager.exchange.EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION
t0 = time.time()
while time.time() - t0 < timeout:
raw_order = await self.exchange_manager.exchange.get_order(order.order_id, order.symbol)
if raw_order is None:
print(f"{self.exchange_manager.exchange_name} {order.order_type} {validation_func.__name__} "
f"Order not found after {time.time() - t0} seconds. Order: [{order}]. Raw order: [{raw_order}]")
if not allow_not_found_order_on_exchange:
raise AssertionError(
f"exchange.get_order() returned None, which means order is not found on exchange. "
f"This should not happen as "
f"self.exchange_manager.exchange.EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION is "
f"{self.exchange_manager.exchange.EXPECT_POSSIBLE_ORDER_NOT_FOUND_DURING_ORDER_CREATION} "
f"and can_order_be_not_found_on_exchange is {can_order_be_not_found_on_exchange}"
)
if raw_order and validation_func(raw_order):
print(f"{self.exchange_manager.exchange_name} {order.order_type} {validation_func.__name__} "
f"True after {time.time() - t0} seconds. Order: [{order}]. Raw order: [{raw_order}]")
return raw_order
await asyncio.sleep(1)
raise TimeoutError(f"Order not filled/cancelled within {timeout}s: {order} ({validation_func.__name__})")

async def order_in_open_orders(self, previous_open_orders, order):
Expand Down
4 changes: 3 additions & 1 deletion exchanges_tests/test_bitget.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ async def test_get_my_recent_trades(self):
await super().test_get_my_recent_trades()

async def test_get_closed_orders(self):
await super().test_get_closed_orders()
# broken in ccxt 3.0.74 because of return self.safe_value(data, 'orderList', []) (no 'orderList' key)
with pytest.raises(AssertionError):
await super().test_get_closed_orders()

async def test_create_and_cancel_stop_orders(self):
# pass if not implemented
Expand Down
2 changes: 1 addition & 1 deletion exchanges_tests/test_cryptocom.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
pytestmark = pytest.mark.asyncio


class _TestCryptoComAuthenticatedExchange(
class TestCryptoComAuthenticatedExchange(
abstract_authenticated_exchange_tester.AbstractAuthenticatedExchangeTester
):
# enter exchange name as a class variable here
Expand Down
4 changes: 2 additions & 2 deletions exchanges_tests/test_hollaex.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class TestHollaexAuthenticatedExchange(
# enter exchange name as a class variable here
EXCHANGE_NAME = "hollaex"
EXCHANGE_TENTACLE_NAME = "hollaex" # specify EXCHANGE_TENTACLE_NAME as the tentacle class has no capital H
ORDER_CURRENCY = "BTC"
SETTLEMENT_CURRENCY = "USDT"
ORDER_CURRENCY = "ETH"
SETTLEMENT_CURRENCY = "BTC"
SYMBOL = f"{ORDER_CURRENCY}/{SETTLEMENT_CURRENCY}"
ORDER_SIZE = 25 # % of portfolio to include in test orders
EXPECT_MISSING_ORDER_FEES_DUE_TO_ORDERS_TOO_OLD_FOR_RECENT_TRADES = True # when recent trades are limited and
Expand Down
2 changes: 1 addition & 1 deletion octobot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@

PROJECT_NAME = "OctoBot"
AUTHOR = "Drakkar-Software"
VERSION = "0.4.48" # major.minor.revision
VERSION = "0.4.49" # major.minor.revision
LONG_VERSION = f"{VERSION}"
9 changes: 5 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ cython==0.29.32

# Drakkar-Software requirements
OctoBot-Commons==1.8.27
OctoBot-Trading==2.3.36
OctoBot-Trading==2.3.37
OctoBot-Evaluators==1.8.7
OctoBot-Tentacles-Manager==2.8.6
OctoBot-Services==1.5.4
OctoBot-Backtesting==1.8.1
OctoBot-Services==1.5.5
OctoBot-Backtesting==1.8.2
Async-Channel==2.1.0
trading-backend==1.0.19

Expand All @@ -22,4 +22,5 @@ setuptools<65.6 # Added because the distutils.log.Log class was removed in setup

# Community
websockets
gmqtt==0.6.11
gmqtt==0.6.11
supabase==1.0.3
5 changes: 0 additions & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,3 @@ universal = 1

[metadata]
license_file = LICENSE

[tool:pytest]
minversion = 3.0
testpaths = tests
addopts = -v -x --ignore=setup.py

0 comments on commit 92247ba

Please sign in to comment.