xync-client 0.0.57.dev22__tar.gz → 0.0.57.dev24__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.dev22/xync_client.egg-info → xync_client-0.0.57.dev24}/PKG-INFO +1 -1
  2. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/agent.py +181 -86
  3. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24/xync_client.egg-info}/PKG-INFO +1 -1
  4. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/.env.sample +0 -0
  5. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/.gitignore +0 -0
  6. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/.pre-commit-config.yaml +0 -0
  7. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/README.md +0 -0
  8. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/makefile +0 -0
  9. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/pyproject.toml +0 -0
  10. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/setup.cfg +0 -0
  11. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/TestAgent.py +0 -0
  12. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/TestAsset.py +0 -0
  13. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/TestEx.py +0 -0
  14. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/TestOrder.py +0 -0
  15. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Binance/test_binance.py +0 -0
  16. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  17. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  18. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Gate/test_gate.py +0 -0
  19. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
  20. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  21. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  22. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/__init__.py +0 -0
  23. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/tests/_todo_refact/_test_ex.py +0 -0
  24. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/Agent.py +0 -0
  25. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/Asset.py +0 -0
  26. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/Auth.py +0 -0
  27. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/BaseTest.py +0 -0
  28. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/Ex.py +0 -0
  29. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/InAgent.py +0 -0
  30. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/Order.py +0 -0
  31. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Abc/xtype.py +0 -0
  32. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/__init__.py +0 -0
  33. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/binance_async.py +0 -0
  34. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/earn_api.py +0 -0
  35. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/etype/ad.py +0 -0
  36. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/etype/pm.py +0 -0
  37. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/ex.py +0 -0
  38. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/exceptions.py +0 -0
  39. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/sapi.py +0 -0
  40. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Binance/web_c2c.py +0 -0
  41. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/__init__.py +0 -0
  42. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/agent.py +0 -0
  43. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/base.py +0 -0
  44. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/etype/ad.py +0 -0
  45. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/etype/pm.py +0 -0
  46. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/ex.py +0 -0
  47. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/req.mjs +0 -0
  48. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BingX/sign.js +0 -0
  49. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BitGet/__init__.py +0 -0
  50. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BitGet/agent.py +0 -0
  51. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BitGet/etype/ad.py +0 -0
  52. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BitGet/ex.py +0 -0
  53. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/BitPapa/ex.py +0 -0
  54. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/InAgent.py +0 -0
  55. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/etype/ad.py +0 -0
  56. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/etype/cred.py +0 -0
  57. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/etype/order.py +0 -0
  58. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/ex.py +0 -0
  59. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/order.py +0 -0
  60. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/web_earn.py +0 -0
  61. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/web_p2p.py +0 -0
  62. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Bybit/ws.py +0 -0
  63. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Gate/etype/ad.py +0 -0
  64. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Gate/ex.py +0 -0
  65. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Gate/premarket.py +0 -0
  66. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Gmail/__init__.py +0 -0
  67. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/agent.py +0 -0
  68. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/earn.py +0 -0
  69. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/etype/__init__.py +0 -0
  70. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/etype/ad.py +0 -0
  71. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/etype/cred.py +0 -0
  72. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/etype/pm.py +0 -0
  73. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/etype/test.py +0 -0
  74. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Htx/ex.py +0 -0
  75. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/KuCoin/etype/ad.py +0 -0
  76. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/KuCoin/etype/pm.py +0 -0
  77. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/KuCoin/ex.py +0 -0
  78. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/KuCoin/web.py +0 -0
  79. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Mexc/etype/ad.py +0 -0
  80. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Mexc/etype/pm.py +0 -0
  81. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Mexc/ex.py +0 -0
  82. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Okx/etype/ad.py +0 -0
  83. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Okx/etype/pm.py +0 -0
  84. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Okx/ex.py +0 -0
  85. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/.gitignore +0 -0
  86. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Alfa/__init__.py +0 -0
  87. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Alfa/state.json +0 -0
  88. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Ozon/__init__.py +0 -0
  89. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Sber/__init__.py +0 -0
  90. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  91. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Tinkoff/state.json +0 -0
  92. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Volet/__init__.py +0 -0
  93. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  94. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  95. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Volet/api.py +0 -0
  96. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/Pms/Volet/pl.py +0 -0
  97. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/agent.py +0 -0
  98. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/asset.py +0 -0
  99. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/auth.py +0 -0
  100. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/ex.py +0 -0
  101. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/inAgent.py +0 -0
  102. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/order.py +0 -0
  103. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/pyd.py +0 -0
  104. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/pyro.py +0 -0
  105. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/TgWallet/web.py +0 -0
  106. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/__init__.py +0 -0
  107. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/loader.py +0 -0
  108. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client/pm_unifier.py +0 -0
  109. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client.egg-info/SOURCES.txt +0 -0
  110. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client.egg-info/dependency_links.txt +0 -0
  111. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/xync_client.egg-info/requires.txt +0 -0
  112. {xync_client-0.0.57.dev22 → xync_client-0.0.57.dev24}/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.dev22
