xync-client 0.0.114__py3-none-any.whl → 0.0.155__py3-none-any.whl
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.
- xync_client/Abc/AdLoader.py +299 -0
- xync_client/Abc/Agent.py +94 -10
- xync_client/Abc/Ex.py +27 -22
- xync_client/Abc/HasAbotUid.py +10 -0
- xync_client/Abc/InAgent.py +0 -11
- xync_client/Abc/PmAgent.py +42 -35
- xync_client/Abc/xtype.py +24 -2
- xync_client/Binance/ex.py +2 -2
- xync_client/BingX/ex.py +2 -2
- xync_client/BitGet/ex.py +2 -2
- xync_client/Bybit/InAgent.py +229 -114
- xync_client/Bybit/agent.py +584 -572
- xync_client/Bybit/etype/ad.py +11 -56
- xync_client/Bybit/etype/cred.py +29 -9
- xync_client/Bybit/etype/order.py +55 -62
- xync_client/Bybit/ex.py +17 -4
- xync_client/Gate/ex.py +2 -2
- xync_client/Gmail/__init__.py +119 -98
- xync_client/Htx/agent.py +162 -31
- xync_client/Htx/etype/ad.py +18 -11
- xync_client/Htx/ex.py +9 -11
- xync_client/KuCoin/ex.py +2 -2
- xync_client/Mexc/agent.py +85 -0
- xync_client/Mexc/api.py +636 -0
- xync_client/Mexc/etype/order.py +639 -0
- xync_client/Mexc/ex.py +12 -10
- xync_client/Okx/ex.py +2 -2
- xync_client/Pms/Payeer/__init__.py +147 -43
- xync_client/Pms/Payeer/login.py +29 -2
- xync_client/Pms/Volet/__init__.py +148 -94
- xync_client/Pms/Volet/api.py +17 -13
- xync_client/TgWallet/ex.py +2 -2
- xync_client/details.py +44 -0
- xync_client/loader.py +2 -1
- xync_client/pm_unifier.py +1 -1
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/METADATA +6 -1
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/RECORD +39 -33
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/WHEEL +0 -0
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/top_level.txt +0 -0
xync_client/Bybit/agent.py
CHANGED
|
@@ -2,34 +2,44 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
4
|
from asyncio import sleep, gather
|
|
5
|
-
from
|
|
5
|
+
from asyncio.tasks import create_task
|
|
6
6
|
from datetime import datetime, timedelta, timezone
|
|
7
7
|
from difflib import SequenceMatcher
|
|
8
8
|
from enum import IntEnum
|
|
9
|
+
from hashlib import sha256
|
|
9
10
|
from http.client import HTTPException
|
|
11
|
+
from math import floor
|
|
10
12
|
from typing import Literal
|
|
11
13
|
|
|
12
14
|
import pyotp
|
|
15
|
+
from aiohttp.http_exceptions import HttpProcessingError
|
|
13
16
|
from asyncpg import ConnectionDoesNotExistError
|
|
14
17
|
from bybit_p2p import P2P
|
|
15
18
|
from bybit_p2p._exceptions import FailedRequestError
|
|
19
|
+
from payeer_api import PayeerAPI
|
|
16
20
|
from pyro_client.client.file import FileClient
|
|
17
21
|
from tortoise import BaseDBAsyncClient
|
|
18
22
|
from tortoise.exceptions import IntegrityError
|
|
19
|
-
from tortoise.expressions import
|
|
23
|
+
from tortoise.expressions import Q
|
|
20
24
|
from tortoise.functions import Count
|
|
21
25
|
from tortoise.signals import post_save
|
|
26
|
+
from tortoise.timezone import now
|
|
22
27
|
from urllib3.exceptions import ReadTimeoutError
|
|
28
|
+
from x_client import df_hdrs
|
|
23
29
|
from x_model import init_db
|
|
24
30
|
from x_model.func import ArrayAgg
|
|
31
|
+
from xync_bot import XyncBot
|
|
32
|
+
from xync_client.Bybit.InAgent import InAgentClient
|
|
33
|
+
|
|
34
|
+
from xync_client.Bybit.ex import ExClient
|
|
25
35
|
from xync_schema import models
|
|
26
|
-
from xync_schema.enums import OrderStatus
|
|
36
|
+
from xync_schema.enums import OrderStatus, AgentStatus
|
|
27
37
|
|
|
28
|
-
from xync_schema.models import Actor,
|
|
38
|
+
from xync_schema.models import Actor, PmCur, Agent
|
|
29
39
|
|
|
30
40
|
from xync_client.Abc.Agent import BaseAgentClient
|
|
31
|
-
from xync_client.Abc.xtype import
|
|
32
|
-
from xync_client.Bybit.etype.ad import AdPostRequest, AdUpdateRequest, Ad, AdStatus
|
|
41
|
+
from xync_client.Abc.xtype import FlatDict, BaseOrderReq
|
|
42
|
+
from xync_client.Bybit.etype.ad import AdPostRequest, AdUpdateRequest, Ad, AdStatus, MyAd
|
|
33
43
|
from xync_client.Bybit.etype.cred import CredEpyd
|
|
34
44
|
from xync_client.Bybit.etype.order import (
|
|
35
45
|
OrderRequest,
|
|
@@ -40,17 +50,20 @@ from xync_client.Bybit.etype.order import (
|
|
|
40
50
|
OrderFull,
|
|
41
51
|
Message,
|
|
42
52
|
Status,
|
|
53
|
+
OrderSellRequest,
|
|
54
|
+
TakeAdReq,
|
|
43
55
|
)
|
|
44
|
-
from xync_client.loader import TORM,
|
|
56
|
+
from xync_client.loader import TORM, NET_TOKEN, PAY_TOKEN
|
|
45
57
|
|
|
46
58
|
|
|
47
59
|
class NoMakerException(Exception):
|
|
48
60
|
pass
|
|
49
61
|
|
|
50
62
|
|
|
51
|
-
class AgentClient(BaseAgentClient): # Bybit client
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
class AgentClient(BaseAgentClient, InAgentClient): # Bybit client
|
|
64
|
+
headers = df_hdrs | {"accept-language": "ru-RU"}
|
|
65
|
+
sec_hdrs: dict[str, str]
|
|
66
|
+
# rewrite token for public methods
|
|
54
67
|
api: P2P
|
|
55
68
|
last_ad_id: list[str] = []
|
|
56
69
|
update_ad_body = {
|
|
@@ -80,26 +93,29 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
80
93
|
"actionType": "MODIFY",
|
|
81
94
|
"securityRiskToken": "",
|
|
82
95
|
}
|
|
83
|
-
all_conds: dict[int, tuple[str, set[int]]] = {}
|
|
84
|
-
cond_sims: dict[int, int] = defaultdict(set)
|
|
85
|
-
rcond_sims: dict[int, set[int]] = defaultdict(set) # backward
|
|
86
|
-
tree: dict = {}
|
|
87
96
|
|
|
88
|
-
def __init__(self,
|
|
89
|
-
super().__init__(
|
|
90
|
-
self.
|
|
97
|
+
def __init__(self, agent: Agent, ex_client: ExClient, fbot: FileClient, bbot: XyncBot, **kwargs):
|
|
98
|
+
super().__init__(agent, ex_client, fbot, bbot, **kwargs)
|
|
99
|
+
self.sec_hdrs = {
|
|
100
|
+
"accept-language": "ru,en;q=0.9",
|
|
101
|
+
"gdfp": agent.auth["Risktoken"],
|
|
102
|
+
"tx-id": agent.auth["Risktoken"],
|
|
103
|
+
}
|
|
104
|
+
self.api = P2P(testnet=False, api_key=agent.auth["key"], api_secret=agent.auth["sec"])
|
|
105
|
+
self.hist: dict | None = None
|
|
106
|
+
self.completed_orders: list[int] | None = None
|
|
91
107
|
|
|
92
108
|
""" Private METHs"""
|
|
93
109
|
|
|
94
110
|
async def fiat_new(self, payment_type: int, real_name: str, account_number: str) -> FlatDict | None:
|
|
95
111
|
method1 = await self._post(
|
|
96
|
-
"/fiat/otc/user/payment/new_create",
|
|
112
|
+
"/x-api/fiat/otc/user/payment/new_create",
|
|
97
113
|
{"paymentType": payment_type, "realName": real_name, "accountNo": account_number, "securityRiskToken": ""},
|
|
98
114
|
)
|
|
99
115
|
if srt := method1["result"]["securityRiskToken"]:
|
|
100
116
|
await self._check_2fa(srt)
|
|
101
117
|
method2 = await self._post(
|
|
102
|
-
"/fiat/otc/user/payment/new_create",
|
|
118
|
+
"/x-api/fiat/otc/user/payment/new_create",
|
|
103
119
|
{
|
|
104
120
|
"paymentType": payment_type,
|
|
105
121
|
"realName": real_name,
|
|
@@ -111,12 +127,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
111
127
|
else:
|
|
112
128
|
return logging.exception(method1)
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if fiat_id:
|
|
117
|
-
fiat = [m for m in list_methods if m["id"] == fiat_id][0]
|
|
118
|
-
return fiat
|
|
119
|
-
return list_methods[1]
|
|
130
|
+
def get_payment_method(self, fiat_id: int) -> CredEpyd:
|
|
131
|
+
return self.creds()[fiat_id]
|
|
120
132
|
|
|
121
133
|
def creds(self) -> dict[int, CredEpyd]:
|
|
122
134
|
data = self.api.get_user_payment_types()
|
|
@@ -140,29 +152,37 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
140
152
|
elif not cur_id: # is new Cred
|
|
141
153
|
cur_id = (
|
|
142
154
|
pmex.pm.df_cur_id
|
|
155
|
+
or await self.guess_cur(ecdx, len(pmex.pm.curs) > 1 and pmex.pm.curs)
|
|
143
156
|
or (pmex.pm.country_id and (await pmex.pm.country).cur_id)
|
|
144
|
-
# or (ecdx.currencyBalance and await models.Cur.get_or_none(ticker=ecdx.currencyBalance[0]))
|
|
145
|
-
or (0 < len(pmex.pm.curs) < 30 and pmex.pm.curs[-1].id)
|
|
146
|
-
or await self.guess_cur(ecdx)
|
|
157
|
+
# or (ecdx.currencyBalance and await models.Cur.get_or_none(ticker=ecdx.currencyBalance[0])) # это че еще за хуйня?
|
|
147
158
|
)
|
|
148
159
|
if not cur_id:
|
|
149
160
|
raise Exception(f"Set default cur for {pmex.name}")
|
|
150
161
|
if not (pmcur := await models.PmCur.get_or_none(cur_id=cur_id, pm_id=pmex.pm_id)):
|
|
151
|
-
raise HTTPException(f"No PmCur with cur#{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
|
|
156
|
-
"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
raise HTTPException(f"No PmCur with cur#{cur_id} and pm#{ecdx.paymentType}", 404)
|
|
163
|
+
xtr = ecdx.branchName
|
|
164
|
+
if ecdx.bankName:
|
|
165
|
+
xtr += (" | " if xtr else "") + ecdx.bankName
|
|
166
|
+
elif ecdx.payMessage:
|
|
167
|
+
xtr += (" | " if xtr else "") + ecdx.payMessage
|
|
168
|
+
elif ecdx.qrcode:
|
|
169
|
+
xtr += (" | " if xtr else "") + ecdx.qrcode
|
|
170
|
+
elif ecdx.paymentExt1:
|
|
171
|
+
xtr += (" | " if xtr else "") + ecdx.paymentExt1
|
|
172
|
+
cred_db, _ = await models.Cred.update_or_create(
|
|
173
|
+
{
|
|
174
|
+
"name": ecdx.realName,
|
|
175
|
+
"extra": xtr,
|
|
176
|
+
},
|
|
177
|
+
pmcur=pmcur,
|
|
178
|
+
person_id=pers_id or self.actor.person_id,
|
|
179
|
+
detail=ecdx.accountNo or ecdx.payMessage,
|
|
180
|
+
)
|
|
161
181
|
credex_in = models.CredEx.validate({"exid": ecdx.id, "cred_id": cred_db.id, "ex_id": self.actor.ex.id})
|
|
162
182
|
credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
|
|
163
183
|
return credex_db
|
|
164
184
|
|
|
165
|
-
async def guess_cur(self, ecdx: CredEpyd):
|
|
185
|
+
async def guess_cur(self, ecdx: CredEpyd, curs: list[models.Cur]):
|
|
166
186
|
mbs = ecdx.bankName.split(", ")
|
|
167
187
|
mbs += ecdx.branchName.split(" / ")
|
|
168
188
|
mbs = {mb.lower(): mb for mb in mbs}
|
|
@@ -174,7 +194,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
174
194
|
.values("pmcurs__cur_id", "names", "ccnt")
|
|
175
195
|
):
|
|
176
196
|
return pms[0]["pmcurs__cur_id"]
|
|
177
|
-
curs = {c.ticker: c.id for c in await models.Cur.all()}
|
|
197
|
+
curs = {c.ticker: c.id for c in curs or await models.Cur.all()}
|
|
178
198
|
for cur, cid in curs.items():
|
|
179
199
|
if re.search(re.compile(rf"\({cur}\)$"), ecdx.bankName):
|
|
180
200
|
return cid
|
|
@@ -184,6 +204,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
184
204
|
return cid
|
|
185
205
|
if re.search(re.compile(rf"\({cur}\)$"), ecdx.payMessage):
|
|
186
206
|
return cid
|
|
207
|
+
if re.search(re.compile(rf"\({cur}\)$"), ecdx.paymentExt1):
|
|
208
|
+
return cid
|
|
187
209
|
return None
|
|
188
210
|
|
|
189
211
|
# 25: Список реквизитов моих платежных методов
|
|
@@ -193,34 +215,34 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
193
215
|
return credexs
|
|
194
216
|
|
|
195
217
|
async def ott(self):
|
|
196
|
-
t = await self._post("/user/private/ott")
|
|
218
|
+
t = await self._post("/x-api/user/private/ott")
|
|
197
219
|
return t
|
|
198
220
|
|
|
199
221
|
# 27
|
|
200
222
|
async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> dict:
|
|
201
223
|
fiat = self.get_payment_method(fiat_id)
|
|
202
|
-
fiat
|
|
203
|
-
fiat
|
|
204
|
-
result = await self._post("/fiat/otc/user/payment/new_update", fiat)
|
|
224
|
+
fiat.realName = name
|
|
225
|
+
fiat.accountNo = detail
|
|
226
|
+
result = await self._post("/x-api/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
|
|
205
227
|
srt = result["result"]["securityRiskToken"]
|
|
206
228
|
await self._check_2fa(srt)
|
|
207
|
-
fiat
|
|
208
|
-
result2 = await self._post("/fiat/otc/user/payment/new_update", fiat)
|
|
229
|
+
fiat.securityRiskToken = srt
|
|
230
|
+
result2 = await self._post("/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
|
|
209
231
|
return result2
|
|
210
232
|
|
|
211
233
|
# 28
|
|
212
234
|
async def fiat_del(self, fiat_id: int) -> dict | str:
|
|
213
235
|
data = {"id": fiat_id, "securityRiskToken": ""}
|
|
214
|
-
method = await self._post("/fiat/otc/user/payment/new_delete", data)
|
|
236
|
+
method = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
|
|
215
237
|
srt = method["result"]["securityRiskToken"]
|
|
216
238
|
await self._check_2fa(srt)
|
|
217
239
|
data["securityRiskToken"] = srt
|
|
218
|
-
delete = await self._post("/fiat/otc/user/payment/new_delete", data)
|
|
240
|
+
delete = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
|
|
219
241
|
return delete
|
|
220
242
|
|
|
221
243
|
async def switch_ads(self, new_status: AdStatus) -> dict:
|
|
222
244
|
data = {"workStatus": new_status.name} # todo: переделать на апи, там status 0 -> 1
|
|
223
|
-
res = await self._post("/fiat/otc/maker/work-config/switch", data)
|
|
245
|
+
res = await self._post("/x-api/fiat/otc/maker/work-config/switch", data)
|
|
224
246
|
return res
|
|
225
247
|
|
|
226
248
|
async def ads(
|
|
@@ -228,27 +250,36 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
228
250
|
cnx: models.CoinEx,
|
|
229
251
|
crx: models.CurEx,
|
|
230
252
|
is_sell: bool,
|
|
231
|
-
|
|
253
|
+
pmexs: list[models.PmEx],
|
|
232
254
|
amount: int = None,
|
|
233
255
|
lim: int = 50,
|
|
234
256
|
vm_filter: bool = False,
|
|
257
|
+
post_pmexs: set[models.PmEx] = None,
|
|
235
258
|
) -> list[Ad]:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
259
|
+
if post_pmexs:
|
|
260
|
+
pm_exids = None
|
|
261
|
+
lim = min(1000, lim * 25)
|
|
262
|
+
post_pmexids = {p.exid for p in post_pmexs}
|
|
263
|
+
else:
|
|
264
|
+
pm_exids = [px.exid for px in pmexs]
|
|
265
|
+
post_pmexids = set()
|
|
266
|
+
ads: list[Ad] = await self.ex_client.ads(cnx.exid, crx.exid, is_sell, pm_exids, amount, lim, vm_filter)
|
|
267
|
+
if post_pmexs:
|
|
268
|
+
ads = [
|
|
269
|
+
ad
|
|
270
|
+
for ad in ads
|
|
271
|
+
if (set(ad.payments) & post_pmexids or [True for px in post_pmexs if px.pm.norm in ad.remark.lower()])
|
|
272
|
+
]
|
|
273
|
+
return ads
|
|
243
274
|
|
|
244
275
|
@staticmethod
|
|
245
276
|
def get_rate(list_ads: list) -> float:
|
|
246
277
|
ads = [ad for ad in list_ads if set(ad["payments"]) - {"5", "51"}]
|
|
247
278
|
return float(ads[0]["price"])
|
|
248
279
|
|
|
249
|
-
def my_ads(self, active: bool = True, page: int = 1) -> list[
|
|
280
|
+
def my_ads(self, active: bool = True, page: int = 1) -> list[MyAd]:
|
|
250
281
|
resp = self.api.get_ads_list(size="30", page=str(page), status=AdStatus.active if active else AdStatus.sold_out)
|
|
251
|
-
ads = [
|
|
282
|
+
ads = [MyAd.model_validate(ad) for ad in resp["result"]["items"]]
|
|
252
283
|
if resp["result"]["count"] > 30 * page:
|
|
253
284
|
ads.extend(self.my_ads(active, page + 1))
|
|
254
285
|
return ads
|
|
@@ -257,35 +288,63 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
257
288
|
ads = self.my_ads(True)
|
|
258
289
|
if not active:
|
|
259
290
|
ads += self.my_ads(False)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
291
|
+
for ad in ads:
|
|
292
|
+
ad_db = await self.ex_client.ad_load(ad, maker=self.actor)
|
|
293
|
+
mad_db, _ = await models.MyAd.update_or_create(ad=ad_db)
|
|
294
|
+
exids = [pt.id for pt in ad.paymentTerms]
|
|
295
|
+
credexs = await models.CredEx.filter(ex_id=self.actor.ex_id, exid__in=exids)
|
|
296
|
+
await mad_db.credexs.add(*credexs)
|
|
297
|
+
return len(ads)
|
|
263
298
|
|
|
264
299
|
def get_security_token_create(self):
|
|
265
|
-
data = self._post("/fiat/otc/item/create", self.create_ad_body)
|
|
300
|
+
data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
|
|
266
301
|
if data["ret_code"] == 912120019: # Current user can not to create add as maker
|
|
267
302
|
raise NoMakerException(data)
|
|
268
303
|
security_risk_token = data["result"]["securityRiskToken"]
|
|
269
304
|
return security_risk_token
|
|
270
305
|
|
|
271
|
-
def _check_2fa(self, risk_token):
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
totp = pyotp.TOTP(bybit_secret)
|
|
275
|
-
totp_code = totp.now()
|
|
276
|
-
|
|
277
|
-
res = self._post(
|
|
278
|
-
"/user/public/risk/verify", {"risk_token": risk_token, "component_list": {"google2fa": totp_code}}
|
|
279
|
-
)
|
|
306
|
+
async def _check_2fa(self, risk_token) -> int:
|
|
307
|
+
data = {"risk_token": risk_token}
|
|
308
|
+
res = await self._post("/x-api/user/public/risk/components", data, hdrs=self.sec_hdrs)
|
|
280
309
|
if res["ret_msg"] != "success":
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
310
|
+
raise HTTPException("get")
|
|
311
|
+
cres = sorted(res["result"]["component_list"], key=lambda c: c["component_id"], reverse=True)
|
|
312
|
+
vdata = {
|
|
313
|
+
"risk_token": risk_token,
|
|
314
|
+
"component_list": {c["component_id"]: await self.__get_2fa(c["component_id"], risk_token) for c in cres},
|
|
315
|
+
}
|
|
316
|
+
res = await self._post("/x-api/user/public/risk/verify", vdata, hdrs=self.sec_hdrs)
|
|
317
|
+
if er_code := res["ret_code"] or res["result"]["ret_code"]: # если код не 0, значит ошибка
|
|
318
|
+
logging.error("Wrong 2fa, wait 5 secs and retry..")
|
|
319
|
+
await sleep(5)
|
|
320
|
+
return await self._check_2fa(risk_token)
|
|
321
|
+
return er_code
|
|
322
|
+
|
|
323
|
+
async def __get_2fa(
|
|
324
|
+
self, typ: Literal["google2fa", "email_verify", "payment_password_verify", "phone_verify"], rt: str = None
|
|
325
|
+
):
|
|
326
|
+
res = {"ret_msg": "success"}
|
|
327
|
+
if typ != "google2fa":
|
|
328
|
+
data = {"risk_token": rt, "component_id": typ}
|
|
329
|
+
res = await self._post("/x-api/user/public/risk/send/code", data, hdrs=self.sec_hdrs)
|
|
330
|
+
if res["ret_msg"] == "success":
|
|
331
|
+
if typ == "google2fa":
|
|
332
|
+
bybit_secret = self.agent.auth["2fa"]
|
|
333
|
+
totp = pyotp.TOTP(bybit_secret)
|
|
334
|
+
return totp.now()
|
|
335
|
+
elif typ == "email_verify":
|
|
336
|
+
return self.gmail.bybit_code()
|
|
337
|
+
elif typ == "payment_password_verify":
|
|
338
|
+
hp = sha256(self.agent.auth["pass"].encode()).hexdigest()
|
|
339
|
+
return hp
|
|
340
|
+
elif cool_down := int(res["result"]["cool_down"]):
|
|
341
|
+
await sleep(cool_down)
|
|
342
|
+
return self.__get_2fa(typ, rt)
|
|
343
|
+
raise Exception("2fa fail")
|
|
285
344
|
|
|
286
345
|
def _post_ad(self, risk_token: str):
|
|
287
346
|
self.create_ad_body.update({"securityRiskToken": risk_token})
|
|
288
|
-
data = self._post("/fiat/otc/item/create", self.create_ad_body)
|
|
347
|
+
data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
|
|
289
348
|
return data
|
|
290
349
|
|
|
291
350
|
# создание объявлений
|
|
@@ -311,7 +370,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
311
370
|
|
|
312
371
|
def get_security_token_update(self) -> str:
|
|
313
372
|
self.update_ad_body["id"] = self.last_ad_id
|
|
314
|
-
data = self._post("/fiat/otc/item/update", self.update_ad_body)
|
|
373
|
+
data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
|
|
315
374
|
security_risk_token = data["result"]["securityRiskToken"]
|
|
316
375
|
return security_risk_token
|
|
317
376
|
|
|
@@ -328,46 +387,75 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
328
387
|
|
|
329
388
|
def update_ad(self, risk_token: str):
|
|
330
389
|
self.update_ad_body.update({"securityRiskToken": risk_token})
|
|
331
|
-
data = self._post("/fiat/otc/item/update", self.update_ad_body)
|
|
390
|
+
data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
|
|
332
391
|
return data
|
|
333
392
|
|
|
334
393
|
def ad_del(self, ad_id: int):
|
|
335
394
|
data = self.api.remove_ad(itemId=ad_id)
|
|
336
395
|
return data
|
|
337
396
|
|
|
338
|
-
async def
|
|
339
|
-
|
|
340
|
-
if
|
|
341
|
-
|
|
342
|
-
|
|
397
|
+
async def __preorder_request(self, ad_id: int) -> PreOrderResp:
|
|
398
|
+
res = await self._post("/x-api/fiat/otc/item/simple", json={"item_id": str(ad_id)})
|
|
399
|
+
if res["ret_code"] == 0:
|
|
400
|
+
res = res["result"]
|
|
401
|
+
return PreOrderResp.model_validate(res)
|
|
402
|
+
|
|
403
|
+
async def _order_request(self, bor: BaseOrderReq) -> OrderResp:
|
|
404
|
+
por: PreOrderResp = await self.__preorder_request(bor.ad_id)
|
|
343
405
|
req = OrderRequest(
|
|
344
|
-
itemId=
|
|
345
|
-
tokenId=
|
|
346
|
-
currencyId=
|
|
347
|
-
side=
|
|
348
|
-
amount=
|
|
349
|
-
curPrice=
|
|
350
|
-
quantity=str(
|
|
351
|
-
flag="amount"
|
|
406
|
+
itemId=por.id,
|
|
407
|
+
tokenId=bor.coin_exid,
|
|
408
|
+
currencyId=bor.cur_exid,
|
|
409
|
+
side="1" if bor.is_sell else "0",
|
|
410
|
+
amount=f"{bor.fiat_amount:.2f}".rstrip("0").rstrip("."),
|
|
411
|
+
curPrice=por.curPrice,
|
|
412
|
+
quantity=str(round(bor.fiat_amount / float(por.price), bor.coin_scale)),
|
|
413
|
+
flag="amount",
|
|
414
|
+
# online="0"
|
|
352
415
|
)
|
|
416
|
+
if bor.is_sell:
|
|
417
|
+
credex = await models.CredEx.get(
|
|
418
|
+
cred__person_id=self.actor.person_id,
|
|
419
|
+
cred__pmcur__pm__pmexs__exid=[pp for pp in por.payments if pp == bor.pmex_exid][0], # bor.pmex_exid
|
|
420
|
+
cred__pmcur__pm__pmexs__ex_id=self.ex_client.ex.id,
|
|
421
|
+
cred__pmcur__cur__ticker=bor.cur_exid,
|
|
422
|
+
)
|
|
423
|
+
req = OrderSellRequest(**req.model_dump(), paymentType=bor.pmex_exid, paymentId=str(credex.exid))
|
|
353
424
|
# вот непосредственно сам запрос на ордер
|
|
354
|
-
|
|
425
|
+
return await self.__order_create(req, bor)
|
|
426
|
+
|
|
427
|
+
async def __order_create(self, req: OrderRequest | OrderSellRequest, bor: BaseOrderReq) -> OrderResp:
|
|
428
|
+
hdrs = {"Risktoken": self.sec_hdrs["gdfp"]}
|
|
429
|
+
res: dict = await self._post("/x-api/fiat/otc/order/create", json=req.model_dump(), hdrs=hdrs)
|
|
355
430
|
if res["ret_code"] == 0:
|
|
356
|
-
|
|
431
|
+
resp = OrderResp.model_validate(res["result"])
|
|
432
|
+
elif res["ret_code"] == 10001:
|
|
433
|
+
logging.error(req.model_dump(), "POST", self.session._base_url)
|
|
434
|
+
raise HTTPException()
|
|
357
435
|
elif res["ret_code"] == 912120030 or res["ret_msg"] == "The price has changed, please try again later.":
|
|
358
|
-
|
|
436
|
+
resp = await self._order_request(bor)
|
|
437
|
+
else:
|
|
438
|
+
logging.exception(res)
|
|
439
|
+
if not resp.orderId and resp.needSecurityRisk:
|
|
440
|
+
if rc := await self._check_2fa(resp.securityRiskToken):
|
|
441
|
+
await self.bbot.send(self.actor.person.user.username_id, f"Bybit 2fa: {rc}")
|
|
442
|
+
raise Exception(f"Bybit 2fa: {rc}")
|
|
443
|
+
# еще раз уже с токеном
|
|
444
|
+
req.securityRiskToken = resp.securityRiskToken
|
|
445
|
+
resp = await self.__order_create(req, bor)
|
|
446
|
+
return resp
|
|
359
447
|
|
|
360
448
|
async def cancel_order(self, order_id: str) -> bool:
|
|
361
449
|
cr = CancelOrderReq(orderId=order_id)
|
|
362
|
-
res = await self._post("/fiat/otc/order/cancel", cr.model_dump())
|
|
450
|
+
res = await self._post("/x-api/fiat/otc/order/cancel", cr.model_dump())
|
|
363
451
|
return res["ret_code"] == 0
|
|
364
452
|
|
|
365
|
-
def get_order_info(self, order_id: str) ->
|
|
366
|
-
data = self._post("/fiat/otc/order/info", json={"orderId": order_id})
|
|
367
|
-
return data["result"]
|
|
453
|
+
async def get_order_info(self, order_id: str) -> OrderFull:
|
|
454
|
+
data = await self._post("/x-api/fiat/otc/order/info", json={"orderId": order_id})
|
|
455
|
+
return OrderFull.model_validate(data["result"])
|
|
368
456
|
|
|
369
457
|
def get_chat_msg(self, order_id):
|
|
370
|
-
data = self._post("/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
|
|
458
|
+
data = self._post("/x-api/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
|
|
371
459
|
msgs = [
|
|
372
460
|
{"text": msg["message"], "type": msg["contentType"], "role": msg["roleType"], "user_id": msg["userId"]}
|
|
373
461
|
for msg in data["result"]["result"]
|
|
@@ -376,14 +464,14 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
376
464
|
return msgs
|
|
377
465
|
|
|
378
466
|
def block_user(self, user_id: str):
|
|
379
|
-
return self._post("/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
|
|
467
|
+
return self._post("/x-api/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
|
|
380
468
|
|
|
381
469
|
def unblock_user(self, user_id: str):
|
|
382
|
-
return self._post("/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
|
|
470
|
+
return self._post("/x-api/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
|
|
383
471
|
|
|
384
472
|
def user_review_post(self, order_id: str):
|
|
385
473
|
return self._post(
|
|
386
|
-
"/fiat/otc/order/appraise/modify",
|
|
474
|
+
"/x-api/fiat/otc/order/appraise/modify",
|
|
387
475
|
{
|
|
388
476
|
"orderId": order_id,
|
|
389
477
|
"anonymous": "0",
|
|
@@ -393,9 +481,17 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
393
481
|
},
|
|
394
482
|
)
|
|
395
483
|
|
|
396
|
-
def
|
|
484
|
+
def my_reviews(self):
|
|
397
485
|
return self._post(
|
|
398
|
-
"/fiat/otc/order/
|
|
486
|
+
"/x-api/fiat/otc/order/appraiseList",
|
|
487
|
+
{"makerUserId": self.actor.exid, "page": "1", "size": "10", "appraiseType": "1"}, # "0" - bad
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
async def get_orders_active(
|
|
491
|
+
self, side: int = None, status: int = None, begin_time: int = None, end_time: int = None, token_id: str = None
|
|
492
|
+
):
|
|
493
|
+
return await self._post(
|
|
494
|
+
"/x-api/fiat/otc/order/pending/simplifyList",
|
|
399
495
|
{
|
|
400
496
|
"status": status,
|
|
401
497
|
"tokenId": token_id,
|
|
@@ -409,7 +505,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
409
505
|
|
|
410
506
|
def get_orders_done(self, begin_time: int, end_time: int, status: int, side: int, token_id: str):
|
|
411
507
|
return self._post(
|
|
412
|
-
"/fiat/otc/order/simplifyList",
|
|
508
|
+
"/x-api/fiat/otc/order/simplifyList",
|
|
413
509
|
{
|
|
414
510
|
"status": status, # 50 - завершено
|
|
415
511
|
"tokenId": token_id,
|
|
@@ -422,27 +518,49 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
422
518
|
)
|
|
423
519
|
|
|
424
520
|
async def create_order(self, order: OrderFull) -> models.Order:
|
|
425
|
-
ad = Ad(**self.api.get_ad_details(itemId=order.itemId)["result"])
|
|
521
|
+
# ad = Ad(**self.api.get_ad_details(itemId=order.itemId)["result"])
|
|
426
522
|
await sleep(1)
|
|
427
523
|
curex = await models.CurEx.get_or_none(ex=self.ex_client.ex, exid=order.currencyId).prefetch_related("cur")
|
|
428
524
|
cur_scale = (curex.scale if curex.scale is not None else curex.cur.scale) if curex else 2
|
|
429
525
|
coinex = await models.CoinEx.get(ex=self.ex_client.ex, exid=order.tokenId).prefetch_related("coin")
|
|
430
526
|
coin_scale = coinex.scale if coinex.scale is not None else coinex.cur.scale
|
|
431
|
-
maker_name = order.
|
|
527
|
+
maker_name = order.sellerRealName, order.buyerRealName
|
|
432
528
|
im_maker = int(order.makerUserId == order.userId)
|
|
433
529
|
taker_id = (order.userId, order.targetUserId)[im_maker]
|
|
434
|
-
taker_person = await self.
|
|
530
|
+
taker_person = await self.ex_client.person_name_update(maker_name[::-1][order.side], taker_id)
|
|
435
531
|
seller_person = (
|
|
436
|
-
self.actor.person
|
|
532
|
+
self.actor.person
|
|
533
|
+
if order.side
|
|
534
|
+
else await self.ex_client.person_name_update(order.sellerRealName, int(order.targetUserId))
|
|
437
535
|
)
|
|
438
536
|
taker_nick = (self.actor.name, order.targetNickName)[im_maker] # todo: check
|
|
439
|
-
ad_db, cond_isnew = await self.
|
|
537
|
+
# ad_db, cond_isnew = await self.ex_client.cond_load(ad, force=True, rname=maker_name[order.side])
|
|
538
|
+
ad_db = await models.Ad.get(exid=order.itemId)
|
|
440
539
|
if not ad_db:
|
|
441
540
|
...
|
|
442
541
|
ecredex: CredEpyd = order.confirmedPayTerm
|
|
542
|
+
|
|
443
543
|
if ecredex.paymentType == 0 and im_maker and order.side:
|
|
444
544
|
ecredex = order.paymentTermList[0]
|
|
445
545
|
if ecredex.paymentType:
|
|
546
|
+
if ecredex.paymentType == 51:
|
|
547
|
+
ecredex.accountNo = ecredex.accountNo.replace("p", "P").replace("р", "P").replace("Р", "P")
|
|
548
|
+
# if not re.match(r"^([Pp])\d{7,10}$", ecredex.accountNo):
|
|
549
|
+
# msgs = self.api.get_chat_messages(orderId=order.id, size=100)["result"]["result"]
|
|
550
|
+
# msgs = [m["message"] for m in msgs if m["roleType"] == "user" and m["userId"] == order.targetUserId]
|
|
551
|
+
# msgs = [g.group() for m in msgs if (g := re.match(r"([PpРр])\d{7,10}\b", m))]
|
|
552
|
+
# crd = await models.Cred.get_or_none(
|
|
553
|
+
# detail=ecredex.accountNo, credexs__exid=ecredex.id, credexs__ex=self.ex_client.ex
|
|
554
|
+
# )
|
|
555
|
+
# if not msgs and re.match(r"^\d{7,10}$", ecredex.accountNo):
|
|
556
|
+
# ecredex.accountNo = "P" + ecredex.accountNo
|
|
557
|
+
# elif msgs:
|
|
558
|
+
# ecredex.accountNo = msgs[-1]
|
|
559
|
+
# else:
|
|
560
|
+
# ...
|
|
561
|
+
# if crd:
|
|
562
|
+
# crd.detail = ecredex.accountNo
|
|
563
|
+
# await crd.save(update_fields=["detail"])
|
|
446
564
|
if not (credex := await models.CredEx.get_or_none(exid=ecredex.id, ex=self.ex_client.ex)):
|
|
447
565
|
# cur_id = await Cur.get(ticker=ad.currencyId).values_list('id', flat=True)
|
|
448
566
|
# await self.cred_epyd2db(ecredex, ad_db.maker.person_id, cur_id)
|
|
@@ -450,7 +568,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
450
568
|
await PmCur.filter(
|
|
451
569
|
pm__pmexs__ex=self.ex_client.ex,
|
|
452
570
|
pm__pmexs__exid=ecredex.paymentType,
|
|
453
|
-
cur__ticker=
|
|
571
|
+
cur__ticker=order.currencyId,
|
|
454
572
|
).count()
|
|
455
573
|
!= 1
|
|
456
574
|
):
|
|
@@ -459,7 +577,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
459
577
|
pmcur := await PmCur.get_or_none(
|
|
460
578
|
pm__pmexs__ex=self.ex_client.ex,
|
|
461
579
|
pm__pmexs__exid=ecredex.paymentType,
|
|
462
|
-
cur__ticker=
|
|
580
|
+
cur__ticker=order.currencyId,
|
|
463
581
|
)
|
|
464
582
|
):
|
|
465
583
|
...
|
|
@@ -496,16 +614,55 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
496
614
|
"amount": float(order.amount) * 10**cur_scale,
|
|
497
615
|
"quantity": float(order.quantity) * 10**coin_scale,
|
|
498
616
|
"status": OrderStatus[Status(order.status).name],
|
|
499
|
-
"created_at":
|
|
500
|
-
"payed_at": order.transferDate != "0" and
|
|
501
|
-
"confirmed_at": Status(order.status) == Status.completed and
|
|
502
|
-
"appealed_at": order.status == 30 and
|
|
617
|
+
"created_at": ms2utc(order.createDate),
|
|
618
|
+
"payed_at": order.transferDate != "0" and ms2utc(order.transferDate) or None,
|
|
619
|
+
"confirmed_at": Status(order.status) == Status.completed and ms2utc(order.transferDate) or None,
|
|
620
|
+
"appealed_at": order.status == 30 and ms2utc(order.transferDate) or None,
|
|
503
621
|
"cred_id": ecredex.paymentType and credex.cred_id or None,
|
|
504
622
|
"taker": taker,
|
|
505
623
|
"ad": ad_db,
|
|
506
624
|
},
|
|
507
625
|
exid=order.id,
|
|
508
626
|
)
|
|
627
|
+
if order.status == Status.completed and ecredex.paymentType == 51:
|
|
628
|
+
await odb.fetch_related("cred", "transfer")
|
|
629
|
+
if odb.cred.detail != ecredex.accountNo:
|
|
630
|
+
...
|
|
631
|
+
frm = (odb.created_at + timedelta(minutes=180 - 1)).isoformat(sep=" ").split("+")[0]
|
|
632
|
+
to = ((odb.payed_at or odb.created_at) + timedelta(minutes=180 + 30)).isoformat(sep=" ").split("+")[0]
|
|
633
|
+
tsa = [
|
|
634
|
+
t
|
|
635
|
+
for tid, t in (self.hist.items() if self.hist else [])
|
|
636
|
+
if (ecredex.accountNo == t["to"] and t["from"] != "@merchant" and frm < t["date"] < to)
|
|
637
|
+
]
|
|
638
|
+
buyer_person = (
|
|
639
|
+
self.actor.person
|
|
640
|
+
if not order.side
|
|
641
|
+
else await self.ex_client.person_name_update(order.buyerRealName, int(order.targetUserId))
|
|
642
|
+
)
|
|
643
|
+
ts = [t for t in tsa if floor(fa := float(order.amount)) <= float(t["creditedAmount"]) <= round(fa)]
|
|
644
|
+
if len(ts) != 1:
|
|
645
|
+
if len(tsa) > 1:
|
|
646
|
+
summ = sum(float(t["creditedAmount"]) for t in tsa)
|
|
647
|
+
if floor(fa) <= summ <= round(fa):
|
|
648
|
+
for tr in tsa:
|
|
649
|
+
am = int(float(tr["creditedAmount"]) * 100)
|
|
650
|
+
await models.Transfer.create(
|
|
651
|
+
pmid=tr["id"], order=odb, amount=am, sender_acc=tr["from"], created_at=tr["date"]
|
|
652
|
+
)
|
|
653
|
+
else:
|
|
654
|
+
bcred, _ = await models.Cred.get_or_create(
|
|
655
|
+
{"detail": ts[0]["from"]}, person=buyer_person, pmcur_id=odb.cred.pmcur_id
|
|
656
|
+
)
|
|
657
|
+
am = int(float(ts[0]["creditedAmount"]) * 100)
|
|
658
|
+
try:
|
|
659
|
+
await models.Transfer.create(
|
|
660
|
+
pmid=ts[0]["id"], order=odb, amount=am, sender_acc=ts[0]["from"], created_at=ts[0]["date"]
|
|
661
|
+
)
|
|
662
|
+
except IntegrityError as e:
|
|
663
|
+
logging.error(e)
|
|
664
|
+
...
|
|
665
|
+
|
|
509
666
|
await odb.fetch_related("ad")
|
|
510
667
|
return odb
|
|
511
668
|
|
|
@@ -523,8 +680,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
523
680
|
page=page,
|
|
524
681
|
# status=status, # 50 - завершено
|
|
525
682
|
# tokenId=token_id,
|
|
526
|
-
beginTime=begin_time,
|
|
527
|
-
endTime=end_time,
|
|
683
|
+
# beginTime=begin_time,
|
|
684
|
+
# endTime=end_time,
|
|
528
685
|
# side=side, # 1 - продажа, 0 - покупка
|
|
529
686
|
size=30,
|
|
530
687
|
)
|
|
@@ -534,6 +691,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
534
691
|
await self.get_api_orders(page, begin_time, end_time) # , status, side, token_id)
|
|
535
692
|
ords = {int(o["id"]): OrderItem.model_validate(o) for o in lst["result"]["items"]}
|
|
536
693
|
for oid, o in ords.items():
|
|
694
|
+
if o.status != Status.completed.value or oid in self.completed_orders:
|
|
695
|
+
continue
|
|
537
696
|
fo = self.api.get_order_details(orderId=o.id)
|
|
538
697
|
order = OrderFull.model_validate(fo["result"])
|
|
539
698
|
order_db = await self.create_order(order)
|
|
@@ -557,6 +716,10 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
557
716
|
if len(ords) == 30:
|
|
558
717
|
await self.get_api_orders(page + 1, begin_time, end_time, status, side, token_id)
|
|
559
718
|
|
|
719
|
+
# async def order_stat(self, papi: PayeerAPI):
|
|
720
|
+
# for t in papi.history():
|
|
721
|
+
# os = self.api.get_orders(page=1, size=30)
|
|
722
|
+
|
|
560
723
|
async def mad_upd(self, mad: Ad, attrs: dict, cxids: list[str]):
|
|
561
724
|
if not [setattr(mad, k, v) for k, v in attrs.items() if getattr(mad, k) != v]:
|
|
562
725
|
print(end="v" if mad.side else "^", flush=True)
|
|
@@ -594,7 +757,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
594
757
|
# cad: Ad = ads[place] if cur_plc > place else ads[cur_plc]
|
|
595
758
|
# переделал пока на жесткую установку целевого места, даже если текущее выше:
|
|
596
759
|
if len(ads) <= target_place:
|
|
597
|
-
logging.error(f"target place {target_place} not found in ads
|
|
760
|
+
logging.error(f"target place {target_place} not found in ads {len(ads)}-lenght list")
|
|
761
|
+
target_place = len(ads) - 1
|
|
598
762
|
cad: Ad = ads[target_place]
|
|
599
763
|
# а цена обгоняемой объявы не выше нашего потолка?
|
|
600
764
|
if (float(cad.price) - ceil) * k <= 0:
|
|
@@ -613,10 +777,14 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
613
777
|
# if round(cpc * new_premium / cpm, 2) == m
|
|
614
778
|
# mad.premium = new_premium.to_eng_string()
|
|
615
779
|
|
|
616
|
-
async def
|
|
617
|
-
self
|
|
618
|
-
|
|
619
|
-
|
|
780
|
+
async def start_race(self):
|
|
781
|
+
races = await models.Race.filter(started=True, road__ad__maker_id=self.actor.id).prefetch_related(
|
|
782
|
+
"road__ad__pair_side__pair__cur", "road__credexs__cred", "road__ad__pms__pmexs__pm"
|
|
783
|
+
)
|
|
784
|
+
tasks = [create_task(self.racing(race), name=f"Rc{race.id}") for race in races]
|
|
785
|
+
return await gather(*tasks)
|
|
786
|
+
|
|
787
|
+
async def racing(self, race: models.Race):
|
|
620
788
|
coinex: models.CoinEx = await models.CoinEx.get(
|
|
621
789
|
coin_id=race.road.ad.pair_side.pair.coin_id, ex=self.actor.ex
|
|
622
790
|
).prefetch_related("coin")
|
|
@@ -624,11 +792,13 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
624
792
|
cur_id=race.road.ad.pair_side.pair.cur_id, ex=self.actor.ex
|
|
625
793
|
).prefetch_related("cur")
|
|
626
794
|
taker_side: bool = not race.road.ad.pair_side.is_sell
|
|
627
|
-
|
|
628
|
-
pmexs: list[models.PmEx] =
|
|
795
|
+
creds = [c.cred for c in race.road.credexs]
|
|
796
|
+
pmexs: list[models.PmEx] = [pmex for pm in race.road.ad.pms for pmex in pm.pmexs if pmex.ex_id == 4]
|
|
797
|
+
post_pm_ids = {c.cred.ovr_pm_id for c in race.road.credexs if c.cred.ovr_pm_id}
|
|
798
|
+
post_pmexs = set(await models.PmEx.filter(pm_id__in=post_pm_ids, ex=self.actor.ex).prefetch_related("pm"))
|
|
799
|
+
|
|
629
800
|
k = (-1) ** int(taker_side) # on_buy=1, on_sell=-1
|
|
630
801
|
sleep_sec = 3 # 1 if set(pms) & {"volet"} and coinex.coin_id == 1 else 5
|
|
631
|
-
creds: list[models.CredEx] = await self.get_credexs_by_pms(race.road.ad.pms, curex.cur_id)
|
|
632
802
|
_lstat, volume = None, 0
|
|
633
803
|
|
|
634
804
|
while self.actor.person.user.status > 0:
|
|
@@ -639,8 +809,9 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
639
809
|
continue
|
|
640
810
|
# если гонка дольше Х минут не обновлялась, обновляем ее (и ее пары) потолок
|
|
641
811
|
expiration = datetime.now(timezone.utc) - timedelta(minutes=15)
|
|
812
|
+
amt = race.filter_amount * 10**-curex.cur.scale if race.filter_amount else None
|
|
642
813
|
if race.updated_at < expiration:
|
|
643
|
-
ceils, hp, vmf, zplace = await self.get_ceils(coinex, curex, pmexs, 0.
|
|
814
|
+
ceils, hp, vmf, zplace = await self.get_ceils(coinex, curex, pmexs, 0.003, False, 0, amt, post_pmexs)
|
|
644
815
|
race.ceil = int(ceils[int(taker_side)] * 10**curex.scale)
|
|
645
816
|
await race.save()
|
|
646
817
|
# upd pair race
|
|
@@ -649,29 +820,28 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
649
820
|
road__ad__pair_side__is_sell=taker_side,
|
|
650
821
|
road__ad__maker=self.actor,
|
|
651
822
|
updated_at__lt=expiration,
|
|
652
|
-
|
|
653
|
-
pms_count=len(
|
|
823
|
+
road__credexs__id__in=[c.id for c in race.road.credexs],
|
|
824
|
+
pms_count=len(pmexs),
|
|
654
825
|
):
|
|
655
826
|
prace.ceil = int(ceils[int(not taker_side)] * 10**curex.scale)
|
|
656
827
|
await prace.save()
|
|
657
828
|
|
|
658
829
|
last_vol = volume
|
|
659
830
|
if taker_side: # гонка в стакане продажи - мы покупаем монету за ФИАТ
|
|
660
|
-
fiat = max(await models.Fiat.filter(cred_id__in=[c.
|
|
661
|
-
volume = fiat.amount / race.road.ad.price
|
|
831
|
+
fiat = max(await models.Fiat.filter(cred_id__in=[c.id for c in creds]), key=lambda x: x.amount)
|
|
832
|
+
volume = (fiat.amount * 10**-curex.cur.scale) / (race.road.ad.price * 10**-curex.scale)
|
|
662
833
|
else: # гонка в стакане покупки - мы продаем МОНЕТУ за фиат
|
|
663
834
|
asset = await models.Asset.get(addr__actor=self.actor, addr__coin_id=coinex.coin_id)
|
|
664
|
-
volume =
|
|
835
|
+
volume = asset.free * 10**-coinex.scale
|
|
665
836
|
volume = str(round(volume, coinex.scale))
|
|
837
|
+
try:
|
|
838
|
+
ads: list[Ad] = await self.ads(coinex, curex, taker_side, pmexs, amt, 50, race.vm_filter, post_pmexs)
|
|
839
|
+
except Exception:
|
|
840
|
+
await sleep(1)
|
|
841
|
+
ads: list[Ad] = await self.ads(coinex, curex, taker_side, pmexs, amt, 50, race.vm_filter, post_pmexs)
|
|
666
842
|
|
|
667
|
-
ads: list[Ad] = await self.ads(coinex, curex, taker_side, pmexs)
|
|
668
|
-
if race.vm_filter:
|
|
669
|
-
ads = [ad for ad in ads if "VA" in ad.authTag]
|
|
670
843
|
self.overprice_filter(ads, race.ceil * 10**-curex.scale, k) # обрезаем сверху все ads дороже нашего потолка
|
|
671
844
|
|
|
672
|
-
if 571 in pm_ids and coinex.coin.ticker == "USDT" and not taker_side:
|
|
673
|
-
...
|
|
674
|
-
|
|
675
845
|
if not ads:
|
|
676
846
|
print(coinex.exid, curex.exid, taker_side, "no ads!")
|
|
677
847
|
await sleep(15)
|
|
@@ -682,7 +852,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
682
852
|
await sleep(15)
|
|
683
853
|
continue
|
|
684
854
|
(cur_plc,) = cur_plc # может упасть если в списке > 1 наш ad
|
|
685
|
-
[(await self.
|
|
855
|
+
[(await self.ex_client.cond_load(ad, race.road.ad.pair_side, True))[0] for ad in ads[:cur_plc]]
|
|
686
856
|
# rivals = [
|
|
687
857
|
# (await models.RaceStat.update_or_create({"place": plc, "price": ad.price, "premium": ad.premium}, ad=ad))[
|
|
688
858
|
# 0
|
|
@@ -703,7 +873,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
703
873
|
continue
|
|
704
874
|
if not (cad := self.get_cad(ads, race.ceil * 10**-curex.scale, k, race.target_place, cur_plc)):
|
|
705
875
|
continue
|
|
706
|
-
new_price = round(float(cad.price) - k * step(mad, cad, curex.
|
|
876
|
+
new_price = round(float(cad.price) - k * step(mad, cad, curex.scale), curex.scale)
|
|
707
877
|
if (
|
|
708
878
|
float(mad.price) == new_price and volume == last_vol
|
|
709
879
|
): # Если место уже нужное или нужная цена и так уже стоит
|
|
@@ -715,23 +885,23 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
715
885
|
await sleep(sleep_sec)
|
|
716
886
|
continue
|
|
717
887
|
if cad.priceType: # Если цена конкурента плавающая, то повышаем себе не цену, а %
|
|
718
|
-
new_premium = float(cad.premium) - k * step(mad, cad, 2)
|
|
719
|
-
if float(mad.premium) == new_premium: # Если нужный % и так уже стоит
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
888
|
+
new_premium = (float(mad.premium) or float(cad.premium)) - k * step(mad, cad, 2)
|
|
889
|
+
# if float(mad.premium) == new_premium: # Если нужный % и так уже стоит
|
|
890
|
+
# if mad.priceType and cur_plc != race.target_place:
|
|
891
|
+
# new_premium -= k * step(mad, cad, 2)
|
|
892
|
+
# elif volume == last_vol:
|
|
893
|
+
# print(end="v" if taker_side else "^", flush=True)
|
|
894
|
+
# await sleep(sleep_sec)
|
|
895
|
+
# continue
|
|
726
896
|
mad.premium = str(round(new_premium, 2))
|
|
727
897
|
mad.priceType = cad.priceType
|
|
728
898
|
mad.quantity = volume
|
|
729
|
-
mad.maxAmount = str(2_000_000)
|
|
899
|
+
mad.maxAmount = str(2_000_000 if curex.cur_id == 1 else 40_000)
|
|
730
900
|
req = AdUpdateRequest.model_validate(
|
|
731
901
|
{
|
|
732
902
|
**mad.model_dump(),
|
|
733
903
|
"price": str(round(new_price, curex.scale)),
|
|
734
|
-
"paymentIds": [str(
|
|
904
|
+
"paymentIds": [str(cx.exid) for cx in race.road.credexs],
|
|
735
905
|
}
|
|
736
906
|
)
|
|
737
907
|
try:
|
|
@@ -755,26 +925,26 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
755
925
|
raise e
|
|
756
926
|
elif ExcCode(e.status_code) == ExcCode.InsufficientBalance:
|
|
757
927
|
asset = await models.Asset.get(addr__actor=self.actor, addr__coin_id=coinex.coin_id)
|
|
758
|
-
req.quantity = str(
|
|
759
|
-
round(
|
|
760
|
-
(asset.free - (asset.freeze or 0) - (asset.lock or 0)) * 10**-coinex.scale,
|
|
761
|
-
coinex.coin.scale or coinex.scale,
|
|
762
|
-
)
|
|
763
|
-
)
|
|
928
|
+
req.quantity = str(round(asset.free * 10**-coinex.scale, coinex.scale))
|
|
764
929
|
_res = self.ad_upd(req)
|
|
765
930
|
elif ExcCode(e.status_code) == ExcCode.RareLimit:
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
931
|
+
if not (
|
|
932
|
+
sads := [
|
|
933
|
+
ma
|
|
934
|
+
for ma in self.my_ads(False)
|
|
935
|
+
if (
|
|
936
|
+
ma.currencyId == curex.exid
|
|
937
|
+
and ma.tokenId == coinex.exid
|
|
938
|
+
and taker_side != ma.side
|
|
939
|
+
and set(ma.payments) == set([pe.exid for pe in pmexs])
|
|
940
|
+
)
|
|
941
|
+
]
|
|
942
|
+
):
|
|
943
|
+
logging.error(f"Need reserve Ad {'sell' if taker_side else 'buy'} {coinex.exid}/{curex.exid}")
|
|
944
|
+
await sleep(90)
|
|
945
|
+
continue
|
|
776
946
|
self.ad_del(ad_id=int(mad.id))
|
|
777
|
-
req.id =
|
|
947
|
+
req.id = sads[0].id
|
|
778
948
|
req.actionType = "ACTIVE"
|
|
779
949
|
self.api.update_ad(**req.model_dump())
|
|
780
950
|
logging.warning(f"Ad#{mad.id} recreated")
|
|
@@ -787,10 +957,15 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
787
957
|
await sleep(6)
|
|
788
958
|
|
|
789
959
|
async def get_books(
|
|
790
|
-
self,
|
|
960
|
+
self,
|
|
961
|
+
coinex: models.CoinEx,
|
|
962
|
+
curex: models.CurEx,
|
|
963
|
+
pmexs: list[models.PmEx],
|
|
964
|
+
amount: int,
|
|
965
|
+
post_pmexs: list[models.PmEx] = None,
|
|
791
966
|
) -> tuple[list[Ad], list[Ad]]:
|
|
792
|
-
buy: list[Ad] = await self.ads(coinex, curex, False, pmexs,
|
|
793
|
-
sell: list[Ad] = await self.ads(coinex, curex, True, pmexs,
|
|
967
|
+
buy: list[Ad] = await self.ads(coinex, curex, False, pmexs, amount, 40, False, post_pmexs)
|
|
968
|
+
sell: list[Ad] = await self.ads(coinex, curex, True, pmexs, amount, 30, False, post_pmexs)
|
|
794
969
|
return buy, sell
|
|
795
970
|
|
|
796
971
|
async def get_spread(
|
|
@@ -800,12 +975,12 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
800
975
|
...
|
|
801
976
|
buy_price, sell_price = float(bb[place].price), float(sb[place].price)
|
|
802
977
|
half_spread = (buy_price - sell_price) / (buy_price + sell_price)
|
|
803
|
-
if half_spread * 2 < perc:
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
978
|
+
# if half_spread * 2 < perc: # todo: aA???
|
|
979
|
+
# if not exact:
|
|
980
|
+
# if vmf is None: # сначала фильтруем только VA
|
|
981
|
+
# return await self.get_spread(bb, sb, perc, True, place)
|
|
982
|
+
# # если даже по VA не хватает спреда - увеличиваем место
|
|
983
|
+
# return await self.get_spread(bb, sb, perc, vmf, place + 1)
|
|
809
984
|
|
|
810
985
|
return (buy_price, sell_price), half_spread, vmf, place
|
|
811
986
|
|
|
@@ -817,301 +992,159 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
817
992
|
min_prof=0.02,
|
|
818
993
|
vmf: bool = False,
|
|
819
994
|
place: int = 0,
|
|
995
|
+
amount: int = None,
|
|
996
|
+
post_pmexs: set[models.PmEx] = None,
|
|
820
997
|
) -> tuple[tuple[float, float], float, bool, int]: # todo: refact to Pairex
|
|
821
|
-
bb, sb = await self.get_books(coinex, curex, pmexs)
|
|
998
|
+
bb, sb = await self.get_books(coinex, curex, pmexs, amount, post_pmexs)
|
|
822
999
|
if vmf:
|
|
1000
|
+
# ориентируемся на цены объявлений только проверенных мерчантов
|
|
823
1001
|
bb = [b for b in bb if "VA" in b.authTag]
|
|
824
1002
|
sb = [s for s in sb if "VA" in s.authTag]
|
|
825
|
-
perc = pmexs[0].pm.fee * 0.0001 + min_prof
|
|
1003
|
+
perc = list(post_pmexs or pmexs)[0].pm.fee * 0.0001 + min_prof
|
|
826
1004
|
(bf, sf), hp, vmf, zplace = await self.get_spread(bb, sb, perc, vmf, place)
|
|
827
1005
|
mdl = (bf + sf) / 2
|
|
828
1006
|
bc, sc = mdl + mdl * (perc / 2), mdl - mdl * (perc / 2)
|
|
829
1007
|
return (bc, sc), hp, vmf, zplace
|
|
830
1008
|
|
|
831
|
-
async def
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1009
|
+
async def take_ad(self, req: TakeAdReq):
|
|
1010
|
+
if req.price and req.is_sell and req.cur_:
|
|
1011
|
+
... # todo call the get_ad_details() only if lack of data
|
|
1012
|
+
# res = self.api.get_ad_details(itemId=req.ad_id)["result"]
|
|
1013
|
+
# ad: Ad = Ad.model_validate(res)
|
|
1014
|
+
# pmexs = await models.PmEx.filter(ex_id=self.actor.ex_id, pm_id=req.pm_id)
|
|
1015
|
+
# if len(pmexs) > 1:
|
|
1016
|
+
# pmexs = [p for p in pmexs if p.exid in ad.payments]
|
|
1017
|
+
#
|
|
1018
|
+
# # todo: map pm->cred_pattern
|
|
1019
|
+
# pmexid = exids.pop() if (exids := set(ad.payments) & set(px.exid for px in pmexs)) else "40"
|
|
1020
|
+
pmexid = str(req.pm_id)
|
|
1021
|
+
coinex = await models.CoinEx.get(coin_id=req.coin_id, ex=self.ex_client.ex)
|
|
1022
|
+
curex = await models.CurEx.get(cur_id=req.cur_id, ex=self.ex_client.ex)
|
|
1023
|
+
|
|
1024
|
+
# if ad.side: # продажа, я (тейкер) покупатель
|
|
1025
|
+
# pmexs = await models.PmEx.filter(ex_id=self.actor.ex_id, pm_id=req.pm_id)
|
|
1026
|
+
# if len(pmexs) > 1:
|
|
1027
|
+
# pmexs = [p for p in pmexs if p.name.endswith(f" ({ad.currencyId})")]
|
|
1028
|
+
# else:
|
|
1029
|
+
# pmexs = await models.CredEx.filter(
|
|
1030
|
+
# ex_id=self.actor.ex_id, cred__person_id=self.actor.person_id,
|
|
1031
|
+
# cred__pmcur__pm_id=req.pm_id, cred__pmcur__cur__ticker=ad.currencyId
|
|
1032
|
+
# )
|
|
1033
|
+
# req.pm_id = pmexs[0].exid
|
|
1034
|
+
# req.quantity = round(req.amount / float(ad.price) - 0.00005, 4) # todo: to get the scale from coinEx
|
|
1035
|
+
|
|
1036
|
+
bor = BaseOrderReq(
|
|
1037
|
+
ad_id=str(req.ad_id),
|
|
1038
|
+
fiat_amount=req.amount,
|
|
1039
|
+
is_sell=req.is_sell,
|
|
1040
|
+
cur_exid=curex.exid,
|
|
1041
|
+
coin_exid=coinex.exid,
|
|
1042
|
+
coin_scale=coinex.scale,
|
|
1043
|
+
pmex_exid=pmexid,
|
|
861
1044
|
)
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
if int(
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
await ad_db.save()
|
|
906
|
-
logging.info(f"{ad.nickName} upd cond#{ad_db.cond_id}->{cid}")
|
|
907
|
-
# old_cid = ad_db.cond_id # todo: solve race-condition, а пока что очищаем при каждом запуске
|
|
908
|
-
# if not len((old_cond := await Cond.get(id=old_cid).prefetch_related('ads')).ads):
|
|
909
|
-
# await old_cond.delete()
|
|
910
|
-
# logging.warning(f"Cond#{old_cid} deleted!")
|
|
911
|
-
return (ad_db or force and await self.ad_create(ad, cid, rname, ps)), False
|
|
912
|
-
# если эта объява в таким ид уже есть в бд, но с другим условием (или без), а текущего условия еще нет в бд
|
|
913
|
-
if ad_db:
|
|
914
|
-
await ad_db.fetch_related("cond__ads", "maker")
|
|
915
|
-
if not ad_db.cond_id or (
|
|
916
|
-
# у измененного условия этой объявы есть другие объявы?
|
|
917
|
-
(rest_ads := set(ad_db.cond.ads) - {ad_db})
|
|
918
|
-
and
|
|
919
|
-
# другие объявы этого условия принадлежат другим юзерам
|
|
920
|
-
{ra.maker_id for ra in rest_ads} - {ad_db.maker_id}
|
|
921
|
-
):
|
|
922
|
-
# создадим новое условие и присвоим его только текущей объяве
|
|
923
|
-
cid = await self.cond_new(cleaned, {int(ad.userId)})
|
|
924
|
-
ad_db.cond_id = cid
|
|
925
|
-
await ad_db.save()
|
|
926
|
-
|
|
927
|
-
return ad_db, True
|
|
928
|
-
# а если других объяв со старым условием этой обявы нет, либо они все этого же юзера
|
|
929
|
-
# обновляем условие (в тч во всех ЕГО объявах)
|
|
930
|
-
ad_db.cond.last_ver = ad_db.cond.raw_txt
|
|
931
|
-
ad_db.cond.raw_txt = cleaned
|
|
932
|
-
await ad_db.cond.save()
|
|
933
|
-
await self.cond_upd(ad_db.cond, {ad_db.maker.exid})
|
|
934
|
-
# и подправим коэфициенты похожести нового текста
|
|
935
|
-
await self.fix_rel_sims(ad_db.cond_id, cleaned)
|
|
936
|
-
return ad_db, False
|
|
937
|
-
|
|
938
|
-
cid = await self.cond_new(cleaned, {int(ad.userId)})
|
|
939
|
-
return await self.ad_create(ad, cid, rname, ps), True
|
|
940
|
-
|
|
941
|
-
async def cond_new(self, txt: str, uids: set[int]) -> int:
|
|
942
|
-
new_cond, _ = await Cond.update_or_create(raw_txt=txt)
|
|
943
|
-
# и максимально похожую связь для нового условия (если есть >= 60%)
|
|
944
|
-
await self.cond_upd(new_cond, uids)
|
|
945
|
-
return new_cond.id
|
|
946
|
-
|
|
947
|
-
async def cond_upd(self, cond: Cond, uids: set[int]):
|
|
948
|
-
self.all_conds[cond.id] = cond.raw_txt, uids
|
|
949
|
-
# и максимально похожую связь для нового условия (если есть >= 60%)
|
|
950
|
-
old_cid, sim = await self.cond_get_max_sim(cond.id, cond.raw_txt, uids)
|
|
951
|
-
await self.actual_sim(cond.id, old_cid, sim)
|
|
952
|
-
|
|
953
|
-
def find_in_tree(self, cid: int, old_cid: int) -> bool:
|
|
954
|
-
if p := self.cond_sims.get(old_cid):
|
|
955
|
-
if p == cid:
|
|
956
|
-
return True
|
|
957
|
-
return self.find_in_tree(cid, p)
|
|
958
|
-
return False
|
|
959
|
-
|
|
960
|
-
async def cond_get_max_sim(self, cid: int, txt: str, uids: set[int]) -> tuple[int | None, int | None]:
|
|
961
|
-
# находим все старые тексты похожие на 90% и более
|
|
962
|
-
if len(txt) < 15:
|
|
963
|
-
return None, None
|
|
964
|
-
sims: dict[int, int] = {}
|
|
965
|
-
for old_cid, (old_txt, old_uids) in self.all_conds.items():
|
|
966
|
-
if len(old_txt) < 15 or uids == old_uids:
|
|
967
|
-
continue
|
|
968
|
-
elif not self.can_add_sim(cid, old_cid):
|
|
969
|
-
continue
|
|
970
|
-
if sim := get_sim(txt, old_txt):
|
|
971
|
-
sims[old_cid] = sim
|
|
972
|
-
# если есть, берем самый похожий из них
|
|
973
|
-
if sims:
|
|
974
|
-
old_cid, sim = max(sims.items(), key=lambda x: x[1])
|
|
975
|
-
await sleep(0.3)
|
|
976
|
-
return old_cid, sim
|
|
977
|
-
return None, None
|
|
978
|
-
|
|
979
|
-
def can_add_sim(self, cid: int, old_cid: int) -> bool:
|
|
980
|
-
if cid == old_cid:
|
|
981
|
-
return False
|
|
982
|
-
elif self.cond_sims.get(cid) == old_cid:
|
|
983
|
-
return False
|
|
984
|
-
elif self.find_in_tree(cid, old_cid):
|
|
985
|
-
return False
|
|
986
|
-
elif self.cond_sims.get(old_cid) == cid:
|
|
987
|
-
return False
|
|
988
|
-
elif cid in self.rcond_sims.get(old_cid, {}):
|
|
989
|
-
return False
|
|
990
|
-
elif old_cid in self.rcond_sims.get(cid, {}):
|
|
991
|
-
return False
|
|
992
|
-
return True
|
|
993
|
-
|
|
994
|
-
async def person_upsert(self, name: str, exid: int) -> models.Person:
|
|
995
|
-
if actor := await models.Actor.get_or_none(exid=exid, ex=self.ex_client.ex).prefetch_related("person"):
|
|
996
|
-
if not actor.person:
|
|
997
|
-
actor.person = await models.Person.create(name=name)
|
|
998
|
-
await actor.save()
|
|
999
|
-
return actor.person
|
|
1000
|
-
return await models.Person.create(name=name)
|
|
1001
|
-
|
|
1002
|
-
async def ad_create(
|
|
1003
|
-
self, ad: Ad, cid: int = None, rname: str = None, ps: PairSide = None, actor: Actor = None
|
|
1004
|
-
) -> models.Ad:
|
|
1005
|
-
act_df = {}
|
|
1006
|
-
if int(ad.userId) != self.actor.exid:
|
|
1007
|
-
act_df |= {"name": ad.nickName}
|
|
1008
|
-
if rname:
|
|
1009
|
-
act_df |= {"person": await self.person_upsert(rname, int(ad.userId))}
|
|
1010
|
-
if not actor:
|
|
1011
|
-
act_df |= {"person": await self.person_upsert(ad.nickName, int(ad.userId))}
|
|
1012
|
-
actor, _ = await Actor.update_or_create(act_df, exid=ad.userId, ex=self.ex_client.ex)
|
|
1013
|
-
ps = ps or await PairSide.get_or_none(
|
|
1014
|
-
is_sell=ad.side,
|
|
1015
|
-
pair__coin__ticker=ad.tokenId,
|
|
1016
|
-
pair__cur__ticker=ad.currencyId,
|
|
1017
|
-
).prefetch_related("pair__cur", "pair__coin")
|
|
1018
|
-
if not ps or not ps.pair:
|
|
1019
|
-
... # THB/USDC
|
|
1020
|
-
ad_upd = models.Ad.validate(ad.model_dump(by_alias=True))
|
|
1021
|
-
cur_scale = 10**ps.pair.cur.scale
|
|
1022
|
-
coinex = await models.CoinEx.get(coin_id=ps.pair.coin_id, ex=self.ex_client.ex)
|
|
1023
|
-
df_unq = ad_upd.df_unq(
|
|
1024
|
-
maker_id=actor.id,
|
|
1025
|
-
pair_side_id=ps.id,
|
|
1026
|
-
amount=int(float(ad.quantity) * float(ad.price) * cur_scale),
|
|
1027
|
-
quantity=int(float(ad.quantity) * 10**coinex.scale),
|
|
1028
|
-
min_fiat=int(float(ad.minAmount) * cur_scale),
|
|
1029
|
-
max_fiat=ad.maxAmount and int(float(ad.maxAmount) * cur_scale),
|
|
1030
|
-
price=int(float(ad.price) * cur_scale),
|
|
1031
|
-
premium=int(float(ad.premium) * cur_scale),
|
|
1032
|
-
)
|
|
1033
|
-
ad_db, _ = await models.Ad.update_or_create(**df_unq)
|
|
1034
|
-
await ad_db.pms.add(*(await models.Pm.filter(pmexs__ex=self.ex_client.ex, pmexs__exid__in=ad.payments)))
|
|
1035
|
-
return ad_db
|
|
1036
|
-
|
|
1037
|
-
async def fix_rel_sims(self, cid: int, new_txt: str):
|
|
1038
|
-
for rel_sim in await CondSim.filter(cond_rel_id=cid).prefetch_related("cond"):
|
|
1039
|
-
if sim := get_sim(new_txt, rel_sim.cond.raw_txt):
|
|
1040
|
-
rel_sim.similarity = sim
|
|
1041
|
-
await rel_sim.save()
|
|
1042
|
-
else:
|
|
1043
|
-
await rel_sim.delete()
|
|
1044
|
-
|
|
1045
|
-
async def actual_cond(self):
|
|
1046
|
-
for curr, old in await CondSim.all().values_list("cond_id", "cond_rel_id"):
|
|
1047
|
-
self.cond_sims[curr] = old
|
|
1048
|
-
self.rcond_sims[old] |= {curr}
|
|
1049
|
-
for cid, (txt, uids) in self.all_conds.items():
|
|
1050
|
-
old_cid, sim = await self.cond_get_max_sim(cid, txt, uids)
|
|
1051
|
-
await self.actual_sim(cid, old_cid, sim)
|
|
1052
|
-
# хз бля чо это ваще
|
|
1053
|
-
# for ad_db in await models.Ad.filter(direction__pairex__ex=self.ex_client.ex).prefetch_related("cond", "maker"):
|
|
1054
|
-
# ad = Ad(id=str(ad_db.exid), userId=str(ad_db.maker.exid), remark=ad_db.cond.raw_txt)
|
|
1055
|
-
# await self.cond_upsert(ad, force=True)
|
|
1056
|
-
|
|
1057
|
-
async def actual_sim(self, cid: int, old_cid: int, sim: int):
|
|
1058
|
-
if not sim:
|
|
1059
|
-
return
|
|
1060
|
-
if old_sim := await CondSim.get_or_none(cond_id=cid):
|
|
1061
|
-
if old_sim.cond_rel_id != old_cid:
|
|
1062
|
-
if sim > old_sim.similarity:
|
|
1063
|
-
logging.warning(f"R {cid}: {old_sim.similarity}->{sim} ({old_sim.cond_rel_id}->{old_cid})")
|
|
1064
|
-
await old_sim.update_from_dict({"similarity": sim, "old_rel_id": old_cid}).save()
|
|
1065
|
-
self._cond_sim_upd(cid, old_cid)
|
|
1066
|
-
elif sim != old_sim.similarity:
|
|
1067
|
-
logging.info(f"{cid}: {old_sim.similarity}->{sim}")
|
|
1068
|
-
await old_sim.update_from_dict({"similarity": sim}).save()
|
|
1069
|
-
else:
|
|
1070
|
-
await CondSim.create(cond_id=cid, cond_rel_id=old_cid, similarity=sim)
|
|
1071
|
-
self._cond_sim_upd(cid, old_cid)
|
|
1072
|
-
|
|
1073
|
-
def _cond_sim_upd(self, cid: int, old_cid: int):
|
|
1074
|
-
if old_old_cid := self.cond_sims.get(cid): # если старый cid уже был в дереве:
|
|
1075
|
-
self.rcond_sims[old_old_cid].remove(cid) # удаляем из обратного
|
|
1076
|
-
self.cond_sims[cid] = old_cid # а в прямом он автоматом переопределится, даже если и был
|
|
1077
|
-
self.rcond_sims[old_cid] |= {cid} # ну и в обратное добавим новый
|
|
1078
|
-
|
|
1079
|
-
async def get_credexs_by_pms(self, pms: list[models.Pm], cur_id: int) -> list[models.CredEx]:
|
|
1080
|
-
return await models.CredEx.filter(
|
|
1081
|
-
ex_id=self.actor.ex_id,
|
|
1082
|
-
cred__pmcur__pm_id__in=[pm.id for pm in pms],
|
|
1083
|
-
cred__person_id=self.actor.person_id,
|
|
1084
|
-
cred__pmcur__cur_id=cur_id,
|
|
1085
|
-
)
|
|
1086
|
-
|
|
1087
|
-
def build_tree(self):
|
|
1088
|
-
set(self.cond_sims.keys()) | set(self.cond_sims.values())
|
|
1089
|
-
tree = defaultdict(dict)
|
|
1090
|
-
# Группируем родителей по детям
|
|
1091
|
-
for child, par in self.cond_sims.items():
|
|
1092
|
-
tree[par] |= {child: {}} # todo: make from self.rcond_sim
|
|
1093
|
-
|
|
1094
|
-
# Строим дерево снизу вверх
|
|
1095
|
-
def subtree(node):
|
|
1096
|
-
if not node:
|
|
1097
|
-
return node
|
|
1098
|
-
for key in node:
|
|
1099
|
-
subnode = tree.pop(key, {})
|
|
1100
|
-
d = subtree(subnode)
|
|
1101
|
-
node[key] |= d # actual tree rebuilding here!
|
|
1102
|
-
return node # todo: refact?
|
|
1103
|
-
|
|
1104
|
-
# Находим корни / без родителей
|
|
1105
|
-
roots = set(self.cond_sims.values()) - set(self.cond_sims.keys())
|
|
1106
|
-
for root in roots:
|
|
1107
|
-
_ = subtree(tree[root])
|
|
1108
|
-
|
|
1109
|
-
self.tree = tree
|
|
1110
|
-
|
|
1045
|
+
resp: OrderResp = await self._order_request(bor)
|
|
1046
|
+
return resp
|
|
1047
|
+
|
|
1048
|
+
async def watch_payeer(self, mcs: dict[int, "AgentClient"]):
|
|
1049
|
+
coinex: models.CoinEx = await models.CoinEx.get(coin_id=1, ex=self.actor.ex).prefetch_related("coin")
|
|
1050
|
+
curex: models.CurEx = await models.CurEx.get(cur_id=1, ex=self.actor.ex).prefetch_related("cur")
|
|
1051
|
+
post_pmexs = set(await models.PmEx.filter(pm_id=366, ex=self.actor.ex).prefetch_related("pm"))
|
|
1052
|
+
i = 0
|
|
1053
|
+
while True:
|
|
1054
|
+
try:
|
|
1055
|
+
ss = await self.ads(coinex, curex, True, None, None, 1000, False, post_pmexs)
|
|
1056
|
+
ss = [s for s in ss if float(s.price) > 90.42 or int(s.userId) in mcs.keys()]
|
|
1057
|
+
if ss:
|
|
1058
|
+
ad: Ad = ss[0]
|
|
1059
|
+
await self.bbot.send(
|
|
1060
|
+
193017646,
|
|
1061
|
+
f"price: {ad.price}\nnick: {ad.nickName}\nprice: {ad.price}"
|
|
1062
|
+
f"\nqty: {ad.quantity} [{ad.minAmount}-{ad.maxAmount}]",
|
|
1063
|
+
)
|
|
1064
|
+
am = min(float(ad.maxAmount), max(1000 + i, float(ad.minAmount)))
|
|
1065
|
+
req = TakeAdReq(
|
|
1066
|
+
ad_id=ad.id,
|
|
1067
|
+
amount=am,
|
|
1068
|
+
pm_id=14,
|
|
1069
|
+
is_sell=True,
|
|
1070
|
+
coin_id=1,
|
|
1071
|
+
cur_id=1,
|
|
1072
|
+
)
|
|
1073
|
+
ord_resp: OrderResp = await self.take_ad(req)
|
|
1074
|
+
# order: OrderFull = OrderFull(**self.api.get_order_details(orderId=ord_resp.orderId)["result"])
|
|
1075
|
+
order: OrderFull = await self.get_order_info(ord_resp.orderId)
|
|
1076
|
+
odb = await self.create_order(order)
|
|
1077
|
+
# t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
1078
|
+
# await t.fetch_related("order__cred__pmcur__cur")
|
|
1079
|
+
# res = await self.pm_clients[366].check_in(t)
|
|
1080
|
+
if int(ad.userId) in mcs:
|
|
1081
|
+
mcs[int(ad.userId)].api.mark_as_paid(
|
|
1082
|
+
orderId=str(odb.exid),
|
|
1083
|
+
paymentType=ad.payments[0], # pmex.exid
|
|
1084
|
+
paymentId=order.paymentTermList[0].id, # credex.exid
|
|
1085
|
+
)
|
|
1086
|
+
self.api.release_assets(orderId=order.id)
|
|
1087
|
+
...
|
|
1111
1088
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1089
|
+
bs = await self.ads(coinex, curex, False, None, None, 1000, False, post_pmexs)
|
|
1090
|
+
bs = [b for b in bs if float(b.price) < 89.56 or int(b.userId) in mcs.keys()]
|
|
1091
|
+
if bs:
|
|
1092
|
+
ad: Ad = bs[0]
|
|
1093
|
+
await self.bbot.send(
|
|
1094
|
+
193017646,
|
|
1095
|
+
f"price: {ad.price}\nnick: {ad.nickName}\nprice: {ad.price}"
|
|
1096
|
+
f"\nqty: {ad.quantity} [{ad.minAmount}-{ad.maxAmount}]",
|
|
1097
|
+
)
|
|
1098
|
+
am = min(float(ad.maxAmount), max(600 + i, float(ad.minAmount)))
|
|
1099
|
+
req = TakeAdReq(
|
|
1100
|
+
ad_id=ad.id,
|
|
1101
|
+
amount=am,
|
|
1102
|
+
pm_id=14,
|
|
1103
|
+
is_sell=False,
|
|
1104
|
+
coin_id=1,
|
|
1105
|
+
cur_id=1,
|
|
1106
|
+
)
|
|
1107
|
+
ord_resp: OrderResp = await self.take_ad(req)
|
|
1108
|
+
# order: OrderFull = OrderFull(**self.api.get_order_details(orderId=ord_resp.orderId)["result"])
|
|
1109
|
+
order: OrderFull = await self.get_order_info(ord_resp.orderId)
|
|
1110
|
+
odb = await self.create_order(order)
|
|
1111
|
+
t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
1112
|
+
await t.fetch_related("order__cred__pmcur__cur")
|
|
1113
|
+
# res = await self.pm_clients[366].send(t)
|
|
1114
|
+
self.api.mark_as_paid(
|
|
1115
|
+
orderId=str(odb.exid),
|
|
1116
|
+
paymentType=ad.payments[0], # pmex.exid
|
|
1117
|
+
paymentId=order.paymentTermList[0].id, # credex.exid
|
|
1118
|
+
)
|
|
1119
|
+
if int(ad.userId) in mcs:
|
|
1120
|
+
mcs[int(ad.userId)].api.release_assets(orderId=order.id)
|
|
1121
|
+
await sleep(1)
|
|
1122
|
+
...
|
|
1123
|
+
except Exception as e:
|
|
1124
|
+
logging.exception(e)
|
|
1125
|
+
await sleep(90)
|
|
1126
|
+
except HttpProcessingError as e:
|
|
1127
|
+
logging.error(e)
|
|
1128
|
+
print(end=".", flush=True)
|
|
1129
|
+
i += 1
|
|
1130
|
+
await sleep(5)
|
|
1131
|
+
|
|
1132
|
+
async def boost_acc(self):
|
|
1133
|
+
await sleep(45)
|
|
1134
|
+
for i in range(10):
|
|
1135
|
+
am = 500 + i
|
|
1136
|
+
req = TakeAdReq(ad_id="1856989782009487360", amount=am, pm_id=366)
|
|
1137
|
+
ord_resp: OrderResp = await self.take_ad(req)
|
|
1138
|
+
order: OrderFull = OrderFull(**self.api.get_order_details(orderId=ord_resp.orderId)["result"])
|
|
1139
|
+
odb = await self.create_order(order)
|
|
1140
|
+
t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
1141
|
+
await t.fetch_related("order__cred__pmcur__cur")
|
|
1142
|
+
await self.pm_clients[366].send(t)
|
|
1143
|
+
...
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
def ms2utc(msk_ts_str: str):
|
|
1147
|
+
return datetime.fromtimestamp(int(msk_ts_str) / 1000, timezone(timedelta(hours=3), name="MSK"))
|
|
1115
1148
|
|
|
1116
1149
|
|
|
1117
1150
|
def detailed_diff(str1, str2):
|
|
@@ -1131,17 +1164,9 @@ def detailed_diff(str1, str2):
|
|
|
1131
1164
|
return "".join(result)
|
|
1132
1165
|
|
|
1133
1166
|
|
|
1134
|
-
def clean(s) -> str:
|
|
1135
|
-
clear = r"[^\w\s.,!?;:()\-]"
|
|
1136
|
-
repeat = r"(.)\1{2,}"
|
|
1137
|
-
s = re.sub(clear, "", s).lower()
|
|
1138
|
-
s = re.sub(repeat, r"\1", s)
|
|
1139
|
-
return s.replace("\n\n", "\n").replace(" ", " ").strip(" \n/.,!?-")
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
1167
|
def step_is_need(mad, cad) -> bool:
|
|
1143
1168
|
# todo: пока не решен непонятный кейс, почему то конкурент по всем параметрам слабже, но в списке ранжируется выше.
|
|
1144
|
-
# текущая версия: recentExecuteRate округляется до целого, но на бэке его дробная часть больше
|
|
1169
|
+
# текущая версия: recentExecuteRate округляется до целого, но на бэке байбита его дробная часть больше
|
|
1145
1170
|
return (
|
|
1146
1171
|
bool(set(cad.authTag) & {"VA2", "BA"})
|
|
1147
1172
|
or cad.recentExecuteRate > mad.recentExecuteRate
|
|
@@ -1163,115 +1188,102 @@ class ExcCode(IntEnum):
|
|
|
1163
1188
|
Timestamp = 10002
|
|
1164
1189
|
IP = 10010
|
|
1165
1190
|
Quantity = 912300019
|
|
1191
|
+
PayMethod = 912300013
|
|
1166
1192
|
Unknown = 912300014
|
|
1167
1193
|
|
|
1168
1194
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1195
|
+
@post_save(models.Race)
|
|
1196
|
+
async def race_upserted(
|
|
1197
|
+
_cls: type[models.Race], race: models.Race, created: bool, _db: BaseDBAsyncClient, _updated: list[str]
|
|
1198
|
+
):
|
|
1199
|
+
logging.warning(f"Race {race.id} is now upserted")
|
|
1200
|
+
asyncio.all_tasks()
|
|
1201
|
+
if created:
|
|
1202
|
+
...
|
|
1203
|
+
else: # параметры гонки изменены
|
|
1204
|
+
...
|
|
1172
1205
|
|
|
1173
|
-
@post_save(models.Race)
|
|
1174
|
-
async def race_upserted(
|
|
1175
|
-
_cls: type[models.Race], race: models.Race, created: bool, _db: BaseDBAsyncClient, _updated: list[str]
|
|
1176
|
-
):
|
|
1177
|
-
logging.warning(f"Race {race.id} is now upserted")
|
|
1178
|
-
asyncio.all_tasks()
|
|
1179
|
-
if created:
|
|
1180
|
-
...
|
|
1181
|
-
else: # параметры гонки изменены
|
|
1182
|
-
...
|
|
1183
|
-
|
|
1184
|
-
actor = (
|
|
1185
|
-
await models.Actor.filter(ex_id=4, agent__isnull=False).prefetch_related("ex", "agent", "person__user").first()
|
|
1186
|
-
)
|
|
1187
|
-
async with FileClient(TOKEN) as b:
|
|
1188
|
-
b: FileClient
|
|
1189
|
-
# b.add_handler(MessageHandler(cond_start_handler, command("cond")))
|
|
1190
|
-
cl: AgentClient = actor.client(b)
|
|
1191
|
-
|
|
1192
|
-
# await cl.ex_client.set_pairs()
|
|
1193
|
-
# await cl.ex_client.set_pms()
|
|
1194
|
-
# await cl.set_creds()
|
|
1195
|
-
# await cl.export_my_ads()
|
|
1196
|
-
|
|
1197
|
-
# создание гонок по мои активным объявам:
|
|
1198
|
-
# for ma in cl.my_ads():
|
|
1199
|
-
# my_ad = await models.MyAd.get(ad__exid=ma.id).prefetch_related('ad__pms', 'ad__pair_side__pair')
|
|
1200
|
-
# race, _ = await models.Race.update_or_create(
|
|
1201
|
-
# {"started": True, "vm_filter": True, "target_place": 5},
|
|
1202
|
-
# road=my_ad
|
|
1203
|
-
# )
|
|
1204
|
-
|
|
1205
|
-
# for name in names:
|
|
1206
|
-
# s, _ = await models.Synonym.update_or_create(typ=SynonymType.name, txt=name)
|
|
1207
|
-
# await s.curs.add(rub.cur)
|
|
1208
|
-
|
|
1209
|
-
# пока порешали рейс-кондишн, очищаем сиротские условия при каждом запуске
|
|
1210
|
-
# [await c.delete() for c in await Cond.filter(ads__isnull=True)]
|
|
1211
|
-
cl.all_conds = {
|
|
1212
|
-
c.id: (c.raw_txt, {a.maker.exid for a in c.ads}) for c in await Cond.all().prefetch_related("ads__maker")
|
|
1213
|
-
}
|
|
1214
|
-
for curr, old in await CondSim.filter().values_list("cond_id", "cond_rel_id"):
|
|
1215
|
-
cl.cond_sims[curr] = old
|
|
1216
|
-
cl.rcond_sims[old] |= {curr}
|
|
1217
|
-
|
|
1218
|
-
cl.build_tree()
|
|
1219
|
-
a = set()
|
|
1220
|
-
|
|
1221
|
-
def check_tree(tre):
|
|
1222
|
-
for p, c in tre.items():
|
|
1223
|
-
a.add(p)
|
|
1224
|
-
check_tree(c)
|
|
1225
|
-
|
|
1226
|
-
for pr, ch in cl.tree.items():
|
|
1227
|
-
check_tree(ch)
|
|
1228
|
-
if ct := set(cl.tree.keys()) & a:
|
|
1229
|
-
logging.exception(f"cycle cids: {ct}")
|
|
1230
1206
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
)
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
# cl.racing(usdt, rub, True, ["volet"], 81.51), # гонка в стакане продажи - мы покупаем
|
|
1244
|
-
# cl.racing(usdt, rub, False, ["payeer"], 81.49), # гонка в стакане покупки - мы продаем
|
|
1245
|
-
# cl.racing(usdt, rub, True, ["payeer"], 80.7), # гонка в стакане продажи - мы покупаем
|
|
1246
|
-
# cl.racing(eth, rub, False, ["volet"], 300_000),
|
|
1247
|
-
# cl.racing(eth, rub, True, ["volet"], 296_000),
|
|
1248
|
-
# cl.racing(eth, rub, False, ["payeer"], 300_000),
|
|
1249
|
-
# cl.racing(eth, rub, True, ["payeer"], 296_000),
|
|
1250
|
-
# cl.racing(btc, rub, False, ["volet"], 9_800_000),
|
|
1251
|
-
# cl.racing(btc, rub, True, ["volet"], 9_700_000),
|
|
1252
|
-
# cl.racing(btc, rub, False, ["payeer"], 9_800_000),
|
|
1253
|
-
# cl.racing(btc, rub, True, ["payeer"], 9_700_000),
|
|
1254
|
-
# cl.racing(usdc, rub, False, ["volet"], 80.98),
|
|
1255
|
-
# cl.racing(usdc, rub, True, ["volet"], 80.01),
|
|
1256
|
-
# cl.racing(usdc, rub, False, ["payeer"], 80.98),
|
|
1257
|
-
# cl.racing(usdc, rub, True, ["payeer"], 80.01),
|
|
1258
|
-
# cl.parse_ads(usdt, rub, False, ceil=81, volume=360),
|
|
1259
|
-
# cl.parse_ads(usdt, rub, True, ceil=80, volume=360),
|
|
1207
|
+
async def main():
|
|
1208
|
+
logging.basicConfig(level=logging.INFO)
|
|
1209
|
+
cn = await init_db(TORM)
|
|
1210
|
+
|
|
1211
|
+
agent = (
|
|
1212
|
+
await models.Agent.filter(actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, id=8)
|
|
1213
|
+
.prefetch_related(
|
|
1214
|
+
"actor__ex",
|
|
1215
|
+
"actor__person__user__gmail",
|
|
1216
|
+
"actor__my_ads__my_ad__race",
|
|
1217
|
+
"actor__my_ads__pair_side__pair__cur",
|
|
1218
|
+
"actor__my_ads__pms",
|
|
1260
1219
|
)
|
|
1220
|
+
.first()
|
|
1221
|
+
)
|
|
1222
|
+
filebot = FileClient(NET_TOKEN)
|
|
1223
|
+
# await filebot.start()
|
|
1224
|
+
# b.add_handler(MessageHandler(cond_start_handler, command("cond")))
|
|
1225
|
+
ex = await models.Ex.get(name="Bybit")
|
|
1226
|
+
ecl: ExClient = ex.client(filebot)
|
|
1227
|
+
abot = XyncBot(PAY_TOKEN, cn)
|
|
1228
|
+
cl: AgentClient = agent.client(ecl, filebot, abot)
|
|
1229
|
+
|
|
1230
|
+
# req = TakeAdReq(ad_id=1955696985964089344, amount=504, pm_id=128)
|
|
1231
|
+
# await cl.take_ad(req)
|
|
1232
|
+
|
|
1233
|
+
# await cl.actual_cond()
|
|
1234
|
+
# cl.get_api_orders(), # 10, 1738357200000, 1742504399999
|
|
1235
|
+
|
|
1236
|
+
# await cl.ex_client.set_pairs()
|
|
1237
|
+
# await cl.ex_client.set_pms()
|
|
1238
|
+
|
|
1239
|
+
# await cl.set_creds()
|
|
1240
|
+
# await cl.export_my_ads()
|
|
1241
|
+
|
|
1242
|
+
ms = await models.Agent.filter(
|
|
1243
|
+
actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, actor__person__user__id__in=[2]
|
|
1244
|
+
).prefetch_related(
|
|
1245
|
+
"actor__ex",
|
|
1246
|
+
"actor__person__user__gmail",
|
|
1247
|
+
"actor__my_ads__my_ad__race",
|
|
1248
|
+
"actor__my_ads__pair_side__pair__cur",
|
|
1249
|
+
"actor__my_ads__pms",
|
|
1250
|
+
)
|
|
1251
|
+
mcs = {m.actor.exid: m.client(ecl, filebot, abot) for m in ms}
|
|
1261
1252
|
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1253
|
+
await gather(
|
|
1254
|
+
create_task(cl.start(True)),
|
|
1255
|
+
create_task(cl.watch_payeer(mcs)),
|
|
1256
|
+
)
|
|
1257
|
+
# ensure_future(cl.start(True))
|
|
1258
|
+
# await cl.boost_acc()
|
|
1259
|
+
|
|
1260
|
+
# создание гонок по мои активным объявам:
|
|
1261
|
+
# for ma in cl.my_ads():
|
|
1262
|
+
# my_ad = await models.MyAd.get(ad__exid=ma.id).prefetch_related('ad__pms', 'ad__pair_side__pair')
|
|
1263
|
+
# race, _ = await models.Race.update_or_create(
|
|
1264
|
+
# {"started": True, "vm_filter": True, "target_place": 5},
|
|
1265
|
+
# road=my_ad
|
|
1266
|
+
# )
|
|
1267
|
+
|
|
1268
|
+
# for name in names:
|
|
1269
|
+
# s, _ = await models.Synonym.update_or_create(typ=SynonymType.name, txt=name)
|
|
1270
|
+
# await s.curs.add(rub.cur)
|
|
1271
|
+
|
|
1272
|
+
pauth = (await models.PmAgent[1]).auth
|
|
1273
|
+
papi = PayeerAPI(pauth["email"], pauth["api_id"], pauth["api_sec"])
|
|
1274
|
+
hist: dict = papi.history(count=1000)
|
|
1275
|
+
hist |= papi.history(count=1000, append=list(hist.keys())[-1])
|
|
1276
|
+
hist |= papi.history(count=1000, append=list(hist.keys())[-1])
|
|
1277
|
+
cl.hist = hist
|
|
1278
|
+
|
|
1279
|
+
# cl.completed_orders = await models.Order.filter(status=OrderStatus.completed, transfer__isnull=False).values_list(
|
|
1280
|
+
# "exid", flat=True
|
|
1281
|
+
# )
|
|
1282
|
+
# await cl.get_api_orders() # 43, 1741294800000, 1749157199999)
|
|
1283
|
+
|
|
1284
|
+
# await cl.cancel_order(res.orderId)
|
|
1285
|
+
await filebot.stop()
|
|
1286
|
+
await cl.close()
|
|
1275
1287
|
|
|
1276
1288
|
|
|
1277
1289
|
if __name__ == "__main__":
|