xync-client 0.0.235.dev3__tar.gz → 0.0.236.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/PKG-INFO +1 -1
  2. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Agent.py +81 -107
  3. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Ex.py +25 -11
  4. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/xtype.py +7 -1
  5. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/agent.py +45 -44
  6. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/etype/ad.py +11 -3
  7. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/ex.py +64 -2
  8. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/details.py +4 -0
  9. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client.egg-info/PKG-INFO +1 -1
  10. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/.env.sample +0 -0
  11. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/.gitignore +0 -0
  12. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/.pre-commit-config.yaml +0 -0
  13. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/CLAUDE.md +0 -0
  14. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/README.md +0 -0
  15. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/__init__.py +0 -0
  16. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/makefile +0 -0
  17. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/pyproject.toml +0 -0
  18. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/setup.cfg +0 -0
  19. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/TestAgent.py +0 -0
  20. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/TestAsset.py +0 -0
  21. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/TestEx.py +0 -0
  22. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/TestOrder.py +0 -0
  23. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Binance/test_binance.py +0 -0
  24. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  25. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  26. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Gate/test_gate.py +0 -0
  27. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  28. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  29. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/__init__.py +0 -0
  30. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/tests/_todo_refact/_test_ex.py +0 -0
  31. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/AdLoader.py +0 -0
  32. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Asset.py +0 -0
  33. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Auth.py +0 -0
  34. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/BaseTest.py +0 -0
  35. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Exception.py +0 -0
  36. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/HasAbotUid.py +0 -0
  37. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/InAgent.py +0 -0
  38. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/Order.py +0 -0
  39. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Abc/PmAgent.py +0 -0
  40. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/__init__.py +0 -0
  41. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/binance_async.py +0 -0
  42. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/earn_api.py +0 -0
  43. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/etype/ad.py +0 -0
  44. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/etype/pm.py +0 -0
  45. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/ex.py +0 -0
  46. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/exceptions.py +0 -0
  47. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/sapi.py +0 -0
  48. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Binance/web_c2c.py +0 -0
  49. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/__init__.py +0 -0
  50. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/agent.py +0 -0
  51. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/base.py +0 -0
  52. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/etype/ad.py +0 -0
  53. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/etype/pm.py +0 -0
  54. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/ex.py +0 -0
  55. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/req.mjs +0 -0
  56. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BingX/sign.js +0 -0
  57. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BitGet/__init__.py +0 -0
  58. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BitGet/agent.py +0 -0
  59. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BitGet/etype/ad.py +0 -0
  60. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BitGet/ex.py +0 -0
  61. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/BitPapa/ex.py +0 -0
  62. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/etype/__init__.py +0 -0
  63. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/etype/cred.py +0 -0
  64. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/etype/order.py +0 -0
  65. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/etype/pm.py +0 -0
  66. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/inAgent.py +0 -0
  67. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/order.py +0 -0
  68. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/web_earn.py +0 -0
  69. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/web_p2p.py +0 -0
  70. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Bybit/ws.py +0 -0
  71. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Gate/etype/ad.py +0 -0
  72. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Gate/ex.py +0 -0
  73. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Gate/premarket.py +0 -0
  74. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Gmail/__init__.py +0 -0
  75. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/agent.py +0 -0
  76. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/earn.py +0 -0
  77. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/__init__.py +0 -0
  78. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/ad.py +0 -0
  79. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/cred.py +0 -0
  80. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/order.py +0 -0
  81. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/pm.py +0 -0
  82. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/etype/test.py +0 -0
  83. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Htx/ex.py +0 -0
  84. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/KuCoin/etype/ad.py +0 -0
  85. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/KuCoin/etype/pm.py +0 -0
  86. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/KuCoin/ex.py +0 -0
  87. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/KuCoin/web.py +0 -0
  88. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/agent.py +0 -0
  89. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/api.py +0 -0
  90. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/etype/ad.py +0 -0
  91. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/etype/order.py +0 -0
  92. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/etype/pm.py +0 -0
  93. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Mexc/ex.py +0 -0
  94. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Okx/1.py +0 -0
  95. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Okx/agent.py +0 -0
  96. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Okx/etype/ad.py +0 -0
  97. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Okx/etype/pm.py +0 -0
  98. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Okx/ex.py +0 -0
  99. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/.gitignore +0 -0
  100. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Alfa/__init__.py +0 -0
  101. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Alfa/state.json +0 -0
  102. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/MTS/__init__.py +0 -0
  103. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Ozon/__init__.py +0 -0
  104. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Payeer/.gitignore +0 -0
  105. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Payeer/agent.py +0 -0
  106. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Payeer/login.py +0 -0
  107. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Payeer/trade.py +0 -0
  108. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Sber/__init__.py +0 -0
  109. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Sber/utils.py +0 -0
  110. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  111. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  112. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  113. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Volet/agent.py +0 -0
  114. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Volet/api.py +0 -0
  115. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Volet/pl.py +0 -0
  116. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Xync/__main__.py +0 -0
  117. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Xync/ed.py +0 -0
  118. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/Yandex/__init__.py +0 -0
  119. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/Pms/airtm/__init__.py +0 -0
  120. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/agent.py +0 -0
  121. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/asset.py +0 -0
  122. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/auth.py +0 -0
  123. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/ex.py +0 -0
  124. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/inAgent.py +0 -0
  125. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/order.py +0 -0
  126. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/pyd.py +0 -0
  127. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/pyro.py +0 -0
  128. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/TgWallet/web.py +0 -0
  129. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/__init__.py +0 -0
  130. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/loader.py +0 -0
  131. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client/pm_unifier.py +0 -0
  132. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client.egg-info/SOURCES.txt +0 -0
  133. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client.egg-info/dependency_links.txt +0 -0
  134. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client.egg-info/requires.txt +0 -0
  135. {xync_client-0.0.235.dev3 → xync_client-0.0.236.dev1}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.235.dev3