3
+ Version: 0.0.57.dev24
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)
@@ -444,13 +445,15 @@ class AgentClient(BaseAgentClient): # Bybit client
444
445
  )
445
446
  ):
446
447
  extr = ", ".join(
447
- [
448
+ x
449
+ for xtr in [
448
450
  ecredex.bankName,
449
451
  ecredex.branchName,
450
452
  ecredex.qrcode,
451
453
  ecredex.payMessage,
452
454
  ecredex.paymentExt1,
453
455
  ]
456
+ if (x := xtr.strip())
454
457
  )
455
458
  crd = await models.Cred.create(
456
459
  detail=ecredex.accountNo,
@@ -476,9 +479,9 @@ class AgentClient(BaseAgentClient): # Bybit client
476
479
  "appealed_at": o.status == 30 and int(order.updateDate[:-3]) or None,
477
480
  "cred_id": ecredex.paymentType and credex.cred_id or None,
478
481
  "taker": taker,
482
+ "ad": ad_db,
479
483
  },
480
484
  exid=o.id,
481
- ad=ad_db,
482
485
  )
483
486
  dmsgs = self.api.get_chat_messages(orderId=oid, size=200)["result"]["result"][::-1]
484
487
  msgs = [Message.model_validate(m) for m in dmsgs if m["msgType"] in (1, 2, 7, 8)]
@@ -727,36 +730,62 @@ class AgentClient(BaseAgentClient): # Bybit client
727
730
  ad_db.cond.raw_txt = cleaned
728
731
  self.all_conds[ad_db.cond_id] = cleaned, {ad_db.maker.exid}
729
732
  await ad_db.cond.save()
730
- await self.sim_upd(ad_db.cond_id, cleaned)
733
+ await self.sim_check_rels(ad_db.cond_id, cleaned)
731
734
  return ad_db, False
732
735
 
733
- # находим все старые тексты похожие на 90% и более
734
- if _sims := {
735
- old_cid: (txt, sim)
736
- for old_cid, (txt, uids) in self.all_conds.items()
737
- if len(cleaned) > 15 and ad.userId not in uids and (sim := get_sim(cleaned, txt))
738
- }:
739
- # если есть, берем самый похожий из них
740
- old_cid, (txt, sim) = max(_sims.items(), key=lambda x: x[1][1])
741
- old_ads = await models.Ad.filter(cond_id=old_cid, maker__exid=int(ad.userId)).prefetch_related("cond")
742
- for old_ad in old_ads:
743
- # и у этого чела есть объява с почти таким же текстом
744
- if old_ad.exid == int(ad.id): # и он изменил текст как раз в ней
745
- # заменяем текст без создания нового cond
746
- await old_ad.cond.update_or_create(raw_txt=cleaned)
747
- await old_ad.fetch_related("cond")
748
- return old_ad, False
749
- # но это не она, значит у него есть другая объява с похожим, но чуть отличающимся текстом
750
- logging.warning(f"ad#{ad.id}-cond#{old_cid} txt updated:\n{txt}\n|\nV\n{cleaned}")
751
-
752
736
  new_cond = await Cond.create(raw_txt=cleaned)
