xync-client 0.0.57.dev23__tar.gz → 0.0.57.dev25__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 (112) hide show
  1. {xync_client-0.0.57.dev23/xync_client.egg-info → xync_client-0.0.57.dev25}/PKG-INFO +1 -1
  2. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/agent.py +147 -52
  3. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25/xync_client.egg-info}/PKG-INFO +1 -1
  4. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/.env.sample +0 -0
  5. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/.gitignore +0 -0
  6. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/.pre-commit-config.yaml +0 -0
  7. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/README.md +0 -0
  8. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/makefile +0 -0
  9. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/pyproject.toml +0 -0
  10. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/setup.cfg +0 -0
  11. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/TestAgent.py +0 -0
  12. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/TestAsset.py +0 -0
  13. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/TestEx.py +0 -0
  14. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/TestOrder.py +0 -0
  15. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Binance/test_binance.py +0 -0
  16. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  17. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  18. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Gate/test_gate.py +0 -0
  19. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
  20. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  21. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  22. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/__init__.py +0 -0
  23. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/tests/_todo_refact/_test_ex.py +0 -0
  24. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/Agent.py +0 -0
  25. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/Asset.py +0 -0
  26. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/Auth.py +0 -0
  27. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/BaseTest.py +0 -0
  28. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/Ex.py +0 -0
  29. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/InAgent.py +0 -0
  30. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/Order.py +0 -0
  31. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Abc/xtype.py +0 -0
  32. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/__init__.py +0 -0
  33. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/binance_async.py +0 -0
  34. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/earn_api.py +0 -0
  35. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/etype/ad.py +0 -0
  36. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/etype/pm.py +0 -0
  37. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/ex.py +0 -0
  38. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/exceptions.py +0 -0
  39. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/sapi.py +0 -0
  40. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Binance/web_c2c.py +0 -0
  41. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/__init__.py +0 -0
  42. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/agent.py +0 -0
  43. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/base.py +0 -0
  44. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/etype/ad.py +0 -0
  45. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/etype/pm.py +0 -0
  46. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/ex.py +0 -0
  47. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/req.mjs +0 -0
  48. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BingX/sign.js +0 -0
  49. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BitGet/__init__.py +0 -0
  50. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BitGet/agent.py +0 -0
  51. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BitGet/etype/ad.py +0 -0
  52. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BitGet/ex.py +0 -0
  53. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/BitPapa/ex.py +0 -0
  54. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/InAgent.py +0 -0
  55. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/etype/ad.py +0 -0
  56. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/etype/cred.py +0 -0
  57. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/etype/order.py +0 -0
  58. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/ex.py +0 -0
  59. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/order.py +0 -0
  60. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/web_earn.py +0 -0
  61. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/web_p2p.py +0 -0
  62. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Bybit/ws.py +0 -0
  63. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Gate/etype/ad.py +0 -0
  64. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Gate/ex.py +0 -0
  65. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Gate/premarket.py +0 -0
  66. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Gmail/__init__.py +0 -0
  67. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/agent.py +0 -0
  68. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/earn.py +0 -0
  69. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/etype/__init__.py +0 -0
  70. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/etype/ad.py +0 -0
  71. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/etype/cred.py +0 -0
  72. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/etype/pm.py +0 -0
  73. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/etype/test.py +0 -0
  74. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Htx/ex.py +0 -0
  75. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/KuCoin/etype/ad.py +0 -0
  76. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/KuCoin/etype/pm.py +0 -0
  77. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/KuCoin/ex.py +0 -0
  78. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/KuCoin/web.py +0 -0
  79. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Mexc/etype/ad.py +0 -0
  80. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Mexc/etype/pm.py +0 -0
  81. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Mexc/ex.py +0 -0
  82. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Okx/etype/ad.py +0 -0
  83. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Okx/etype/pm.py +0 -0
  84. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Okx/ex.py +0 -0
  85. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/.gitignore +0 -0
  86. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Alfa/__init__.py +0 -0
  87. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Alfa/state.json +0 -0
  88. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Ozon/__init__.py +0 -0
  89. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Sber/__init__.py +0 -0
  90. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  91. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Tinkoff/state.json +0 -0
  92. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Volet/__init__.py +0 -0
  93. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  94. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  95. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Volet/api.py +0 -0
  96. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/Pms/Volet/pl.py +0 -0
  97. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/agent.py +0 -0
  98. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/asset.py +0 -0
  99. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/auth.py +0 -0
  100. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/ex.py +0 -0
  101. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/inAgent.py +0 -0
  102. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/order.py +0 -0
  103. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/pyd.py +0 -0
  104. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/pyro.py +0 -0
  105. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/TgWallet/web.py +0 -0
  106. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/__init__.py +0 -0
  107. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/loader.py +0 -0
  108. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client/pm_unifier.py +0 -0
  109. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client.egg-info/SOURCES.txt +0 -0
  110. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client.egg-info/dependency_links.txt +0 -0
  111. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/xync_client.egg-info/requires.txt +0 -0
  112. {xync_client-0.0.57.dev23 → xync_client-0.0.57.dev25}/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.57.dev23