3
+ Version: 0.0.236.dev1
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import math
2
3
  from abc import abstractmethod
3
4
  from asyncio import create_task, sleep
4
5
  from collections import defaultdict
@@ -8,7 +9,7 @@ from pydantic import BaseModel
8
9
  from tortoise.exceptions import IntegrityError
9
10
  from x_client import df_hdrs
10
11
  from x_client.aiohttp import Client as HttpClient
11
- from xync_client.details import hot_ad_cond
12
+ from xync_client.details import hot_ad_cond, more1perc
12
13
  from xync_schema.enums import AdStatus, OrderStatus
13
14
 
14
15
  from xync_client.Abc.PmAgent import PmAgentClient
@@ -16,7 +17,7 @@ from xync_client.Abc.PmAgent import PmAgentClient
16
17
  from xync_client.Abc.InAgent import BaseInAgentClient
17
18
 
18
19
  from xync_client.Bybit.etype.order import TakeAdReq
19
- from xync_schema import models
20
+ from xync_schema import models, xtype
20
21
 
21
22
  from xync_client.Abc.Ex import BaseExClient
22
23
  from xync_client.Abc.xtype import (
@@ -27,7 +28,6 @@ from xync_client.Abc.xtype import (
27
28
  GetAdsReq,
28
29
  BaseCredexsExidsTrait,
29
30
  BaseOrderFull,
30
- BaseOrder,
31
31
  MyAdXOut,
32
32
  )
33
33
 
@@ -36,7 +36,7 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
36
36
  actor: models.Actor
37
37
  agent: models.Agent
38
38
  ex_client: BaseExClient
39
- orders: dict[int, tuple[models.Order, BaseOrder]] = {} # pending
39
+ orders: dict[int, tuple[models.Order, xtype.BaseOrder]] = {} # pending
40
40
  pm_clients: dict[int, PmAgentClient] # {pm_id: PmAgentClient}
41
41
  api: HttpClient
42
42
  cred_x2e: dict[int, int] = {}
@@ -61,7 +61,7 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
61
61
  self.pm_clients: dict[int, PmAgentClient] = defaultdict()
62
62
  super().__init__(self.actor.ex.host_p2p, headers, cookies, proxy) # and proxy.str()
63
63
  # start
64
- create_task(self.start())
64
+ # create_task(self.start())
65
65
 
66
66
  async def x2e_cred(self, cred_id: int) -> int: # cred.exid
67
67
  if not self.cred_x2e.get(cred_id):
@@ -114,7 +114,7 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
114
114
  await self.load_pending_orders()
115
115
  await self.ads_share()
116
116
 
117
- async def load_assets(self, coin_ids: list[int] = None) -> dict:
117
+ async def load_assets(self, coin_ids: list[int] = None):
118
118
  assets = {cid: await self.get_asset(cid) for cid in coin_ids} if coin_ids else await self.my_assets()
119
119
  for cid, amount in assets.items():
120
120
  await self.asset_save(cid, amount)
@@ -188,7 +188,7 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
188
188
  @abstractmethod
189
189
  async def _get_order_full(self, order_exid: int) -> BaseOrderFull: ...
190
190
 
191
- async def get_order_full(self, order_exid: int) -> BaseOrder:
191
+ async def get_order_full(self, order_exid: int) -> xtype.BaseOrder:
192
192
  eorder: BaseOrderFull = await self._get_order_full(order_exid)
193
193
  _, cur_scale, __ = await self.ex_client.x2e_cur(await self.ex_client.e2x_cur(eorder.curex_exid))
194
194
  _, coin_scale = await self.ex_client.x2e_coin(await self.ex_client.e2x_coin(eorder.coinex_exid))
@@ -203,11 +203,11 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
203
203
  amount=int(eorder.amount * 10**cur_scale),
204
204
  quantity=int(eorder.quantity * 10**coin_scale),
205
205
  )
206
- return BaseOrder.model_validate(border)
206
+ return xtype.BaseOrder.model_validate(border)
207
207
 