753
- self.all_conds[new_cond.id] = new_cond.raw_txt, {ad.userId}
737
+ # находим все старые тексты похожие на 90% и более
738
+ old_cid, sim = await self.cond_get_max_sim(new_cond.id, new_cond.raw_txt, {int(ad.userId)})
739
+ # old_ads = await models.Ad.filter(cond_id=old_cid, maker__exid=int(ad.userId)).prefetch_related("cond")
740
+ # for old_ad in old_ads:
741
+ # # и у этого чела есть объява с почти таким же текстом
742
+ # if old_ad.exid == int(ad.id): # и он изменил текст как раз в ней
743
+ # # заменяем текст без создания нового cond
744
+ # await old_ad.cond.update_or_create(raw_txt=cleaned)
745
+ # await old_ad.fetch_related("cond")
746
+ # return old_ad, False
747
+ # # но это не она, значит у него есть другая объява с похожим, но чуть отличающимся текстом
748
+ # logging.warning(f"ad#{ad.id}-cond#{old_cid} txt updated:\n{txt}\n|\nV\n{cleaned}")
749
+
750
+ self.all_conds[new_cond.id] = new_cond.raw_txt, {int(ad.userId)}
754
751
  # если нашелся похожий текст у другого юзера, добавим связь с % похожести
755
752
  if sim:
756
- await self.sim_new(new_cond.id, sim, old_cid)
753
+ await CondSim.create(cond_id=new_cond.id, similarity=sim, cond_rel_id=old_cid)
757
754
 
758
755
  return await self.ad_create(ad, new_cond.id), True
759
756
 
757
+ def find_in_tree(self, cid: int, old_cid: int) -> bool:
758
+ if p := self.cond_sims.get(old_cid):
759
+ if p == cid:
760
+ return True
761
+ return self.find_in_tree(cid, p)
762
+ return False
763
+
764
+ async def cond_get_max_sim(self, cid: int, txt: str, uids: set[int]) -> tuple[int | None, int | None]:
765
+ # находим все старые тексты похожие на 90% и более
766
+ sims: dict[int, int] = {}
767
+ for old_cid, (old_txt, old_uids) in self.all_conds.items():
768
+ if len(old_txt) < 15 or cid == old_cid or uids == old_uids:
769
+ continue
770
+ elif self.cond_sims.get(cid) == old_cid:
771
+ continue
772
+ elif self.cond_sims.get(old_cid) == cid:
773
+ continue
774
+ elif cid in self.rcond_sims.get(old_cid, {}):
775
+ continue
776
+ elif old_cid in self.rcond_sims.get(cid, {}):
777
+ continue
778
+ elif self.find_in_tree(cid, old_cid):
779
+ continue
780
+ if sim := get_sim(txt, old_txt):
781
+ sims[old_cid] = sim
782
+ # если есть, берем самый похожий из них
783
+ if sims:
784
+ old_cid, sim = max(sims.items(), key=lambda x: x[1])
785
+ await sleep(0.3)
786
+ return old_cid, sim
787
+ return None, None
788
+
760
789
  async def person_upsert(self, name: str, exid: int) -> models.Person:
761
790
  if actor := await models.Actor.get_or_none(exid=exid, ex=self.ex_client.ex).prefetch_related("person"):
762
791
  if not actor.person:
@@ -796,24 +825,75 @@ class AgentClient(BaseAgentClient): # Bybit client
796
825
  return None
797
826
  return await CondSim.create(cond_id=new_cid, similarity=sim, cond_rel_id=old_cid)
798
827
 