3
+ Version: 0.0.57.dev25
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
@@ -79,9 +79,10 @@ class AgentClient(BaseAgentClient): # Bybit client
79
79
  "actionType": "MODIFY",
80
80
  "securityRiskToken": "",
81
81
  }
82
- all_conds: dict[int, tuple[str, set[str]]] = {}
83
- cond_sims: dict[int, tuple[int, int]] = {}
84
- sim_conds: dict[int, set[int]] = defaultdict(set) # backward
82
+ all_conds: dict[int, tuple[str, set[int]]] = {}
83
+ cond_sims: dict[int, int] = defaultdict(set)
84
+ rcond_sims: dict[int, set[int]] = defaultdict(set) # backward
85
+ tree: dict = {}
85
86
 
86
87
  def __init__(self, actor: Actor, bot: FileClient, **kwargs):
87
88
  super().__init__(actor, bot, **kwargs)
@@ -395,7 +396,7 @@ class AgentClient(BaseAgentClient): # Bybit client
395
396
  size=30,
396
397
  # status=status, # 50 - завершено
397
398
  # tokenId=token_id,
398
- # beginTime=begin_time,
399
+ beginTime=begin_time,
399
400
  # endTime=end_time,
400
401
  # side=side, # 1 - продажа, 0 - покупка
401
402
  )
@@ -713,7 +714,8 @@ class AgentClient(BaseAgentClient): # Bybit client
713
714
  if rest_uids := {ra.maker_id for ra in rest_ads} - {ad_db.maker_id}:
714
715
  # создадим новое условие и присвоим его только текущей объяве
715
716
  new_cond = await Cond.create(raw_txt=cleaned)
716
- await self.sim_new(new_cond.id, get_sim(cleaned, ad_db.cond.raw_txt), ad_db.cond_id)
717
+ if sim := get_sim(cleaned, ad_db.cond.raw_txt):
718
+ await CondSim.create(cond_id=new_cond.id, similarity=sim, cond_rel_id=ad_db.cond_id)
717
719
  ad_db.cond_id = new_cond.id
718
720
  self.all_conds[ad_db.cond_id] = cleaned, {ad_db.maker.exid}
719
721
  await ad_db.save()
@@ -729,36 +731,71 @@ class AgentClient(BaseAgentClient): # Bybit client
729
731
  ad_db.cond.raw_txt = cleaned
730
732
  self.all_conds[ad_db.cond_id] = cleaned, {ad_db.maker.exid}
731
733
  await ad_db.cond.save()
732
- await self.sim_upd(ad_db.cond_id, cleaned)
734
+ await self.sim_check_rels(ad_db.cond_id, cleaned)
733
735
  return ad_db, False
734
736
 