208
- async def load_order(self, order_exid: int, force_refresh: bool = False) -> tuple[models.Order, BaseOrder]:
208
+ async def load_order(self, order_exid: int, force_refresh: bool = False) -> tuple[models.Order, xtype.BaseOrder]:
209
209
  if not self.orders.get(order_exid) or force_refresh:
210
- order: BaseOrder = await self.get_order_full(order_exid)
210
+ order: xtype.BaseOrder = await self.get_order_full(order_exid)
211
211
  if not (
212
212
  order_db := await models.Order.get_or_none(
213
213
  exid=order_exid, ad__maker__ex=self.actor.ex
@@ -222,7 +222,7 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
222
222
  self.orders[order_exid] = order_db, order
223
223
  return self.orders[order_exid]
224
224
 
225
- async def order_save(self, order: BaseOrder) -> models.Order:
225
+ async def order_save(self, order: xtype.BaseOrder) -> models.Order:
226
226
  order_in = models.Order.validate(order.model_dump())
227
227
  odb, _ = await models.Order.update_or_create(**order_in.df_unq())
228
228
 
@@ -524,12 +524,62 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
524
524
  @abstractmethod
525
525
  async def _ad_upd_api(self, ad: MyAdXOut) -> int: ...
526
526
 
527
+ @staticmethod
528
+ def fee(min_count):
529
+ return 7.5 * math.exp(-0.1 * min_count) + 1.1
530
+
531
+ async def ad_fresh(self, ads: list[models.Ad], is_sell: bool, bal: float, cur_min, rate: float, haq: dict) -> dict:
532
+ if not ads:
533
+ return haq
534
+
535
+ ad = await ads.pop(0).to_float(ex_id=self.actor.ex_id)
536
+ if (min_count := int(ad.min_fiat / cur_min)) in {1, 10, 60}: # is_full
537
+ i = (list(haq)).index((min_count, int(ad.filtered)))
538
+ elif 5 <= min_count < 10:
539
+ i = 2
540
+ elif 23 <= min_count < 60:
541
+ i = 3
542
+ else:
543
+ logging.error(f"Wrong ad.min_fiat: {ad.exid}:{ad.min_fiat}:{ad.filtered}") # need debug
544
+ return await self.ad_fresh(ads, is_sell, bal, cur_min, rate, haq)
545
+ k, fltrd = list(haq)[i]
546
+ target_min = cur_min * k
547
+ # ad.min_fiat = min(target_min, xbal)
548
+
549
+ fld = ("amount", "quantity")[
550
+ int(is_sell)
551
+ ] # если покупка - отталкиваемся от имеющегося cur баланса, else - coin
552
+ old_bal = getattr(ad, fld)
553
+ setattr(ad, fld, bal)
554
+ setattr(ad, ("amount", "quantity")[int(not is_sell)], None) # а связанный (другой) балланс обнуляем
555
+ xma = MyAdXOut.model_validate(ad, from_attributes=True)
556
+
557
+ if k > 1 and xma.amount < target_min / 2: # хватает ли денег на размещение объявы
558
+ logging.warning(f"Less balance {bal} for {is_sell} ad:{ad.exid}:{ad.min_fiat}:{ad.filtered}")
559
+ return await self.ad_fresh(ads, is_sell, bal, cur_min, rate, haq)
560
+
561
+ xma.min_fiat = min(target_min, xma.amount)
562
+ min_count = xma.min_fiat / cur_min
563
+ pk = self.fee(min_count) if fltrd else 10
564
+ sk = 2 * int(is_sell) - 1
565
+ new_price = round(rate * 0.01 * (1 + sk * pk / 200), 2)
566
+ if xma.price != new_price or more1perc(
567
+ old_bal, bal
568
+ ): # если текущий объем валюты/монеты не совпадает с текущим балансом - обновляем
569
+ xma.price = new_price
570
+ xma.cond_txt = hot_ad_cond
571
+ await self._ad_upd_api(xma)
572
+ haq[(k, fltrd)][int(is_sell)] += 1
573
+ else:
574
+ haq[(k, fltrd)][int(is_sell)] -= 1
575
+ return await self.ad_fresh(ads, is_sell, bal, cur_min, rate, haq)
576
+
527
577
  async def ads_fresh(self, cur_id: int = 1, coin_id: int = 1):
528
578
  """
529
579
  Обновляем/добавляем объявления агента, в зависимости от кол-ва объявлений которое он может размещать
530
580
  одновременно `same_dir_ad` (от 1 до 4), и его текущего coin_balance.
531
581
  """
532
- curex = await models.CurEx.get(cur_id=cur_id, ex_id=self.actor.ex_id)
582
+ curex = await models.CurEx.get(cur_id=cur_id, ex_id=self.actor.ex_id).prefetch_related("cur")
533
583
  usdt_bal = (await self.agent.coins_balance())[coin_id]
534
584
  xbals = await self.actor.person.user.balances()
535
585
  xbal = xbals[cur_id]
@@ -537,10 +587,14 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
537
587
  # то постим 4 объявления:
538
588
  # 1) с минимальным нижним лимитом размера ордера, и без фильтрации контрагентов
539
589
  # 2) с минимальным лимитом, но с фильтрацией контрагентов
540
- # 3) с 10x мин лимитом, и с фильтрацией (если вообще есть баланс от 10x min)
541
- # 4) 50x мин лимит, либо весь баланс если он меньше, с фильтрацией (если есть баланс от 20x min)
542
- if usdt_bal < curex.minimum:
543
- return
590
+ # 3) с 10x мин лимитом, и с фильтрацией (если вообще есть баланс хотя бы от 5x min)
591
+ # 4) 60x мин лимит, либо весь баланс если он меньше, с фильтрацией (если есть баланс от 30x min)
592
+ hot_ads_q = { # item legend: (min_multiplier, is_filtered): [buy_ad_is_posted, sell_ad_is_posted]
593
+ (1, 0): [0, 0],
594
+ (1, 1): [0, 0],
595
+ (10, 1): [0, 0],
596
+ (60, 1): [0, 0],
597
+ }
544
598
  fltr = dict(
545
599
  my_ad__credexs__cred__ovr_pm_id=0,
546
600
  my_ad__credexs__cred__pmcur__cur_id=cur_id,
@@ -549,110 +603,30 @@ class BaseAgentClient(HttpClient, BaseInAgentClient): # , metaclass=ABCMeta
549
603
  )
550
604
  prftch = "my_ad__credexs", "pair_side__pair__coin", "pair_side__pair__cur"
551
605
 
606
+ if xbal < curex.minimum:
607
+ logging.error(f"Not enough xync balance: {xbal}")
608
+ return
609
+
552
610
  bads = (
553
611
  await models.Ad.filter(**fltr, status=AdStatus.active, pair_side__is_sell=False)
554
612
  .order_by("min_fiat", "filtered")
555
613
  .prefetch_related(*prftch)
556
614
  .limit(self.agent.same_dir_ad)
557
615
  )
558
- if not bads:
559
- return
560
- bad = await bads.pop(0).to_float(ex_id=self.actor.ex_id)
561
- if bad.min_fiat != curex.minimum and bad.filtered:
562
- logging.error(bad.min_fiat) # need debug
563
- if bad.amount != xbal:
564
- bad.amount = xbal
565
- bad.quantity = None
566
- xma = MyAdXOut.model_validate(bad, from_attributes=True)
567
- xma.cond_txt = hot_ad_cond
568
- await self._ad_upd_api(xma)
569
-
570
- if not bads:
571
- return
572
- bad = await bads.pop(0).to_float(ex_id=self.actor.ex_id)
573
- if bad.min_fiat != curex.minimum and not bad.filtered:
574
- logging.error(bad.min_fiat) # need debug
575
- if bad.amount != xbal:
576
- bad.amount = xbal
577
- bad.quantity = None
578
- xma = MyAdXOut.model_validate(bad, from_attributes=True)
579
- xma.cond_txt = hot_ad_cond
580
- await self._ad_upd_api(xma)
581
-
582
- if not bads:
583
- return
584
- bad = await bads.pop(0).to_float(ex_id=self.actor.ex_id)
585
- if curex.minimum * 2 <= bad.min_fiat < curex.minimum * 10 or bad.amount != xbal:
586
- bad.min_fiat = min(xbal, curex.minimum * 10)
587
- bad.amount = xbal
588
- bad.quantity = None
589
- xma = MyAdXOut.model_validate(bad, from_attributes=True)
590
- xma.cond_txt = hot_ad_cond
591
- await self._ad_upd_api(xma)
616
+ await self.ad_fresh(bads, False, xbal, curex.minimum, curex.cur.rate, hot_ads_q)
592
617
 
593
- if not bads:
618
+ if usdt_bal * curex.cur.rate * 10**-curex.cur.scale < curex.minimum:
619
+ logging.error(f"Not enough {self.ex_client.ex.name} balance: {usdt_bal}")
594
620
  return
595
- bad = await bads.pop(0).to_float(ex_id=self.actor.ex_id)
596
- if curex.minimum * 20 <= bad.min_fiat < curex.minimum * 50 or bad.amount != xbal:
597
- bad.min_fiat = min(xbal, curex.minimum * 10)
598
- bad.amount = xbal
599
- bad.quantity = None
600
- xma = MyAdXOut.model_validate(bad, from_attributes=True)
601
- xma.cond_txt = hot_ad_cond
602
- await self._ad_upd_api(xma)
603
621
 
604
- # sell
605
622
  sads = (
606
- await models.Ad.filter(**fltr, status=AdStatus.active, pair_side__is_sell=False)
607
- .order_by("min_fiat", "filtered")
623
+ await models.Ad.filter(**fltr, status=AdStatus.active, pair_side__is_sell=True)
624
+ .order_by("-min_fiat", "-filtered")
608
625
  .prefetch_related(*prftch)
609
626
  .limit(self.agent.same_dir_ad)
610
627
  )
611
- if not sads:
612
- return
613
- sad = await sads.pop(0).to_float(ex_id=self.actor.ex_id)
614
- if sad.min_fiat != curex.minimum and sad.filtered:
615
- logging.error(sad.min_fiat) # need debug
616
- if sad.quantity != usdt_bal:
617
- sad.quantity = usdt_bal
618
- sad.amount = None
619
- xma = MyAdXOut.model_validate(sad, from_attributes=True)
620
- xma.cond_txt = hot_ad_cond
621
- await self._ad_upd_api(xma)
622
-
623
- if not sads:
624
- return
625
- sad = await sads.pop(0).to_float(ex_id=self.actor.ex_id)
626
- if sad.min_fiat != curex.minimum and not sad.filtered:
627
- logging.error(sad.min_fiat) # need debug
628
- if sad.quantity != usdt_bal:
629
- sad.quantity = usdt_bal
630
- sad.amount = None
631
- xma = MyAdXOut.model_validate(sad, from_attributes=True)
632
- xma.cond_txt = hot_ad_cond
633
- await self._ad_upd_api(xma)
634
-
635
- if not sads:
636
- return
637
- sad = await sads.pop(0).to_float(ex_id=self.actor.ex_id)
638
- if curex.minimum * 2 <= sad.min_fiat < curex.minimum * 10 or sad.quantity != usdt_bal:
639
- sad.min_fiat = min(usdt_bal, curex.minimum * 10)
640
- sad.quantity = usdt_bal
641
- sad.amount = None
642
- xma = MyAdXOut.model_validate(sad, from_attributes=True)
643
- xma.cond_txt = hot_ad_cond
644
- await self._ad_upd_api(xma)
645
-
646
- if not sads:
647
- return
648
- sad = await sads.pop(0).to_float(ex_id=self.actor.ex_id)
649
- if curex.minimum * 20 <= sad.min_fiat < curex.minimum * 50 or sad.quantity != usdt_bal:
650
- sad.min_fiat = min(usdt_bal, curex.minimum * 10)
651
- sad.quantity = usdt_bal
652
- sad.amount = None
653
- xma = MyAdXOut.model_validate(sad, from_attributes=True)
654
- xma.cond_txt = hot_ad_cond
655
- await self._ad_upd_api(xma)
628
+ await self.ad_fresh(sads, True, usdt_bal, curex.minimum, curex.cur.rate, hot_ads_q)
629
+ return hot_ads_q
656
630
 
657
631
  # 32: Удаление
658
632
  @abstractmethod
@@ -4,7 +4,6 @@ from abc import abstractmethod
4
4
  from asyncio import sleep
5
5
  from collections import defaultdict
6
6
  from difflib import SequenceMatcher
7
- from math import floor
8
7
 
9
8
  from aiohttp import ClientSession, ClientResponse
10
9
  from msgspec import Struct
@@ -187,7 +186,6 @@ class BaseExClient(HttpClient, AdLoader):
187
186
  update=dict(
188
187
  coin_id=(await self.x2e_coin(xreq.coin_id))[0],
189
188
  cur_id=(await self.x2e_cur(xreq.cur_id))[0],
190
- is_sell=str(int(xreq.is_sell)),
191
189
  pm_ids=xreq.pm_ids and [await self.x2e_pm(pid) for pid in xreq.pm_ids],
192
190
  )
193
191
  )
@@ -471,12 +469,12 @@ class BaseExClient(HttpClient, AdLoader):
471
469
  badd = base_ad.model_dump()
472
470
  pms = await models.Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=base_ad.pmex_exids)