799
- async def sim_upd(self, cid: int, new_txt: int):
800
- for sim_db in (_sims := await CondSim.filter(Q(join_type="OR", cond_id=cid, cond_rel_id=cid))):
801
- (op,) = {sim_db.cond_id, sim_db.cond_rel_id} - {cid}
802
- op_cond = await Cond[op]
803
- sim_db.similarity = get_sim(new_txt, op_cond.raw_txt)
804
- await sim_db.save()
828
+ async def sim_check_rels(self, cid: int, new_txt: int):
829
+ if _old_sims := await CondSim.filter(Q(join_type="OR", cond_id=cid, cond_rel_id=cid)):
830
+ for sim_db in _old_sims:
831
+ (op,) = {sim_db.cond_id, sim_db.cond_rel_id} - {cid}
832
+ op_cond = await Cond[op]
833
+ sim_db.similarity = get_sim(new_txt, op_cond.raw_txt)
834
+ await sim_db.save()
835
+
836
+ def build_tree(self):
837
+ set(self.cond_sims.keys()) | set(self.cond_sims.values())
838
+ tree = defaultdict(dict)
839
+ # Группируем родителей по детям
840
+ for child, par in self.cond_sims.items():
841
+ tree[par] |= {child: {}} # todo: make from self.rcond_sim
842
+
843
+ # Строим дерево снизу вверх
844
+ def subtree(node):
845
+ if not node:
846
+ return node
847
+ for key in node:
848
+ subnode = tree.pop(key, {})
849
+ d = subtree(subnode)
850
+ node[key] |= d # actual tree rebuilding here!
851
+ return node # todo: refact?
852
+
853
+ # Находим корни / без родителей
854
+ roots = set(self.cond_sims.values()) - set(self.cond_sims.keys())
855
+ for root in roots:
856
+ _ = subtree(tree[root])
857
+
858
+ self.tree = tree
805
859
 
806
860
  async def actual_cond(self):
807
- self.all_conds = {
808
- c.id: (c.raw_txt, {str(a.maker.exid) for a in c.ads})
809
- for c in await Cond.all().prefetch_related("ads__maker")
810
- }
811
- self.cond_sims = {cs.cond_id: (cs.cond_rel_id, cs.similarity) for cs in await CondSim.all()}
812
- for c, (o, s) in self.cond_sims.items():
813
- self.sim_conds[o].add(c)
814
- for ad_db in await models.Ad.filter(direction__pairex__ex=self.ex_client.ex).prefetch_related("cond", "maker"):
815
- ad = Ad(id=str(ad_db.exid), userId=str(ad_db.maker.exid), remark=ad_db.cond.raw_txt)
816
- await self.cond_upsert(ad, force=True)
861
+ for curr, old in await CondSim.all().values_list("cond_id", "cond_rel_id"):
862
+ self.cond_sims[curr] = old
863
+ self.rcond_sims[old] |= {curr}
864
+ self.build_tree()
865
+ for cid, (txt, uids) in self.all_conds.items():
866
+ old_cid, sim = await self.cond_get_max_sim(cid, txt, uids)
867
+ if sim:
868
+ if old_sim := await CondSim.get_or_none(cond_id=cid):
869
+ if old_sim.cond_rel_id != old_cid:
870
+ if sim <= old_sim.similarity:
871
+ # old_rsim = await CondSim.get_or_none(cond_id=old_cid)
872
+ # if not old_rsim:
873
+ # await CondSim.create(cond_id=old_cid, cond_rel_id=cid, similarity=sim)
874
+ # self.cond_sims[old_cid] = cid
875
+ # self.rcond_sims[cid] |= {old_cid}
876
+ # # self.add_to_tree(old_cid, cid, self.tree)
877
+ # elif old_rsim.similarity < sim:
878
+ # await CondSim.update_or_create({"cond_rel_id": cid, "similarity": sim}, cond_id=old_cid)
879
+ # self.cond_sims[old_cid] = cid
880
+ # self.rcond_sims[cid] |= {old_cid}
881
+ # self.rcond_sims[old_rsim.cond_rel_id].remove(old_rsim.cond_id)
882
+ # logging.warning(f'{old_cid}: {old_sim.similarity}->{sim} ({old_sim.cond_rel_id}->{cid})')
883
+ continue
884
+ logging.warning(f"R {cid}: {old_sim.similarity}->{sim} ({old_sim.cond_rel_id}->{old_cid})")
885
+ await old_sim.update_from_dict({"similarity": sim, "old_rel_id": old_cid}).save()
886
+ elif sim != old_sim.similarity:
887
+ logging.info(f"{cid}: {old_sim.similarity}->{sim}")
888
+ await old_sim.update_from_dict({"similarity": sim}).save()
889
+ else:
890
+ await CondSim.create(cond_id=cid, cond_rel_id=old_cid, similarity=sim)
891
+ self.cond_sims[cid] = old_cid
892
+ self.rcond_sims[old_cid] |= {cid}
893
+ # self.add_to_tree(cid, old_cid, self.tree)
894
+ # for ad_db in await models.Ad.filter(direction__pairex__ex=self.ex_client.ex).prefetch_related("cond", "maker"):
895
+ # ad = Ad(id=str(ad_db.exid), userId=str(ad_db.maker.exid), remark=ad_db.cond.raw_txt)
896
+ # await self.cond_upsert(ad, force=True)
817
897
 