735
- # находим все старые тексты похожие на 90% и более
736
- if _sims := {
737
- old_cid: (txt, sim)
738
- for old_cid, (txt, uids) in self.all_conds.items()
739
- if len(cleaned) > 15 and ad.userId not in uids and (sim := get_sim(cleaned, txt))
740
- }:
741
- # если есть, берем самый похожий из них
742
- old_cid, (txt, sim) = max(_sims.items(), key=lambda x: x[1][1])
743
- old_ads = await models.Ad.filter(cond_id=old_cid, maker__exid=int(ad.userId)).prefetch_related("cond")
744
- for old_ad in old_ads:
745
- # и у этого чела есть объява с почти таким же текстом
746
- if old_ad.exid == int(ad.id): # и он изменил текст как раз в ней
747
- # заменяем текст без создания нового cond
748
- await old_ad.cond.update_or_create(raw_txt=cleaned)
749
- await old_ad.fetch_related("cond")
750
- return old_ad, False
751
- # но это не она, значит у него есть другая объява с похожим, но чуть отличающимся текстом
752
- logging.warning(f"ad#{ad.id}-cond#{old_cid} txt updated:\n{txt}\n|\nV\n{cleaned}")
753
-
754
737
  new_cond = await Cond.create(raw_txt=cleaned)
755
- self.all_conds[new_cond.id] = new_cond.raw_txt, {ad.userId}
738
+ # находим все старые тексты похожие на 90% и более
739
+ old_cid, sim = await self.cond_get_max_sim(new_cond.id, new_cond.raw_txt, {int(ad.userId)})
740
+ # old_ads = await models.Ad.filter(cond_id=old_cid, maker__exid=int(ad.userId)).prefetch_related("cond")
741
+ # for old_ad in old_ads:
742
+ # # и у этого чела есть объява с почти таким же текстом
743
+ # if old_ad.exid == int(ad.id): # и он изменил текст как раз в ней
744
+ # # заменяем текст без создания нового cond
745
+ # await old_ad.cond.update_or_create(raw_txt=cleaned)
746
+ # await old_ad.fetch_related("cond")
747
+ # return old_ad, False
748
+ # # но это не она, значит у него есть другая объява с похожим, но чуть отличающимся текстом
749
+ # logging.warning(f"ad#{ad.id}-cond#{old_cid} txt updated:\n{txt}\n|\nV\n{cleaned}")
750
+
751
+ self.all_conds[new_cond.id] = new_cond.raw_txt, {int(ad.userId)}
756
752
  # если нашелся похожий текст у другого юзера, добавим связь с % похожести
757
753
  if sim:
758
- await self.sim_new(new_cond.id, sim, old_cid)
754
+ await CondSim.create(cond_id=new_cond.id, similarity=sim, cond_rel_id=old_cid)
759
755
 
760
756
  return await self.ad_create(ad, new_cond.id), True
761
757
 
758
+ def find_in_tree(self, cid: int, old_cid: int) -> bool:
759
+ if p := self.cond_sims.get(old_cid):
760
+ if p == cid:
761
+ return True
762
+ return self.find_in_tree(cid, p)
763
+ return False
764
+
765
+ async def cond_get_max_sim(self, cid: int, txt: str, uids: set[int]) -> tuple[int | None, int | None]:
766
+ # находим все старые тексты похожие на 90% и более
767
+ if len(txt) < 15:
768
+ return None, None
769
+ sims: dict[int, int] = {}
770
+ for old_cid, (old_txt, old_uids) in self.all_conds.items():
771
+ if len(old_txt) < 15 or uids == old_uids:
772
+ continue
773
+ elif not self.can_add_sim(cid, old_cid):
774
+ continue
775
+ if sim := get_sim(txt, old_txt):
776
+ sims[old_cid] = sim
777
+ # если есть, берем самый похожий из них
778
+ if sims:
779
+ old_cid, sim = max(sims.items(), key=lambda x: x[1])
780
+ await sleep(0.3)
781
+ return old_cid, sim
782
+ return None, None
783
+
784
+ def can_add_sim(self, cid: int, old_cid: int) -> bool:
785
+ if cid == old_cid:
786
+ return False
787
+ elif self.cond_sims.get(cid) == old_cid:
788
+ return False
789
+ elif self.find_in_tree(cid, old_cid):
790
+ return False
791
+ elif self.cond_sims.get(old_cid) == cid:
792
+ return False
793
+ elif cid in self.rcond_sims.get(old_cid, {}):
794
+ return False
795
+ elif old_cid in self.rcond_sims.get(cid, {}):
796
+ return False
797
+ return True
798
+
762
799
  async def person_upsert(self, name: str, exid: int) -> models.Person:
763
800
  if actor := await models.Actor.get_or_none(exid=exid, ex=self.ex_client.ex).prefetch_related("person"):