473
471
  badd.update(
474
- amount=int((base_ad.amount or base_ad.quantity * base_ad.price) * 10**cur_scale),
475
- max_fiat=int(base_ad.max_fiat),
476
- min_fiat=int(base_ad.min_fiat),
477
- premium=int(base_ad.premium * 100_00),
478
- price=int(base_ad.price * 10**cur_scale),
479
- quantity=int((base_ad.quantity or base_ad.amount / base_ad.price) * 10**coin_scale),
472
+ amount=round((base_ad.amount or base_ad.quantity * base_ad.price) * 10**cur_scale),
473
+ max_fiat=base_ad.max_fiat,
474
+ min_fiat=base_ad.min_fiat,
475
+ premium=round(base_ad.premium * 100_00),
476
+ price=round(base_ad.price * 10**cur_scale),
477
+ quantity=round((base_ad.quantity or base_ad.amount / base_ad.price) * 10**coin_scale),
480
478
  maker_id=(await self.e2x_actor(base_ad.maker)).id,
481
479
  cond_id=cond and cond.id,
482
480
  pair_side_id=await self.e2x_pair(base_ad.coinex_exid, base_ad.curex_exid, bool(base_ad.side.value)),
@@ -721,9 +719,25 @@ class BaseExClient(HttpClient, AdLoader):
721
719
  bc, sc = mdl + mdl * (perc / 2), mdl - mdl * (perc / 2)
722
720
  return bc, sc
723
721
 
724
- async def rate(self, cur_id: int, coin_id: int = 1) -> int:
725
- bp, sp = await self.get_books(cur_id, coin_id)
726
- return floor((sum(b.price for b in bp[5:]) + sum(s.price for s in sp[5:])) * 0.1)
722
+ async def rate(self, cur_id: int, coin_id: int = 1) -> float:
723
+ if coin_id == 1:
724
+ ofc = 4 if cur_id in (1, 2, 3) else 1
725
+ else:
726
+ ofc = 1 if cur_id in (1, 2, 3) else 0
727
+
728
+ bp, sp = await self.get_books(coin_id, cur_id)
729
+ if bp and sp:
730
+ return (sum(b.price for b in bp[ofc:]) / len(bp[ofc:]) + sum(s.price for s in sp[ofc:]) / len(bp[ofc:])) / 2
731
+ return 0
732
+
733
+ async def set_rate(self, cur_id: int, coin_id: int = 1):
734
+ cur = await models.Cur[cur_id]
735
+ rate = round(await self.rate(cur_id, coin_id), cur.scale)
736
+ if coin_id == 1:
737
+ cur.rate = rate * 10**cur.scale
738
+ await cur.save(update_fields=["rate"])
739
+ await models.Pair.filter(cur_id=cur_id, coin_id=coin_id).update(rate=rate * 10**cur.scale)
740
+ logging.warning(f"Set rate {coin_id}/{cur.ticker}: {rate}")
727
741
 
728
742
  async def init_seed(self, fbot: FileClient):
729
743
  await self.set_curs()
@@ -186,7 +186,7 @@ class AmountQuantityMixin:
186
186
 
187
187
  class MyAdXOut(AmountQuantityMixin, BaseModel):
188
188
  id: int
189
- amount: float
189
+ amount: float | None = None
190
190
  auto_msg: str | None = None
191
191
  coin_id: int = Field(validation_alias=AliasPath("pair_side", "pair", "coin_id"))
192
192
  cond_txt: str = Field(None, validation_alias=AliasPath("cond", "raw_txt"))
@@ -216,6 +216,12 @@ class MyAdXOut(AmountQuantityMixin, BaseModel):
216
216
  self.maker = None
217
217
  return self
218
218
 
219
+ @model_validator(mode="after")
220
+ def min_amount(self):
221
+ if self.amount < self.min_fiat:
222
+ self.min_fiat = int(self.amount)
223
+ return self
224
+
219
225
 
220
226
  class BaseCredexsExidsTrait:
221
227
  credex_exids: list[int]
@@ -1,7 +1,7 @@
1
1
  import asyncio
2
2
  import json
3
3
  import logging
4
- from asyncio import sleep, gather
4
+ from asyncio import sleep
5
5
  from datetime import datetime, timedelta, timezone
6
6
  from difflib import SequenceMatcher
7
7
  from hashlib import sha256
@@ -15,7 +15,6 @@ import websockets
15
15
  from aiohttp.http_exceptions import HttpProcessingError, HttpBadRequest
16
16
  from bybit_p2p import P2P
17
17
  from bybit_p2p._exceptions import FailedRequestError
18
- from payeer_api import PayeerAPI
19
18
  from pybit.unified_trading import HTTP
20
19
  from tortoise import Tortoise, get_connection
21
20
  from tortoise.timezone import now
@@ -341,6 +340,7 @@ class AgentClient(BaseAgentClient): # Bybit client
341
340
  data = self.api.update_ad(**upd.model_dump(exclude_none=True))
342
341
  if data["ret_code"]:
343
342
  raise HttpBadRequest(data)
343
+ logging.info(f"Ad:{req.exid} upd: min:{req.min_fiat}, prc:{req.price}, qty:{req.quantity}, flt:{req.filtered}")
344
344
  return not data["ret_code"]
345
345
 
346
346
  def get_security_token_update(self) -> str:
@@ -1001,7 +1001,7 @@ async def main():
1001
1001
  await Tortoise.init(db_url=PG_DSN, modules={"models": ["x_auth.models", "xync_schema.models"]})
1002
1002
 
1003
1003
  agent = (
1004
- await models.Agent.filter(actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, id=3)
1004
+ await models.Agent.filter(actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, id=1)
1005
1005
  .prefetch_related(
1006
1006
  "actor__ex",
1007
1007
  "actor__person__user",
@@ -1033,50 +1033,51 @@ async def main():
1033
1033
  # await bot.start()
1034
1034
  # await cl.ex_client.set_pms(bot)
1035
1035
  # await bot.stop()
1036
- # await cl.load_assets()
1037
- # mads = await cl.load_my_ads()
1038
- await cl.ads_fresh(1)
1036
+ await cl.load_assets()
1037
+ await cl.load_my_ads()
1038
+ r = await cl.ads_fresh(1, 1)
1039
+ print(r)
1039
1040
  # await cl.asset_save(1, b)
1040
1041
  # await cl.load_creds()
1041
1042
 
1042
- await cl.ads_share()
1043
-
1044
- ms = await models.Agent.filter(
1045
- actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, actor__person__user__id__in=[3]
1046
- ).prefetch_related(
1047
- "actor__ex",
1048
- "actor__person__user__gmail",
1049
- "actor__my_ads__my_ad__race",
1050
- "actor__my_ads__pair_side__pair__cur",
1051
- "actor__my_ads__pms",
1052
- )
1053
- {m.actor.exid: m.client(ecl) for m in ms}
1054
-
1055
- await gather(
1056
- # create_task(cl.start()),
1057
- # create_task(cl.watch_payeer(mcs, abot)),
1058
- )
1059
- # ensure_future(cl.start(True))
1060
- # await cl.boost_acc()
1061
-
1062
- # создание гонок по мои активным объявам:
1063
- # for ma in cl.my_ads():
1064
- # my_ad = await models.MyAd.get(ad__exid=ma.id).prefetch_related('ad__pms', 'ad__pair_side__pair')
1065
- # race, _ = await models.Race.update_or_create(
1066
- # {"started": True, "vm_filter": True, "target_place": 5},
1067
- # road=my_ad
1068
- # )
1069
-
1070
- # for name in names:
1071
- # s, _ = await models.Synonym.update_or_create(typ=SynonymType.name, txt=name)
1072
- # await s.curs.add(rub.cur)
1073
-
1074
- pauth = (await models.PmAgent[1]).auth
1075
- papi = PayeerAPI(pauth["email"], pauth["api_id"], pauth["api_sec"])
1076
- hist: dict = papi.history(count=1000)
1077
- hist |= papi.history(count=1000, append=list(hist.keys())[-1])
1078
- hist |= papi.history(count=1000, append=list(hist.keys())[-1])
1079
- cl.hist = hist
1043
+ # await cl.ads_share()
1044
+ #
1045
+ # ms = await models.Agent.filter(
1046
+ # actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, actor__person__user__id__in=[3]
1047
+ # ).prefetch_related(
1048
+ # "actor__ex",
1049
+ # "actor__person__user__gmail",
1050
+ # "actor__my_ads__my_ad__race",
1051
+ # "actor__my_ads__pair_side__pair__cur",
1052
+ # "actor__my_ads__pms",
1053
+ # )
1054
+ # {m.actor.exid: m.client(ecl) for m in ms}
1055
+ #
1056
+ # await gather(
1057
+ # # create_task(cl.start()),
1058
+ # # create_task(cl.watch_payeer(mcs, abot)),
1059
+ # )
1060
+ # # ensure_future(cl.start(True))
1061
+ # # await cl.boost_acc()
1062
+ #
1063
+ # # создание гонок по мои активным объявам:
1064
+ # # for ma in cl.my_ads():
1065
+ # # my_ad = await models.MyAd.get(ad__exid=ma.id).prefetch_related('ad__pms', 'ad__pair_side__pair')
1066
+ # # race, _ = await models.Race.update_or_create(
1067
+ # # {"started": True, "vm_filter": True, "target_place": 5},
1068
+ # # road=my_ad
1069
+ # # )
1070
+ #
1071
+ # # for name in names:
1072
+ # # s, _ = await models.Synonym.update_or_create(typ=SynonymType.name, txt=name)
1073
+ # # await s.curs.add(rub.cur)
1074
+ #
1075
+ # pauth = (await models.PmAgent[1]).auth
1076
+ # papi = PayeerAPI(pauth["email"], pauth["api_id"], pauth["api_sec"])
1077
+ # hist: dict = papi.history(count=1000)
1078
+ # hist |= papi.history(count=1000, append=list(hist.keys())[-1])
1079
+ # hist |= papi.history(count=1000, append=list(hist.keys())[-1])
1080
+ # cl.hist = hist
1080
1081
 
1081
1082
  # cl.completed_orders = await models.Order.filter(status=OrderStatus.completed, transfer__isnull=False).values_list(
1082
1083
  # "exid", flat=True
@@ -19,13 +19,15 @@ class AdStatusReq(StrEnum):
19
19
 
20
20
  IntStr = Annotated[str, BeforeValidator(str)]
21
21
  Dec2Str = Annotated[str, BeforeValidator(lambda v: f"{round(v, 2):g}")]
22
+ Dec4Str = Annotated[str, BeforeValidator(lambda v: f"{round(v - 0.00049, 4):g}")]
22
23
  NoneStr = Annotated[str, BeforeValidator(lambda v: f"{v or ''}")]
24
+ BoolIntStr = Annotated[Literal["0", "1"], BeforeValidator(lambda v: str(int(v)))]
23
25
 
24
26
 
25
27
  class AdsReq(BaseModel):
26
28
  tokenId: str = Field(validation_alias="coin_id")
27
29
  currencyId: str = Field(validation_alias="cur_id")
28
- side: Literal["0", "1"] = Field(validation_alias="is_sell") # 0 покупка, # 1 продажа
30
+ side: BoolIntStr = Field(validation_alias="is_sell") # 0 покупка, # 1 продажа
29
31
  payment: list[str] = Field([], validation_alias="pm_ids") # int
30
32
  size: str = Field("20", validation_alias="limit", coerce_numbers_to_str=True) # int
31
33
  page: IntStr = "1" # int
@@ -120,7 +122,7 @@ class _MyAdEIn(RemapBase):
120
122
  remark: NoneStr = Field("", validation_alias=AliasChoices("cond_txt", AliasPath("cond", "raw_txt")))
121
123
  tradingPreferenceSet: TradingPreferenceSet = TradingPreferenceSet()
122
124
  paymentIds: list[IntStr]
123
- quantity: Dec2Str # float
125
+ quantity: Dec4Str # float
124
126
  paymentPeriod: int = 15
125
127
 
126
128
  @model_validator(mode="before")
@@ -140,6 +142,7 @@ class _MyAdEIn(RemapBase):
140
142
  orderFinishNumberDay30=5,
141
143
  registerTimeThreshold=15,
142
144
  )
145
+ # out['quantity'] = f"{round(data.quantity-0.5*10**-data._coin_scale, data._coin_scale):g}"
143
146
  return out
144
147
 
145
148
 
@@ -228,7 +231,12 @@ class Ad(BaseAd, RemapBase):
228
231
 
229
232
  @model_validator(mode="after")
230
233
  def set_filtered_flag(self):
231
- self.filtered = bool(self.tradingPreferenceSet.completeRateDay30 or self.tradingPreferenceSet.hasRegisterTime)
234
+ self.filtered = bool(
235
+ self.tradingPreferenceSet
236
+ and self.tradingPreferenceSet.hasCompleteRateDay30
237
+ and self.tradingPreferenceSet.hasRegisterTime
238
+ and self.tradingPreferenceSet.hasOrderFinishNumberDay30
239
+ )
232
240
  return self
233
241
 
234
242
 
@@ -124,6 +124,66 @@ class ExClient(BaseExClient): # Bybit client
124
124
  return ads
125
125
 
126
126
 
127
+ curs = (
128
+ 1,
129
+ 2,
130
+ 3,
131
+ 4,
132
+ 6,
133
+ 8,
134
+ 9,
135
+ 10,
136
+ 11,
137
+ 12,
138
+ 13,
139
+ 14,
140
+ 15,
141
+ 17,
142
+ 18,
143
+ 19,
144
+ 20,
145
+ 21,
146
+ 22,
147
+ 28,
148
+ 29,
149
+ 30,
150
+ 33,
151
+ 36,
152
+ 37,
153
+ 40,
154
+ 41,
155
+ 43,
156
+ 44,
157
+ 47,
158
+ 50,
159
+ 51,
160
+ 52,
161
+ 56,
162
+ 59,
163
+ 65,
164
+ 66,
165
+ 68,
166
+ 69,
167
+ 73,
168
+ 74,
169
+ 77,
170
+ 78,
171
+ 80,
172
+ 81,
173
+ 82,
174
+ 85,
175
+ 88,
176
+ 91,
177
+ 101,
178
+ 103,
179
+ 107,
180
+ 111,
181
+ 112,
182
+ 113,
183
+ 119,
184
+ )
185
+
186
+
127
187
  async def main():
128
188
  _ = await init_db(TORM, True)
129
189
  ex = await Ex.get(name="Bybit")
@@ -131,8 +191,10 @@ async def main():
131
191
  # await bot.start()
132
192
  prx = PRX and "http://" + PRX
133
193
  cl: ExClient = ex.client(proxy=prx)
134
- await cl.set_coins(False)
135
- await cl.rate(1)
194
+ # await cl.set_coins(False)
195
+ for cur in curs:
196
+ for coin in (1, 2, 3, 4):
197
+ await cl.set_rate(cur, coin)
136
198
  # await cl.set_curs()
137
199
  await cl.set_pms(bot)
138
200
  await cl.set_pairs()
@@ -27,6 +27,10 @@ hot_ad_cond = "Банков НЕТ! Только XyncPay: @ex212 \n --- \n К
27
27
  hot_ad_auto_msg = "Банков нет. Только XyncPay. Читайте условия! Отменяйте, если у вас нет XyncPay"
28
28
 
29
29
 
30
+ def more1perc(a: float, b: float):
31
+ return abs(a - b) / a > 0.01
32
+
33
+
30
34
  async def search_messages(phrases_to_find) -> List[Dict[str, str]]:
31
35
  _ = await init_db(TORM, True)
32
36
  msgs = await models.Msg.all().values("txt")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.235.dev3
3
+ Version: 0.0.236.dev1
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client