818
898
  async def get_credexs_by_norms(self, norms: list[str], cur_id: int) -> dict[models.Pmex, models.CredEx] | None:
819
899
  try:
@@ -831,7 +911,7 @@ class AgentClient(BaseAgentClient): # Bybit client
831
911
 
832
912
 
833
913
  def get_sim(s1, s2) -> int:
834
- sim = int((SequenceMatcher(None, s1, s2).ratio() - 0.9) * 10_000)
914
+ sim = int((SequenceMatcher(None, s1, s2).ratio() - 0.6) * 10_000)
835
915
  return sim if sim > 0 else 0
836
916
 
837
917
 
@@ -888,49 +968,64 @@ async def main():
888
968
  actor = (
889
969
  await models.Actor.filter(ex_id=9, agent__isnull=False).prefetch_related("ex", "agent", "person__user").first()
890
970
  )
891
- async with FileClient(TOKEN) as b:
892
- cl: AgentClient = actor.client(b)
893
- # await cl.ex_client.set_pmcurexs(cookies=actor.agent.auth["cookies"]) # 617 -> 639
894
- # await cl.set_creds()
895
- # await cl.ex_client.set_pairs()
896
- usdt = await models.Coinex.get(coin__ticker="USDT", ex=cl.actor.ex).prefetch_related("coin")
897
- btc = await models.Coinex.get(coin__ticker="BTC", ex=cl.actor.ex).prefetch_related("coin")
898
- eth = await models.Coinex.get(coin__ticker="ETH", ex=cl.actor.ex).prefetch_related("coin")
899
- usdc = await models.Coinex.get(coin__ticker="USDC", ex=cl.actor.ex).prefetch_related("coin")
900
- rub = await models.Curex.get(cur__ticker="RUB", ex=cl.actor.ex).prefetch_related("cur")
901
- cl.all_conds = {
902
- c.id: (c.raw_txt, {str(a.maker.exid) for a in c.ads})
903
- for c in await Cond.all().prefetch_related("ads__maker")
904
- }
905
- # await cl.actual_cond()
906
- await gather(
907
- cl.battle(usdt, rub, False, ["volet"], 79.8), # гонка в стакане покупки - мы продаем
908
- cl.battle(usdt, rub, True, ["volet"], 79.8), # гонка в стакане продажи - мы покупаем
909
- cl.battle(eth, rub, False, ["volet"], 206_000),
910
- cl.battle(eth, rub, True, ["volet"], 200_000),
911
- cl.battle(btc, rub, False, ["volet"], 8_500_000),
912
- cl.battle(btc, rub, True, ["volet"], 8_400_000),
913
- cl.battle(usdc, rub, False, ["volet"], 80.5),
914
- cl.battle(usdc, rub, True, ["volet"], 79),
915
- cl.take(usdt, rub, False, ceil=80, volume=360),
916
- cl.take(usdt, rub, True, ceil=80, volume=360),
917
- # cl.get_api_orders(), # 10, 1738357200000, 1742504399999
918
- )
971
+ # async with FileClient(TOKEN) as b:
972
+ cl: AgentClient = actor.client(FileClient(TOKEN))
973
+ # await cl.ex_client.set_pmcurexs(cookies=actor.agent.auth["cookies"]) # 617 -> 639
974
+ # await cl.set_creds()
975
+ # await cl.ex_client.set_pairs()
976
+ usdt = await models.Coinex.get(coin__ticker="USDT", ex=cl.actor.ex).prefetch_related("coin")
977
+ btc = await models.Coinex.get(coin__ticker="BTC", ex=cl.actor.ex).prefetch_related("coin")
978
+ eth = await models.Coinex.get(coin__ticker="ETH", ex=cl.actor.ex).prefetch_related("coin")
979
+ usdc = await models.Coinex.get(coin__ticker="USDC", ex=cl.actor.ex).prefetch_related("coin")
980
+ rub = await models.Curex.get(cur__ticker="RUB", ex=cl.actor.ex).prefetch_related("cur")
981
+ cl.all_conds = {
982
+ c.id: (c.raw_txt, {a.maker.exid for a in c.ads}) for c in await Cond.all().prefetch_related("ads__maker")
983
+ }
984
+ for curr, old in await CondSim.filter().values_list("cond_id", "cond_rel_id"):
985
+ cl.cond_sims[curr] = old
986
+ cl.rcond_sims[old] |= {curr}
987
+ cl.build_tree()
988
+ a = set()
989
+
990
+ def check_tree(tre):
991
+ for p, c in tre.items():
992
+ a.add(p)
993
+ check_tree(c)
994
+
995
+ for pr, ch in cl.tree.items():
996
+ check_tree(ch)
997
+ await cl.actual_cond()
998
+ await gather(
999
+ cl.get_api_orders(10, 1737493200000, 1742590800000), # 10, 1738357200000, 1742504399999
1000
+ cl.battle(usdt, rub, False, ["volet"], 79.8), # гонка в стакане покупки - мы продаем
1001
+ cl.battle(usdt, rub, True, ["volet"], 79.8), # гонка в стакане продажи - мы покупаем
1002
+ cl.battle(eth, rub, False, ["volet"], 206_000),
1003
+ cl.battle(eth, rub, True, ["volet"], 200_000),
1004
+ cl.battle(btc, rub, False, ["volet"], 8_500_000),
1005
+ cl.battle(btc, rub, True, ["volet"], 8_400_000),
1006
+ cl.battle(usdc, rub, False, ["volet"], 80.5),
1007
+ cl.battle(usdc, rub, True, ["volet"], 79),
1008
+ cl.take(usdt, rub, False, ceil=80, volume=360),
1009
+ cl.take(usdt, rub, True, ceil=80, volume=360),
1010
+ )
919
1011
 