764
801
  if not actor.person:
@@ -793,29 +830,75 @@ class AgentClient(BaseAgentClient): # Bybit client
793
830
  await ad_db.pms.add(*(await models.Pm.filter(pmexs__ex=self.ex_client.ex, pmexs__exid__in=ad.payments)))
794
831
  return ad_db
795
832
 
796
- async def sim_new(self, new_cid: int, sim: int, old_cid: int):
797
- if not sim:
798
- return None
799
- return await CondSim.create(cond_id=new_cid, similarity=sim, cond_rel_id=old_cid)
800
-
801
- async def sim_upd(self, cid: int, new_txt: int):
802
- for sim_db in (_sims := await CondSim.filter(Q(join_type="OR", cond_id=cid, cond_rel_id=cid))):
803
- (op,) = {sim_db.cond_id, sim_db.cond_rel_id} - {cid}
804
- op_cond = await Cond[op]
805
- sim_db.similarity = get_sim(new_txt, op_cond.raw_txt)
806
- await sim_db.save()
833
+ async def sim_check_rels(self, cid: int, new_txt: int):
834
+ if _old_sims := await CondSim.filter(Q(join_type="OR", cond_id=cid, cond_rel_id=cid)):
835
+ for sim_db in _old_sims:
836
+ (op,) = {sim_db.cond_id, sim_db.cond_rel_id} - {cid}
837
+ op_cond = await Cond[op]
838
+ sim_db.similarity = get_sim(new_txt, op_cond.raw_txt)
839
+ await sim_db.save()
840
+
841
+ def build_tree(self):
842
+ set(self.cond_sims.keys()) | set(self.cond_sims.values())
843
+ tree = defaultdict(dict)
844
+ # Группируем родителей по детям
845
+ for child, par in self.cond_sims.items():
846
+ tree[par] |= {child: {}} # todo: make from self.rcond_sim
847
+
848
+ # Строим дерево снизу вверх
849
+ def subtree(node):
850
+ if not node:
851
+ return node
852
+ for key in node:
853
+ subnode = tree.pop(key, {})
854
+ d = subtree(subnode)
855
+ node[key] |= d # actual tree rebuilding here!
856
+ return node # todo: refact?
857
+
858
+ # Находим корни / без родителей
859
+ roots = set(self.cond_sims.values()) - set(self.cond_sims.keys())
860
+ for root in roots:
861
+ _ = subtree(tree[root])
862
+
863
+ self.tree = tree
807
864
 
808
865
  async def actual_cond(self):
