xync-client 0.0.155__py3-none-any.whl → 0.0.156.dev18__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 +0 -294
- xync_client/Abc/Agent.py +313 -51
- xync_client/Abc/Ex.py +414 -12
- xync_client/Abc/xtype.py +34 -2
- xync_client/Bybit/InAgent.py +225 -436
- xync_client/Bybit/agent.py +529 -397
- xync_client/Bybit/etype/__init__.py +0 -0
- xync_client/Bybit/etype/ad.py +47 -34
- xync_client/Bybit/etype/order.py +33 -48
- xync_client/Bybit/ex.py +20 -46
- xync_client/Htx/agent.py +82 -40
- xync_client/Htx/etype/ad.py +22 -5
- xync_client/Htx/etype/order.py +194 -0
- xync_client/Htx/ex.py +16 -16
- xync_client/Mexc/agent.py +196 -13
- xync_client/Mexc/api.py +955 -336
- xync_client/Mexc/etype/ad.py +52 -1
- xync_client/Mexc/etype/order.py +131 -416
- xync_client/Mexc/ex.py +29 -19
- xync_client/Okx/1.py +14 -0
- xync_client/Okx/agent.py +39 -0
- xync_client/Okx/ex.py +8 -8
- xync_client/Pms/Payeer/agent.py +396 -0
- xync_client/Pms/Payeer/login.py +1 -63
- xync_client/Pms/Payeer/trade.py +58 -0
- xync_client/loader.py +1 -0
- {xync_client-0.0.155.dist-info → xync_client-0.0.156.dev18.dist-info}/METADATA +2 -1
- {xync_client-0.0.155.dist-info → xync_client-0.0.156.dev18.dist-info}/RECORD +30 -26
- xync_client/Pms/Payeer/__init__.py +0 -262
- xync_client/Pms/Payeer/api.py +0 -25
- {xync_client-0.0.155.dist-info → xync_client-0.0.156.dev18.dist-info}/WHEEL +0 -0
- {xync_client-0.0.155.dist-info → xync_client-0.0.156.dev18.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, NonNegativeInt, Field, PositiveInt
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class C2COrder(BaseModel):
|
|
8
|
+
cancelCountDown: NonNegativeInt
|
|
9
|
+
consultCancelCountDown: NonNegativeInt
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OrderItem(BaseModel):
|
|
13
|
+
orderId: int
|
|
14
|
+
counterpartUid: PositiveInt
|
|
15
|
+
counterpartNickName: str
|
|
16
|
+
counterpartIsOnline: bool
|
|
17
|
+
counterpartOrderCount: NonNegativeInt
|
|
18
|
+
counterpartLastTradeTime: NonNegativeInt # timestamp in ms
|
|
19
|
+
counterpartMerchantLevel: NonNegativeInt
|
|
20
|
+
counterpartThumbUp: NonNegativeInt
|
|
21
|
+
counterpartRocketAmount: NonNegativeInt | None
|
|
22
|
+
counterpartPrimeLevel: str = Field(pattern=r"^Prime\d+$")
|
|
23
|
+
counterpartRecentWithdrawTime: PositiveInt | None # timestamp in ms
|
|
24
|
+
side: Literal[0, 1] # 0=buy, 1=sell
|
|
25
|
+
tradeMode: Literal[1, 2] # предполагаемые значения
|
|
26
|
+
runMode: Literal[1, 2] # предполагаемые значения
|
|
27
|
+
quoteAssetName: str = Field(min_length=1, max_length=10)
|
|
28
|
+
cryptoAssetName: str = Field(min_length=1, max_length=10)
|
|
29
|
+
amount: Decimal = Field(gt=0, decimal_places=2)
|
|
30
|
+
quantity: Decimal = Field(gt=0)
|
|
31
|
+
quote: Decimal = Field(gt=0, decimal_places=2)
|
|
32
|
+
orderStatus: NonNegativeInt
|
|
33
|
+
c2cOrder: C2COrder = None
|
|
34
|
+
inNegotiation: bool
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ModelField(BaseModel):
|
|
38
|
+
fieldId: str
|
|
39
|
+
name: str
|
|
40
|
+
fieldType: Literal["payee", "pay_account", "bank", "sub_bank", "qr_code"]
|
|
41
|
+
index: PositiveInt
|
|
42
|
+
maxLength: int | None = None
|
|
43
|
+
required: bool | None = None
|
|
44
|
+
copyable: bool
|
|
45
|
+
remindWord: str | None = None
|
|
46
|
+
valueType: str | None = None
|
|
47
|
+
value: str
|
|
48
|
+
nameList: list | None = None
|
|
49
|
+
remindWordList: list | None = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PaymentMethod(BaseModel):
|
|
53
|
+
id: PositiveInt
|
|
54
|
+
userName: str = Field(min_length=1)
|
|
55
|
+
bankType: PositiveInt
|
|
56
|
+
bankNumber: str
|
|
57
|
+
bankName: str | None = None
|
|
58
|
+
bankAddress: str | None = None
|
|
59
|
+
qrCode: str | None = None
|
|
60
|
+
color: str = Field(pattern=r"^#[0-9A-F]{6}$")
|
|
61
|
+
payMethodName: str = Field(min_length=1)
|
|
62
|
+
paymentStatus: Literal[1]
|
|
63
|
+
modelFieldsList: list[ModelField]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class OrderInfo(BaseModel):
|
|
67
|
+
orderId: PositiveInt
|
|
68
|
+
orderNo: PositiveInt
|
|
69
|
+
uid: PositiveInt
|
|
70
|
+
nickName: str = Field(min_length=1)
|
|
71
|
+
realName: str | None = None
|
|
72
|
+
roleName: Literal["maker", "taker"]
|
|
73
|
+
side: Literal[0, 1]
|
|
74
|
+
runMode: Literal[1]
|
|
75
|
+
tradeMode: Literal[1]
|
|
76
|
+
liquidDivision: Literal[3]
|
|
77
|
+
sideName: Literal["buy", "sell"]
|
|
78
|
+
quoteAssetId: PositiveInt
|
|
79
|
+
quoteAssetType: Literal[1]
|
|
80
|
+
quoteAssetName: str = Field(min_length=1, max_length=10)
|
|
81
|
+
quoteAssetSymbol: str
|
|
82
|
+
cryptoAssetId: PositiveInt
|
|
83
|
+
cryptoAssetType: Literal[2]
|
|
84
|
+
cryptoAssetName: str = Field(min_length=1, max_length=10)
|
|
85
|
+
cryptoAssetSymbol: str
|
|
86
|
+
amount: Decimal = Field(gt=0, decimal_places=2)
|
|
87
|
+
quantity: Decimal = Field(gt=0)
|
|
88
|
+
quote: Decimal = Field(gt=0, decimal_places=2)
|
|
89
|
+
orderStatus: NonNegativeInt
|
|
90
|
+
gmtCreate: PositiveInt
|
|
91
|
+
gmtModified: PositiveInt
|
|
92
|
+
areaType: Literal[1]
|
|
93
|
+
appealCountDown: NonNegativeInt
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class OtherInfo(BaseModel):
|
|
97
|
+
uid: PositiveInt
|
|
98
|
+
nickName: str = Field(min_length=1)
|
|
99
|
+
realName: str | None = None
|
|
100
|
+
gmtCreate: PositiveInt
|
|
101
|
+
merchantLevel: NonNegativeInt
|
|
102
|
+
realTradeCountBuy: NonNegativeInt
|
|
103
|
+
realTradeCountSell: NonNegativeInt
|
|
104
|
+
registerTime: PositiveInt
|
|
105
|
+
isPhoneBind: bool
|
|
106
|
+
marginAssetId: NonNegativeInt
|
|
107
|
+
marginAssetName: str | None = None
|
|
108
|
+
marginAmount: NonNegativeInt
|
|
109
|
+
appealMonthTimes: NonNegativeInt
|
|
110
|
+
appealMonthWinTimes: NonNegativeInt
|
|
111
|
+
isOnline: bool
|
|
112
|
+
isSeniorAuth: bool
|
|
113
|
+
orderCompleteRate: Decimal = Field(ge=0, le=100, decimal_places=2)
|
|
114
|
+
tradeMonthCount: NonNegativeInt
|
|
115
|
+
tradeCount: NonNegativeInt
|
|
116
|
+
releaseTime: NonNegativeInt
|
|
117
|
+
buyCompleteRate: Decimal = Field(ge=0, le=100, decimal_places=2)
|
|
118
|
+
buyCancelTimeAvg: Decimal = Field(ge=0, decimal_places=2)
|
|
119
|
+
thumbUp: NonNegativeInt
|
|
120
|
+
merchantTags: str | None = None
|
|
121
|
+
totalUserTradeCount: NonNegativeInt
|
|
122
|
+
totalTradeOrderCount: NonNegativeInt
|
|
123
|
+
totalTradeOrderCancelCount: NonNegativeInt
|
|
124
|
+
orderBuyCompleteRate: Decimal = Field(ge=0, le=100, decimal_places=2)
|
|
125
|
+
orderSellCompleteRate: Decimal = Field(ge=0, le=100, decimal_places=2)
|
|
126
|
+
totalOrderCompleteRate: Decimal = Field(ge=0, le=100, decimal_places=2)
|
|
127
|
+
counterpartRocketAmount: int | None = None
|
|
128
|
+
counterpartPrimeLevel: str = Field(pattern=r"^Prime\d+$")
|
|
129
|
+
counterpartRecentWithdrawTime: PositiveInt | None = None
|
|
130
|
+
counterpartOrderCount: NonNegativeInt
|
|
131
|
+
counterpartLastTradeTime: NonNegativeInt
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class Fee(BaseModel):
|
|
135
|
+
feeType: Literal[1]
|
|
136
|
+
feeStatus: Literal[1, 2]
|
|
137
|
+
fee: Decimal = Field(ge=0)
|
|
138
|
+
feeName: str = Field(min_length=1)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class FeeInfo(BaseModel):
|
|
142
|
+
totalFee: Decimal = Field(ge=0)
|
|
143
|
+
feeList: list[Fee]
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class OrderTag(BaseModel):
|
|
147
|
+
isSoonLock: Literal[1, 2]
|
|
148
|
+
isPremature: Literal[1, 2]
|
|
149
|
+
isAppeal: Literal[1, 2]
|
|
150
|
+
specialCancelFlag: Literal[1, 2]
|
|
151
|
+
isPhone: Literal[1, 2]
|
|
152
|
+
now: PositiveInt
|
|
153
|
+
isAppealPremature: Literal[1, 2]
|
|
154
|
+
isFollowed: bool
|
|
155
|
+
isShield: bool
|
|
156
|
+
negotiationStatus: int | None = None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class C2COrderDetail(BaseModel):
|
|
160
|
+
matchPayId: int | None = None
|
|
161
|
+
payTerm: PositiveInt
|
|
162
|
+
payCode: str | None = None
|
|
163
|
+
quote: Decimal = Field(gt=0, decimal_places=2)
|
|
164
|
+
amount: Decimal = Field(gt=0, decimal_places=2)
|
|
165
|
+
quantity: Decimal = Field(gt=0)
|
|
166
|
+
quoteAssetName: str = Field(min_length=1)
|
|
167
|
+
cryptoAssetName: str = Field(min_length=1)
|
|
168
|
+
buyPayAccount: PositiveInt | None
|
|
169
|
+
gmtPay: PositiveInt | None
|
|
170
|
+
gmtResetCancel: PositiveInt | None = None
|
|
171
|
+
orderStatus: NonNegativeInt
|
|
172
|
+
cancelCountDown: NonNegativeInt
|
|
173
|
+
consultCancelCountDown: NonNegativeInt
|
|
174
|
+
waitCompletedCountDown: NonNegativeInt
|
|
175
|
+
areaType: Literal[1]
|
|
176
|
+
acceptStatus: Literal[0, 1]
|
|
177
|
+
appCountDown: NonNegativeInt
|
|
178
|
+
appMaxCountDown: NonNegativeInt
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class OrderSnapshot(BaseModel):
|
|
182
|
+
tradeInstructionStatus: Literal["INIT", "COMPLETED"] # добавь другие статусы
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class OrderFull(BaseModel):
|
|
186
|
+
orderInfo: OrderInfo
|
|
187
|
+
otherInfo: OtherInfo
|
|
188
|
+
paymentMethod: list[PaymentMethod]
|
|
189
|
+
feeInfo: FeeInfo
|
|
190
|
+
orderTag: OrderTag
|
|
191
|
+
c2cOrder: C2COrderDetail
|
|
192
|
+
inNegotiation: bool
|
|
193
|
+
takerEvaluateStatus: Literal[0, 1]
|
|
194
|
+
orderSnapshot: OrderSnapshot
|
xync_client/Htx/ex.py
CHANGED
|
@@ -42,22 +42,22 @@ class ExClient(BaseExClient):
|
|
|
42
42
|
pair[rcurs[cur["name"]]] += [coen]
|
|
43
43
|
return tuple(pairs.values())
|
|
44
44
|
|
|
45
|
-
async def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
res = (await self._get("/-/x/otc/v1/data/trade-market",
|
|
45
|
+
async def x2e_req_ads(self, xreq: GetAds) -> ad.AdsReq:
|
|
46
|
+
coin_id, _ = await self.x2e_coin(xreq.coin_id)
|
|
47
|
+
cur_id, _, __ = await self.x2e_cur(xreq.cur_id)
|
|
48
|
+
ereq = ad.AdsReq(
|
|
49
|
+
coinId=int(coin_id),
|
|
50
|
+
currency=int(cur_id),
|
|
51
|
+
tradeType="sell" if xreq.is_sell else "buy",
|
|
52
|
+
payMethod=",".join([await self.x2e_pm(pm_id) for pm_id in xreq.pm_ids]),
|
|
53
|
+
)
|
|
54
|
+
if xreq.amount:
|
|
55
|
+
ereq.amount = str(xreq.amount)
|
|
56
|
+
# todo: all kwargs
|
|
57
|
+
return ereq
|
|
58
|
+
|
|
59
|
+
async def _ads(self, req: ad.AdsReq, lim: int = None, vm_filter: bool = False, **kwargs) -> list[ad.Resp]:
|
|
60
|
+
res = (await self._get("/-/x/otc/v1/data/trade-market", req.model_dump()))["data"]
|
|
61
61
|
ads = [ad.Resp(**a) for a in res]
|
|
62
62
|
return ads
|
|
63
63
|
|
xync_client/Mexc/agent.py
CHANGED
|
@@ -1,25 +1,86 @@
|
|
|
1
|
-
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from asyncio import run, sleep, create_task
|
|
2
4
|
from hashlib import md5
|
|
5
|
+
from urllib.parse import quote
|
|
3
6
|
from uuid import uuid4
|
|
4
7
|
|
|
8
|
+
import websockets
|
|
9
|
+
from blackboxprotobuf import protobuf_to_json
|
|
5
10
|
from pyro_client.client.file import FileClient
|
|
6
11
|
from xync_bot import XyncBot
|
|
12
|
+
|
|
13
|
+
from xync_client.Mexc.api import MEXCP2PApiClient
|
|
14
|
+
from xync_client.Mexc.etype import ad
|
|
15
|
+
|
|
16
|
+
from xync_client.Abc.xtype import GetAds, AdUpd
|
|
7
17
|
from xync_client.Bybit.etype.order import TakeAdReq
|
|
18
|
+
from xync_client.Mexc.etype.order import OrderDetail
|
|
8
19
|
|
|
9
20
|
from xync_client.loader import PAY_TOKEN, NET_TOKEN
|
|
10
21
|
from xync_schema import models
|
|
11
|
-
from xync_schema.enums import UserStatus
|
|
22
|
+
from xync_schema.enums import UserStatus, AgentStatus
|
|
12
23
|
|
|
13
24
|
from xync_client.Abc.Agent import BaseAgentClient
|
|
14
25
|
|
|
15
26
|
|
|
16
27
|
class AgentClient(BaseAgentClient):
|
|
17
|
-
i: int =
|
|
28
|
+
i: int = 5
|
|
18
29
|
headers = {
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
30
|
+
# "Accept-Encoding": "gzip, deflate, br, zstd",
|
|
31
|
+
"Accept-Language": "ru,en;q=0.9",
|
|
32
|
+
"Language:": "ru-RU",
|
|
33
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
|
|
22
34
|
}
|
|
35
|
+
api: MEXCP2PApiClient
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
async def _heartbeat(ws):
|
|
39
|
+
"""Фоновая задача для PING/PONG"""
|
|
40
|
+
while True:
|
|
41
|
+
await sleep(25)
|
|
42
|
+
await ws.send('{"method":"PING"}')
|
|
43
|
+
|
|
44
|
+
async def _ws_key(self):
|
|
45
|
+
self.i = 13 if self.i > 9999 else self.i + 1
|
|
46
|
+
hdrs = self.agent.auth["headers"] | {
|
|
47
|
+
"trochilus-trace-id": "c7831459-3bb2-4aa7-bf5d-9ff2adef0c08-0062",
|
|
48
|
+
"ucenter-token": self.agent.auth["cookies"]["u_id"],
|
|
49
|
+
}
|
|
50
|
+
# resp = get("https://www.mexc.com/ucenter/api/ws_token", headers=hdrs, cookies=self.agent.auth['cookies'])
|
|
51
|
+
resp = await self._get("/ucenter/api/ws_token", hdrs=hdrs)
|
|
52
|
+
self.wkk = resp["data"]["wsToken"]
|
|
53
|
+
|
|
54
|
+
async def ws_prv(self):
|
|
55
|
+
await self._ws_key()
|
|
56
|
+
url = f"wss://wbs.mexc.com/ws?wsToken={self.wkk}"
|
|
57
|
+
async with websockets.connect(url) as ws:
|
|
58
|
+
create_task(self._heartbeat(ws))
|
|
59
|
+
await ws.send('{"method":"SUBSCRIPTION","params":["otc@private.p2p.orders.pb"],"id":12}')
|
|
60
|
+
await ws.send('{"method":"SUBSCRIPTION","params":["common@private.risk.result.pb"],"id":11}')
|
|
61
|
+
while resp := await ws.recv():
|
|
62
|
+
try:
|
|
63
|
+
data: dict = json.loads(resp)
|
|
64
|
+
except UnicodeDecodeError:
|
|
65
|
+
msg, typedef = protobuf_to_json(resp)
|
|
66
|
+
data = json.loads(msg)
|
|
67
|
+
await self.recv(data)
|
|
68
|
+
if data.get("msg") == "PONG":
|
|
69
|
+
print(end="p")
|
|
70
|
+
else:
|
|
71
|
+
logging.warning(data)
|
|
72
|
+
|
|
73
|
+
async def recv(self, data: dict):
|
|
74
|
+
if data["1"] == "otc@private.p2p.orders.pb":
|
|
75
|
+
o = data["218"]["1"]
|
|
76
|
+
order: OrderDetail = (await self.api.get_order_detail(o["1"])).data
|
|
77
|
+
if order.side == "SELL":
|
|
78
|
+
if order.state == "NOT_PAID":
|
|
79
|
+
...
|
|
80
|
+
elif order.side == "BUY":
|
|
81
|
+
if order.state == "PAID":
|
|
82
|
+
...
|
|
83
|
+
...
|
|
23
84
|
|
|
24
85
|
async def _take_ad(self, req: TakeAdReq):
|
|
25
86
|
self.i = 33 if self.i > 9998 else self.i + 2
|
|
@@ -39,7 +100,7 @@ class AgentClient(BaseAgentClient):
|
|
|
39
100
|
"authVersion": "v2",
|
|
40
101
|
"deviceId": auth["mtoken"],
|
|
41
102
|
}
|
|
42
|
-
res = await self._post("/api/verify/second_auth/risk/scene", json=data, hdrs=hdrs)
|
|
103
|
+
res = await self._post("/api/platform/p2p/api/verify/second_auth/risk/scene", json=data, hdrs=hdrs)
|
|
43
104
|
data = {
|
|
44
105
|
"amount": req.amount,
|
|
45
106
|
"authVersion": "v2",
|
|
@@ -50,9 +111,36 @@ class AgentClient(BaseAgentClient):
|
|
|
50
111
|
}
|
|
51
112
|
self.i = 33 if self.i > 9999 else self.i + 1
|
|
52
113
|
hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
|
|
53
|
-
res = await self._post("/api/order/deal?mhash=" + auth["mhash"], data=auth | data, hdrs=hdrs)
|
|
114
|
+
res = await self._post("/api/platform/p2p/api/order/deal?mhash=" + auth["mhash"], data=auth | data, hdrs=hdrs)
|
|
54
115
|
return res["data"]
|
|
55
116
|
|
|
117
|
+
async def x2e_req_ad_upd(self, xreq: AdUpd) -> ad.AdUpd:
|
|
118
|
+
coin_id, coin_scale = await self.ex_client.x2e_coin(xreq.coin_id)
|
|
119
|
+
cur_id, cur_scale, minimum = await self.ex_client.x2e_cur(xreq.cur_id)
|
|
120
|
+
ereq = ad.AdUpd(
|
|
121
|
+
id=xreq.id,
|
|
122
|
+
price=round(xreq.price, cur_scale),
|
|
123
|
+
coinId=coin_id,
|
|
124
|
+
currency=cur_id,
|
|
125
|
+
tradeType="SELL" if xreq.is_sell else "BUY",
|
|
126
|
+
deviceId=self.agent.auth["deviceId"],
|
|
127
|
+
payment=",".join([str(cdx.exid) for cdx in xreq.credexs]),
|
|
128
|
+
priceType=0,
|
|
129
|
+
minTradeLimit=minimum,
|
|
130
|
+
maxTradeLimit=round(xreq.max_amount or xreq.amount - 10**-cur_scale, cur_scale),
|
|
131
|
+
quantity=round(xreq.quantity or xreq.amount / xreq.price, coin_scale),
|
|
132
|
+
)
|
|
133
|
+
if xreq.cond:
|
|
134
|
+
ereq.autoResponse = quote(xreq.cond)
|
|
135
|
+
# todo: all kwargs
|
|
136
|
+
return ereq
|
|
137
|
+
|
|
138
|
+
async def _ad_upd(self, req: ad.AdUpd):
|
|
139
|
+
self.i = 33 if self.i > 9999 else self.i + 1
|
|
140
|
+
hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
|
|
141
|
+
res = await self._put("/api/platform/p2p/api/merchant/order", form_data=req.model_dump(), hdrs=hdrs)
|
|
142
|
+
return res["code"]
|
|
143
|
+
|
|
56
144
|
|
|
57
145
|
async def main():
|
|
58
146
|
from x_model import init_db
|
|
@@ -60,10 +148,11 @@ async def main():
|
|
|
60
148
|
|
|
61
149
|
cn = await init_db(TORM, True)
|
|
62
150
|
|
|
151
|
+
ex = await models.Ex[12]
|
|
63
152
|
agent = (
|
|
64
153
|
await models.Agent.filter(
|
|
65
|
-
|
|
66
|
-
|
|
154
|
+
actor__ex=ex,
|
|
155
|
+
status__gte=AgentStatus.race,
|
|
67
156
|
auth__isnull=False,
|
|
68
157
|
actor__person__user__status=UserStatus.ACTIVE,
|
|
69
158
|
actor__person__user__pm_agents__isnull=False,
|
|
@@ -71,12 +160,106 @@ async def main():
|
|
|
71
160
|
.prefetch_related("actor__ex", "actor__person__user__gmail")
|
|
72
161
|
.first()
|
|
73
162
|
)
|
|
74
|
-
|
|
75
163
|
bbot = XyncBot(PAY_TOKEN, cn)
|
|
76
164
|
fbot = FileClient(NET_TOKEN)
|
|
165
|
+
ecl = ex.client(fbot)
|
|
166
|
+
cl: AgentClient = agent.client(ecl, fbot, bbot)
|
|
167
|
+
cl.api = MEXCP2PApiClient(agent.auth["key"], agent.auth["sec"])
|
|
168
|
+
create_task(cl.ws_prv())
|
|
169
|
+
|
|
170
|
+
while True:
|
|
171
|
+
bceil = 106
|
|
172
|
+
sceil = 124.98
|
|
173
|
+
breq = GetAds(coin_id=1, cur_id=1, is_sell=False, pm_ids=[366])
|
|
174
|
+
sreq = GetAds(coin_id=1, cur_id=1, is_sell=True, pm_ids=[366])
|
|
175
|
+
breq_upd = AdUpd(
|
|
176
|
+
id="a1574183931501582340", price=87, **{**breq.model_dump(), "amount": 11000.01}, max_amount=4370
|
|
177
|
+
) # + 1 cent
|
|
178
|
+
sreq_upd = AdUpd(id="a1594624084590445568", price=150, **{**sreq.model_dump(), "amount": 30000.01})
|
|
179
|
+
|
|
180
|
+
await sleep(5)
|
|
181
|
+
bads: list[ad.Ad] = await cl.ex_client.ads(breq)
|
|
182
|
+
if bads[0].price >= sceil:
|
|
183
|
+
bad: ad.Ad = bads.pop(0)
|
|
184
|
+
await cl.bbot.send(
|
|
185
|
+
193017646,
|
|
186
|
+
f"price: {bad.price}\nnick: {bad.merchant.nickName}\nmax:{bad.maxPayLimit}"
|
|
187
|
+
f"\nqty: {bad.availableQuantity} [{bad.minTradeLimit}-{bad.maxTradeLimit}]",
|
|
188
|
+
)
|
|
189
|
+
# am = min(bad.maxTradeLimit, max(10000.0, bad.minTradeLimit))
|
|
190
|
+
# req = TakeAdReq(
|
|
191
|
+
# ad_id=bad.exid,
|
|
192
|
+
# amount=am,
|
|
193
|
+
# pm_id=366,
|
|
194
|
+
# is_sell=False,
|
|
195
|
+
# coin_id=1,
|
|
196
|
+
# cur_id=1,
|
|
197
|
+
# )
|
|
198
|
+
# ord_resp: OrderResp = await cl.take_ad(req)
|
|
199
|
+
|
|
200
|
+
bads = [
|
|
201
|
+
a
|
|
202
|
+
for a in bads
|
|
203
|
+
if a.price <= bceil and a.availableQuantity > 20 and (a.maxTradeLimit - a.minTradeLimit > 1000)
|
|
204
|
+
]
|
|
205
|
+
if len(bads) > 1:
|
|
206
|
+
if bads[0].merchant.nickName == cl.actor.name:
|
|
207
|
+
if round(bads[0].price - bads[1].price, 2) > 0.01:
|
|
208
|
+
breq_upd.price = bads[1].price + 0.01
|
|
209
|
+
if _ := await cl.ad_upd(breq_upd):
|
|
210
|
+
await sleep(5, print(_, flush=True))
|
|
211
|
+
print(end="!", flush=True)
|
|
212
|
+
elif bads[0].price != (trgt_price := bads[0].price + 0.01):
|
|
213
|
+
breq_upd.price = trgt_price
|
|
214
|
+
if _ := await cl.ad_upd(breq_upd):
|
|
215
|
+
await sleep(5, print(_, flush=True))
|
|
216
|
+
print(end="!", flush=True)
|
|
217
|
+
|
|
218
|
+
await sleep(5)
|
|
219
|
+
sads: list[ad.Ad] = await cl.ex_client.ads(sreq)
|
|
220
|
+
if sads[0].price <= bceil:
|
|
221
|
+
sad: ad.Ad = sads.pop(0)
|
|
222
|
+
await cl.bbot.send(
|
|
223
|
+
193017646,
|
|
224
|
+
f"price: {sad.price}\nnick: {sad.merchant.nickName}\nmax:{sad.maxPayLimit}"
|
|
225
|
+
f"\nqty: {sad.availableQuantity} [{sad.minTradeLimit}-{sad.maxTradeLimit}]",
|
|
226
|
+
)
|
|
227
|
+
# am = min(sad.maxTradeLimit, max(10000.0, sad.minTradeLimit))
|
|
228
|
+
# req = TakeAdReq(
|
|
229
|
+
# ad_id=sad.exid,
|
|
230
|
+
# amount=am,
|
|
231
|
+
# pm_id=366,
|
|
232
|
+
# is_sell=False,
|
|
233
|
+
# coin_id=1,
|
|
234
|
+
# cur_id=1,
|
|
235
|
+
# )
|
|
236
|
+
# ord_resp: OrderResp = await cl.take_ad(req)
|
|
237
|
+
|
|
238
|
+
sads = [
|
|
239
|
+
a
|
|
240
|
+
for a in sads
|
|
241
|
+
if a.price >= sceil and a.availableQuantity > 20 and (a.maxTradeLimit - a.minTradeLimit > 1000)
|
|
242
|
+
]
|
|
243
|
+
if len(sads) > 1:
|
|
244
|
+
if sads[0].merchant.nickName == cl.actor.name:
|
|
245
|
+
if round(sads[1].price - sads[0].price, 2) > 0.01:
|
|
246
|
+
sreq_upd.price = sads[1].price - 0.01
|
|
247
|
+
if _ := await cl.ad_upd(sreq_upd):
|
|
248
|
+
await sleep(15, print(_, flush=True))
|
|
249
|
+
continue
|
|
250
|
+
print(end="!", flush=True)
|
|
251
|
+
continue
|
|
252
|
+
elif sads[0].price > sceil:
|
|
253
|
+
sreq_upd.price = sads[0].price - 0.01
|
|
254
|
+
if _ := await cl.ad_upd(sreq_upd):
|
|
255
|
+
await sleep(15, print(_, flush=True))
|
|
256
|
+
continue
|
|
257
|
+
print(end="!", flush=True)
|
|
258
|
+
continue
|
|
259
|
+
|
|
260
|
+
print(end=".", flush=True)
|
|
77
261
|
|
|
78
|
-
|
|
79
|
-
req = TakeAdReq(ad_id="a1574088909645125632", amount=500, pm_id=366, cur_="RUB", price=85.8, is_sell=True)
|
|
262
|
+
req = TakeAdReq(ad_id="a1574088909645125632", amount=500, pm_id=366, cur_id=1, price=85.8, is_sell=True)
|
|
80
263
|
res = await cl.take_ad(req)
|
|
81
264
|
print(res)
|
|
82
265
|
|