920
- bor = BaseOrderReq(
921
- ad_id="1861440060199632896",
922
- # asset_amount=40,
923
- fiat_amount=3000,
924
- amount_is_fiat=True,
925
- is_sell=False,
926
- cur_exid=rub.exid,
927
- coin_exid=usdt.exid,
928
- coin_scale=usdt.coin.scale,
929
- )
930
- res: OrderResp = await cl.order_request(bor)
931
- await cl.cancel_order(res.orderId)
932
- await cl.close()
1012
+ bor = BaseOrderReq(
1013
+ ad_id="1861440060199632896",
1014
+ # asset_amount=40,
1015
+ fiat_amount=3000,
1016
+ amount_is_fiat=True,
1017
+ is_sell=False,
1018
+ cur_exid=rub.exid,
1019
+ coin_exid=usdt.exid,
1020
+ coin_scale=usdt.coin.scale,
1021
+ )
1022
+ res: OrderResp = await cl.order_request(bor)
1023
+ await cl.cancel_order(res.orderId)
1024
+ await cl.close()
933
1025
 
934
1026
 
935
1027
  if __name__ == "__main__":
936
- run(main())
1028
+ try:
1029
+ run(main())
1030
+ except KeyboardInterrupt:
1031
+ logging.info("Shutting down")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.57.dev22
3
+ Version: 0.0.57.dev24
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