809
- self.all_conds = {
810
- c.id: (c.raw_txt, {str(a.maker.exid) for a in c.ads})
811
- for c in await Cond.all().prefetch_related("ads__maker")
812
- }
813
- self.cond_sims = {cs.cond_id: (cs.cond_rel_id, cs.similarity) for cs in await CondSim.all()}
814
- for c, (o, s) in self.cond_sims.items():
815
- self.sim_conds[o].add(c)
816
- for ad_db in await models.Ad.filter(direction__pairex__ex=self.ex_client.ex).prefetch_related("cond", "maker"):
817
- ad = Ad(id=str(ad_db.exid), userId=str(ad_db.maker.exid), remark=ad_db.cond.raw_txt)
818
- await self.cond_upsert(ad, force=True)
866
+ for curr, old in await CondSim.all().values_list("cond_id", "cond_rel_id"):
867
+ self.cond_sims[curr] = old
868
+ self.rcond_sims[old] |= {curr}
869
+ self.build_tree()
870
+ for cid, (txt, uids) in self.all_conds.items():
871
+ old_cid, sim = await self.cond_get_max_sim(cid, txt, uids)
872
+ if sim:
873
+ if old_sim := await CondSim.get_or_none(cond_id=cid):
874
+ if old_sim.cond_rel_id != old_cid:
875
+ if sim <= old_sim.similarity:
876
+ # old_rsim = await CondSim.get_or_none(cond_id=old_cid)
877
+ # if not old_rsim:
878
+ # await CondSim.create(cond_id=old_cid, cond_rel_id=cid, similarity=sim)
879
+ # self.cond_sims[old_cid] = cid
880
+ # self.rcond_sims[cid] |= {old_cid}
881
+ # # self.add_to_tree(old_cid, cid, self.tree)
882
+ # elif old_rsim.similarity < sim:
883
+ # await CondSim.update_or_create({"cond_rel_id": cid, "similarity": sim}, cond_id=old_cid)
884
+ # self.cond_sims[old_cid] = cid
885
+ # self.rcond_sims[cid] |= {old_cid}
886
+ # self.rcond_sims[old_rsim.cond_rel_id].remove(old_rsim.cond_id)
887
+ # logging.warning(f'{old_cid}: {old_sim.similarity}->{sim} ({old_sim.cond_rel_id}->{cid})')
888
+ continue
889
+ logging.warning(f"R {cid}: {old_sim.similarity}->{sim} ({old_sim.cond_rel_id}->{old_cid})")
890
+ await old_sim.update_from_dict({"similarity": sim, "old_rel_id": old_cid}).save()
891
+ elif sim != old_sim.similarity:
892
+ logging.info(f"{cid}: {old_sim.similarity}->{sim}")
893
+ await old_sim.update_from_dict({"similarity": sim}).save()
894
+ else:
895
+ await CondSim.create(cond_id=cid, cond_rel_id=old_cid, similarity=sim)
896
+ self.cond_sims[cid] = old_cid
897
+ self.rcond_sims[old_cid] |= {cid}
898
+ # self.add_to_tree(cid, old_cid, self.tree)
899
+ # for ad_db in await models.Ad.filter(direction__pairex__ex=self.ex_client.ex).prefetch_related("cond", "maker"):
900
+ # ad = Ad(id=str(ad_db.exid), userId=str(ad_db.maker.exid), remark=ad_db.cond.raw_txt)
901
+ # await self.cond_upsert(ad, force=True)
819
902
 
820
903
  async def get_credexs_by_norms(self, norms: list[str], cur_id: int) -> dict[models.Pmex, models.CredEx] | None:
821
904
  try:
@@ -833,7 +916,7 @@ class AgentClient(BaseAgentClient): # Bybit client
833
916
 
834
917
 
835
918
  def get_sim(s1, s2) -> int:
836
- sim = int((SequenceMatcher(None, s1, s2).ratio() - 0.9) * 10_000)
919
+ sim = int((SequenceMatcher(None, s1, s2).ratio() - 0.6) * 10_000)
837
920
  return sim if sim > 0 else 0
838
921
 
839
922
 
@@ -901,12 +984,24 @@ async def main():
901
984
  usdc = await models.Coinex.get(coin__ticker="USDC", ex=cl.actor.ex).prefetch_related("coin")
902
985
  rub = await models.Curex.get(cur__ticker="RUB", ex=cl.actor.ex).prefetch_related("cur")
903
986
  cl.all_conds = {
904
- c.id: (c.raw_txt, {str(a.maker.exid) for a in c.ads})
905
- for c in await Cond.all().prefetch_related("ads__maker")
987
+ c.id: (c.raw_txt, {a.maker.exid for a in c.ads}) for c in await Cond.all().prefetch_related("ads__maker")
906
988
  }
989
+ for curr, old in await CondSim.filter().values_list("cond_id", "cond_rel_id"):
990
+ cl.cond_sims[curr] = old
991
+ cl.rcond_sims[old] |= {curr}
992
+ cl.build_tree()
993
+ a = set()
994
+
995
+ def check_tree(tre):
996
+ for p, c in tre.items():
997
+ a.add(p)
998
+ check_tree(c)
999
+
1000
+ for pr, ch in cl.tree.items():
1001
+ check_tree(ch)
907
1002
  # await cl.actual_cond()
908
1003
  await gather(
909
- cl.get_api_orders(20), # 10, 1738357200000, 1742504399999
1004
+ cl.get_api_orders(1, 1742504400000), # 10, 1738357200000, 1742504399999
910
1005
  cl.battle(usdt, rub, False, ["volet"], 79.8), # гонка в стакане покупки - мы продаем
911
1006
  cl.battle(usdt, rub, True, ["volet"], 79.8), # гонка в стакане продажи - мы покупаем
912
1007
  cl.battle(eth, rub, False, ["volet"], 206_000),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.57.dev23
3
+ Version: 0.0.57.dev25
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