This commit is contained in:
Administrator
2025-12-11 15:10:27 +08:00
parent 74161f8603
commit 7d9eb0ebca
4 changed files with 592 additions and 72 deletions

View File

@@ -1,3 +1,72 @@
import time
import requests
print(time.time())
cookies = {
'AF_SYNC': '1765258261595',
'_ym_d': '1765261165',
'_ym_uid': '1765261165802134230',
'tradeType': 'pro',
'__adroll_fpc': '23875168b001e1ea5b3c338cadd7fe49-1762510277666',
'afUserId': '1ac8dae1-3f99-4800-b10c-6a2f5b9128a2-p',
'golang': 'cn',
'accessKey': 'eyJoZWFkZXIiOnsidHlwIjoiQml0TWFydCIsImFsZyI6IkJNQVBJU0lYIn0sInBheWxvYWQiOnsiamlkIjoiMjU4MDk0NmY0MzE1NDk2NWJjNmUxMmEyMjdmMGQ3ZjciLCJ2ZXJzaW9uIjoiMjAyNTEyMTEiLCJleHBpcmVzQXQiOjE3NjU1MTUxMzE2MjUsImJtIjoia1NkYzJOY0JuQnVTdEsvTk1OamFlQ0R6NVRIeS9wZXIxNmdYeDZPRFBWLytxaVh0UW5WcWoyNjNobHQwSWNaQk4vOWJkOXN1VlZpV2kxQm1Mc2JnTUNsTU1ZTE4wTExCTnN6WUJYSFZURWp4NXV4WmZvbnhoeDMwU1hkN3VPbHpDcFlKSVE2ZVE1YlM2ak5RemJMbU1jb1hxeERMYS9pTWJ2S2JRVCtSKzJFalhwdEZ3WDIxaEZCNDl3OUNPTnVQTG01T0ZibTEyKzZrMVFIeklxN1d3cTV4MUlzdW9Yam5kYWZXOVkzbVYxQ1B0U3dDNmxYcFFCRHBpUTVweGlYNGdybkx4MzBYUXZOMWRsQWVxR1NaeGJEN3ZodzNMRk9RTThFZU5aK3BpcFlTd3JCK08xOFh6Y0FzZE14U0h2RzRxbVp4MGxZN1pqUjlyaVhvVXRqYy9penZGTFROR0FhZ3NWRzRwOEp4TlhMakROcE0yMnM0dWxxQ0FjYUlET2tvIn0sInNpZ25hdHVyZSI6InhZK1lLTUJ1Q2ZROExDc3NlY21NcDdtZGVUL1YycGloL0I5MFdRU1B3MkQyMUVlbEJtRlZWeWhBYWhXUXFOOGpsek0wdEExeDJ4ZzdaUzZDZk1YUE1RPT0ifQ==',
'accessSalt': 'ybBIkojJPAgx3B57DxWp9tDqZBQGF14g92U',
'tokenAt': '1765515131625',
'tokenSt': '1765428734351',
'_gcl_au': '1.1.1161787028.1762510265',
'_gid': 'GA1.2.727267646.1765355541',
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2214768493%22%2C%22first_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTlhNWRjYzQ3MWQxMzRiLTA1MmRjYWMzNjM4NTNiOC0yNjAxMTA1MS0xNDU0MDgwMC0xOWE1ZGNjNDcxZWYzMyIsIiRpZGVudGl0eV9sb2dpbl9pZCI6IjE0NzY4NDkzIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2214768493%22%7D%2C%22%24device_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%7D',
'currentCurrency': 'USD',
'__cf_bm': 'd5utJxL3iD_YzZrYsaVGToGq1ho5vNoUBQxBcj84wAE-1765429537-1.0.1.1-ohkjT5elYCmZy_AhBKOEnWhpNuX1KtA9IGDTR9klXqLjlX75vLD.8NaSNgDPXHls422F6I7DDhP9TiLBeAGzmdeNLxlqCtkSfbEZW6cf.T4',
'_cfuvid': 'oINzbJqq18DXD3nYfw8WDzYlLQW_Emc2JoTaA9G_T3A-1765429537429-0.0.1.1-604800000',
'_ga_R8QWWJS24Y': 'GS2.1.s1765428734$o6$g1$t1765429603$j59$l0$h0',
'hasDelegation': 'false',
'delegationType': '0',
'delegationTypeList': '[]',
'_ga_7BWH3BJ925': 'GS2.1.s1765428735$o7$g1$t1765429604$j58$l0$h0',
'_ga_PJBF32MZ6E': 'GS2.1.s1765428735$o7$g1$t1765429604$j58$l0$h0',
'_gat_gtag_UA_116271308_6': '1',
'_ga_0V649X1YZB': 'GS2.1.s1765428735$o6$g1$t1765429604$j58$l0$h0',
'_ga': 'GA1.2.1461651029.1762510272',
'_gat': '1',
}
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-TW,zh;q=0.9',
'baggage': 'sentry-environment=production,sentry-release=e9b215a,sentry-public_key=42eada5febd1737fdcb9413516bdb44f,sentry-trace_id=ffb2aa1c055c49aabc90f69344e7c98f,sentry-sampled=false,sentry-sample_rand=0.8176968250645713,sentry-sample_rate=0.2',
'cache-control': 'no-cache',
'content-type': 'application/json;charset=UTF-8',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT?theme=dark',
'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'sentry-trace': 'ffb2aa1c055c49aabc90f69344e7c98f-a1ba2fca190697ae-0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
'x-bm-client': 'WEB',
'x-bm-contract': '2',
'x-bm-device': '790af181784031fde5b40950055c7a72',
'x-bm-tag': '',
'x-bm-timezone': 'Asia/Taipei',
'x-bm-timezone-offset': '-480',
'x-bm-ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
'x-bm-version': 'e9b215a',
# 'cookie': 'AF_SYNC=1765258261595; _ym_d=1765261165; _ym_uid=1765261165802134230; tradeType=pro; __adroll_fpc=23875168b001e1ea5b3c338cadd7fe49-1762510277666; afUserId=1ac8dae1-3f99-4800-b10c-6a2f5b9128a2-p; golang=cn; accessKey=eyJoZWFkZXIiOnsidHlwIjoiQml0TWFydCIsImFsZyI6IkJNQVBJU0lYIn0sInBheWxvYWQiOnsiamlkIjoiMjU4MDk0NmY0MzE1NDk2NWJjNmUxMmEyMjdmMGQ3ZjciLCJ2ZXJzaW9uIjoiMjAyNTEyMTEiLCJleHBpcmVzQXQiOjE3NjU1MTUxMzE2MjUsImJtIjoia1NkYzJOY0JuQnVTdEsvTk1OamFlQ0R6NVRIeS9wZXIxNmdYeDZPRFBWLytxaVh0UW5WcWoyNjNobHQwSWNaQk4vOWJkOXN1VlZpV2kxQm1Mc2JnTUNsTU1ZTE4wTExCTnN6WUJYSFZURWp4NXV4WmZvbnhoeDMwU1hkN3VPbHpDcFlKSVE2ZVE1YlM2ak5RemJMbU1jb1hxeERMYS9pTWJ2S2JRVCtSKzJFalhwdEZ3WDIxaEZCNDl3OUNPTnVQTG01T0ZibTEyKzZrMVFIeklxN1d3cTV4MUlzdW9Yam5kYWZXOVkzbVYxQ1B0U3dDNmxYcFFCRHBpUTVweGlYNGdybkx4MzBYUXZOMWRsQWVxR1NaeGJEN3ZodzNMRk9RTThFZU5aK3BpcFlTd3JCK08xOFh6Y0FzZE14U0h2RzRxbVp4MGxZN1pqUjlyaVhvVXRqYy9penZGTFROR0FhZ3NWRzRwOEp4TlhMakROcE0yMnM0dWxxQ0FjYUlET2tvIn0sInNpZ25hdHVyZSI6InhZK1lLTUJ1Q2ZROExDc3NlY21NcDdtZGVUL1YycGloL0I5MFdRU1B3MkQyMUVlbEJtRlZWeWhBYWhXUXFOOGpsek0wdEExeDJ4ZzdaUzZDZk1YUE1RPT0ifQ==; accessSalt=ybBIkojJPAgx3B57DxWp9tDqZBQGF14g92U; tokenAt=1765515131625; tokenSt=1765428734351; _gcl_au=1.1.1161787028.1762510265; _gid=GA1.2.727267646.1765355541; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2214768493%22%2C%22first_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTlhNWRjYzQ3MWQxMzRiLTA1MmRjYWMzNjM4NTNiOC0yNjAxMTA1MS0xNDU0MDgwMC0xOWE1ZGNjNDcxZWYzMyIsIiRpZGVudGl0eV9sb2dpbl9pZCI6IjE0NzY4NDkzIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2214768493%22%7D%2C%22%24device_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%7D; currentCurrency=USD; __cf_bm=d5utJxL3iD_YzZrYsaVGToGq1ho5vNoUBQxBcj84wAE-1765429537-1.0.1.1-ohkjT5elYCmZy_AhBKOEnWhpNuX1KtA9IGDTR9klXqLjlX75vLD.8NaSNgDPXHls422F6I7DDhP9TiLBeAGzmdeNLxlqCtkSfbEZW6cf.T4; _cfuvid=oINzbJqq18DXD3nYfw8WDzYlLQW_Emc2JoTaA9G_T3A-1765429537429-0.0.1.1-604800000; _ga_R8QWWJS24Y=GS2.1.s1765428734$o6$g1$t1765429603$j59$l0$h0; hasDelegation=false; delegationType=0; delegationTypeList=[]; _ga_7BWH3BJ925=GS2.1.s1765428735$o7$g1$t1765429604$j58$l0$h0; _ga_PJBF32MZ6E=GS2.1.s1765428735$o7$g1$t1765429604$j58$l0$h0; _gat_gtag_UA_116271308_6=1; _ga_0V649X1YZB=GS2.1.s1765428735$o6$g1$t1765429604$j58$l0$h0; _ga=GA1.2.1461651029.1762510272; _gat=1',
}
params = {
'status': '1',
}
response = requests.get(
'https://derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/userPositions',
params=params,
cookies=cookies,
headers=headers,
)
print(response.json())

View File

@@ -150,11 +150,10 @@ class WeexTransaction:
for i in range(3):
logger.info(f"获取最新数据:{i + 1}次。。。")
try:
response = requests.get('https://contract-v2.bitmart.com/v1/ifcontract/quote/kline', params=params, headers=headers)
response = self.session.get('https://contract-v2.bitmart.com/v1/ifcontract/quote/kline', params=params,
headers=headers, timeout=5)
for i in response.json()["data"]:
print(i)
insert_data = {
'id': int(i["timestamp"]) - 1,
'open': float(i["open"]),
@@ -164,8 +163,7 @@ class WeexTransaction:
}
datas.append(insert_data)
break
return datas
except:
time.sleep(1)
@@ -301,13 +299,21 @@ class WeexTransaction:
tab.listen.start("derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/userPositions")
tab.get(url="https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
tab.listen.listen.wait(timeout=15)
self.headers = tab.response.headers
res = tab.listen.wait()
self.headers = res.request.headers
self.cookies = {}
for i in res.request.cookies:
self.cookies[i["name"]] = i["value"]
self.cookies = tab.cookies()
if self.cookies.get('accessKey'):
self.session.cookies.update(self.cookies)
self.session.headers.update(self.headers)
self.session.cookies.update(self.cookies)
self.session.headers.update(self.headers)
tab.close()
return True
else:
tab.close()
return False
def get_position_status(self):
params = {
@@ -319,13 +325,31 @@ class WeexTransaction:
response = self.session.get(
'https://derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/userPositions',
params=params,
impersonate="chrome120"
)
if response.json()["data"]["positions"][0]["position_type"] == 1:
self.start = 1
elif response.json()["data"]["positions"][0]["position_type"] == 2:
self.start = -1
else:
try:
resp_data = response.json()
if not resp_data.get("success", False):
self.start = 0
return
positions = resp_data.get("data", {}).get("positions", [])
if not positions:
self.start = 0
else:
pos_type = positions[0].get("position_type")
if pos_type == 1:
self.start = 1
elif pos_type == 2:
self.start = -1
else:
self.start = 0 # 或 raise/log 异常情况
except (KeyError, IndexError, AttributeError, TypeError, ValueError) as e:
# JSON 解析失败或结构异常
print(f"持仓数据解析错误: {e}")
self.start = 0
return True
@@ -354,8 +378,6 @@ class WeexTransaction:
else:
logger.info('关闭多余标签页失败!!!')
self.mn_tab = self.page.new_tab()
self.mn_tab = self.page.new_tab(url="https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT") # 打开网页
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
@@ -373,7 +395,7 @@ class WeexTransaction:
self.pbar.refresh()
if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, ]: # 判断是否是 新的30分钟了
# if current_minute not in range(60): # 判断是否是 新的30分钟了
# if current_minute not in range(60): # 判断是否是 新的30分钟了
time.sleep(10)
continue
@@ -391,6 +413,7 @@ class WeexTransaction:
if self.get_now_time() != self.kline_3["id"]:
continue
self.get_token()
if self.get_position_status():
logger.info("获取仓位信息成功!!!")
else:

View File

@@ -1,72 +1,59 @@
import requests
cookies = {
'AF_SYNC': '1765258261595',
'tradeType': 'pro',
'_ym_d': '1765261165',
'_ym_uid': '1765261165802134230',
'__adroll_fpc': '23875168b001e1ea5b3c338cadd7fe49-1762510277666',
'_gcl_au': '1.1.1161787028.1762510265',
'afUserId': '1ac8dae1-3f99-4800-b10c-6a2f5b9128a2-p',
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2214768493%22%2C%22first_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTlhNWRjYzQ3MWQxMzRiLTA1MmRjYWMzNjM4NTNiOC0yNjAxMTA1MS0xNDU0MDgwMC0xOWE1ZGNjNDcxZWYzMyIsIiRpZGVudGl0eV9sb2dpbl9pZCI6IjE0NzY4NDkzIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2214768493%22%7D%2C%22%24device_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%7D',
'currentCurrency': 'USD',
'_gid': 'GA1.2.727267646.1765355541',
'_cfuvid': 'LqxpAwUIaf4fiq72Py_dM.deEKsZlGr2mGFEQZMcGiA-1765397364323-0.0.1.1-604800000',
'golang': 'cn',
'accessKey': 'eyJoZWFkZXIiOnsidHlwIjoiQml0TWFydCIsImFsZyI6IkJNQVBJU0lYIn0sInBheWxvYWQiOnsiamlkIjoiYzQxYWUzOGFjMjY1NDY1YjgyNDJiMGFlNGMzYmZlOWUiLCJ2ZXJzaW9uIjoiMjAyNTEyMTEiLCJleHBpcmVzQXQiOjE3NjU1MTAzMDkyMjMsImJtIjoia1NkYzJOY0JuQnVTdEsvTk1OamFlQ0R6NVRIeS9wZXIxNmdYeDZPRFBWLytxaVh0UW5WcWoyNjNobHQwSWNaQmZDVWh0N0xDUGRDZlpYYVg4aFJJekN6aGpubWxSNC9Sa2prQWNPR3NKUFo5SUp5N0MrSjhCa3pPTHJObE5mVFk0K0JjQkVCeEZuNVkvNXJEN2dYUWRVRm5MWkZpZXJ2V0doaW95ZzY5dHFFQ2JlK0FRMmJKU25qNmxRMWtNM3dCaHM2dzBvNVVhSFB4RXdmY3V5MFlObXVEZkllc1V1MFRERFRZZXFJOHltT2RqNmNUd2RuKzZlMnpJampZM3ZuVkhYOG9sblBkNTFVQ0RQM1YzUUY1QVFTRGVGd1ptYkUyTXNFR0R3QTRRTzBvZTlhMWozZWhneDlDY0IxTW1UMy96b3VrRFpESk80Tm9XVmNPU01YZzVEbDNpaU1Zeml6UWlxL1MvS1IxZUh4a0Vsa3Z6dEo1UzZGU2FYaWY3Yms2In0sInNpZ25hdHVyZSI6ImpsYTF3SUFySGtSdml2Z29QY1JKdEJMd1Vxb2RRb2VjUWFNY2NqK05XNFNXUzFjOFV1UGIvUnREd3V0Q3lGMStVVnBUbTFVQkZCQm1HekFEdjZBQnRnPT0ifQ==',
'accessSalt': 'wxtMqnh06IDcwNWA2CJXVcWJgQEhONNngZu',
'tokenAt': '1765510309223',
'tokenSt': '1765423911627',
'__cf_bm': '0C1pnUOIxv6UEs41adhYfAK6xRZl4W8j5Vz1QJgiNJQ-1765424190-1.0.1.1-5hfWqfjxsvm3ebMH8k5InFTDa9.ASF9nnizvLopXaacWUKoOTCPj0AC42fjXnve7Q.oVOJHIz3x9Gn80uQOYUWBa8gMPMhZFqYk6OLlAIds',
'hasDelegation': 'false',
'delegationType': '0',
'delegationTypeList': '[]',
'_ga_R8QWWJS24Y': 'GS2.1.s1765422430$o5$g1$t1765424194$j58$l0$h0',
'_ga_7BWH3BJ925': 'GS2.1.s1765422430$o6$g1$t1765424194$j58$l0$h0',
'_ga_PJBF32MZ6E': 'GS2.1.s1765422430$o6$g1$t1765424194$j58$l0$h0',
'_ga_0V649X1YZB': 'GS2.1.s1765422430$o5$g1$t1765424194$j58$l0$h0',
'_ga': 'GA1.2.1461651029.1762510272',
}
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'baggage': 'sentry-environment=production,sentry-release=e9b215a,sentry-public_key=42eada5febd1737fdcb9413516bdb44f,sentry-trace_id=dcfafebe185040448b9fa1864b4d65f0,sentry-sampled=false,sentry-sample_rand=0.7037873385703364,sentry-sample_rate=0.2',
'accept-language': 'fi',
'appversion': '2.0.1',
'bundleid': '',
'cache-control': 'no-cache',
'content-type': 'application/json;charset=UTF-8',
'expires': '0',
'content-type': 'application/json',
'language': 'en_US',
'locale': 'en_US',
'origin': 'https://www.weeaxs.site',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT?theme=dark',
'referer': 'https://www.weeaxs.site/',
'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'sentry-trace': 'dcfafebe185040448b9fa1864b4d65f0-8663a32b9bdfc923-0',
'sec-fetch-site': 'cross-site',
'sidecar': '011a2e3a777b5c1f6f6d426a6c28f1872b3d1836fb25135a0ca940511c4e5d4806',
'terminalcode': 'ea778f2af8f3a418595f4993fe0ed949',
'terminaltype': '1',
'traceid': '437bc1e7-15f3-47f5-8de6-25c3c89e16aa',
'u-token': 'eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJhM2FkNWY2MC0xNzEwLTQ3ZjgtYjZlNS0yNTBiMjZmYjBhNzIxNTU1MTk2Mjg4IiwidWlkIjoidEQzQ1FIaFJUblVYcm5MNFNwckw3UT09Iiwic3ViIjoieXgyMDI1KioqKkBnbWFpbC5jb20iLCJpcCI6IllXb3dNNkVVWnYzamdjOTkwUHVHUFE9PSIsImRpZCI6InVxSnQ1N1N2SVBZcE5oM1MzU3VxcktCVERiaHBoeTN6S2VyMmZVNnF3MktnMk12cVptaUhFNmJ0YSt0OUgrcUEiLCJzdHMiOjAsImlhdCI6MTc2NTI2MDEwNSwiZXhwIjoxNzczMDM2MTA1LCJwdXNoaWQiOiJvTmpMNm1ab2h4T203V3ZyZlIvcWdBPT0iLCJhdGwiOiIxIiwiaXNzIjoidXBleCJ9.NKJ_hTEYsLPcmSBHk3NTJAT8-LufA2yJBd0f9daQ7GIeNSVyliXJMEAV0x6z3-JMa52SOPIT6FdfpTnUszpe-nucT0UPeC2a4a9Uqm930alBk_erBGYX0yaRW6cQimeLRXA7MxHp8OuFsUE4ZXmDZTm8cShRfoDKTI6lXOYLEvI',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
'x-bm-client': 'WEB',
'x-bm-contract': '2',
'x-bm-device': '4e796e2e0eab358305db106ff976ef2e',
'x-bm-tag': '',
'x-bm-timezone': 'Asia/Shanghai',
'x-bm-timezone-offset': '-480',
'x-bm-ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
'x-bm-version': 'e9b215a',
# 'cookie': 'AF_SYNC=1765258261595; tradeType=pro; _ym_d=1765261165; _ym_uid=1765261165802134230; __adroll_fpc=23875168b001e1ea5b3c338cadd7fe49-1762510277666; _gcl_au=1.1.1161787028.1762510265; afUserId=1ac8dae1-3f99-4800-b10c-6a2f5b9128a2-p; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2214768493%22%2C%22first_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTlhNWRjYzQ3MWQxMzRiLTA1MmRjYWMzNjM4NTNiOC0yNjAxMTA1MS0xNDU0MDgwMC0xOWE1ZGNjNDcxZWYzMyIsIiRpZGVudGl0eV9sb2dpbl9pZCI6IjE0NzY4NDkzIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2214768493%22%7D%2C%22%24device_id%22%3A%2219a5dcc471d134b-052dcac363853b8-26011051-14540800-19a5dcc471ef33%22%7D; currentCurrency=USD; _gid=GA1.2.727267646.1765355541; _cfuvid=LqxpAwUIaf4fiq72Py_dM.deEKsZlGr2mGFEQZMcGiA-1765397364323-0.0.1.1-604800000; golang=cn; accessKey=eyJoZWFkZXIiOnsidHlwIjoiQml0TWFydCIsImFsZyI6IkJNQVBJU0lYIn0sInBheWxvYWQiOnsiamlkIjoiYzQxYWUzOGFjMjY1NDY1YjgyNDJiMGFlNGMzYmZlOWUiLCJ2ZXJzaW9uIjoiMjAyNTEyMTEiLCJleHBpcmVzQXQiOjE3NjU1MTAzMDkyMjMsImJtIjoia1NkYzJOY0JuQnVTdEsvTk1OamFlQ0R6NVRIeS9wZXIxNmdYeDZPRFBWLytxaVh0UW5WcWoyNjNobHQwSWNaQmZDVWh0N0xDUGRDZlpYYVg4aFJJekN6aGpubWxSNC9Sa2prQWNPR3NKUFo5SUp5N0MrSjhCa3pPTHJObE5mVFk0K0JjQkVCeEZuNVkvNXJEN2dYUWRVRm5MWkZpZXJ2V0doaW95ZzY5dHFFQ2JlK0FRMmJKU25qNmxRMWtNM3dCaHM2dzBvNVVhSFB4RXdmY3V5MFlObXVEZkllc1V1MFRERFRZZXFJOHltT2RqNmNUd2RuKzZlMnpJampZM3ZuVkhYOG9sblBkNTFVQ0RQM1YzUUY1QVFTRGVGd1ptYkUyTXNFR0R3QTRRTzBvZTlhMWozZWhneDlDY0IxTW1UMy96b3VrRFpESk80Tm9XVmNPU01YZzVEbDNpaU1Zeml6UWlxL1MvS1IxZUh4a0Vsa3Z6dEo1UzZGU2FYaWY3Yms2In0sInNpZ25hdHVyZSI6ImpsYTF3SUFySGtSdml2Z29QY1JKdEJMd1Vxb2RRb2VjUWFNY2NqK05XNFNXUzFjOFV1UGIvUnREd3V0Q3lGMStVVnBUbTFVQkZCQm1HekFEdjZBQnRnPT0ifQ==; accessSalt=wxtMqnh06IDcwNWA2CJXVcWJgQEhONNngZu; tokenAt=1765510309223; tokenSt=1765423911627; __cf_bm=0C1pnUOIxv6UEs41adhYfAK6xRZl4W8j5Vz1QJgiNJQ-1765424190-1.0.1.1-5hfWqfjxsvm3ebMH8k5InFTDa9.ASF9nnizvLopXaacWUKoOTCPj0AC42fjXnve7Q.oVOJHIz3x9Gn80uQOYUWBa8gMPMhZFqYk6OLlAIds; hasDelegation=false; delegationType=0; delegationTypeList=[]; _ga_R8QWWJS24Y=GS2.1.s1765422430$o5$g1$t1765424194$j58$l0$h0; _ga_7BWH3BJ925=GS2.1.s1765422430$o6$g1$t1765424194$j58$l0$h0; _ga_PJBF32MZ6E=GS2.1.s1765422430$o6$g1$t1765424194$j58$l0$h0; _ga_0V649X1YZB=GS2.1.s1765422430$o5$g1$t1765424194$j58$l0$h0; _ga=GA1.2.1461651029.1762510272',
'vs': 'e5Q7tUk8vovXba9N9zke7gNdwbiKo6uW',
'x-sig': '211d84906d3c326d1bdd740be5f02ede',
'x-timestamp': '1765433783692',
}
params = {
'account_type': '3',
'isServerCal': '1',
json_data = {
'filterContractIdList': [
10000002,
],
'limit': 100,
'languageType': 0,
'sign': 'SIGN',
'timeZone': 'string',
}
response = requests.get(
'https://derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/accounts',
params=params,
cookies=cookies,
response = requests.post(
'https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderFillTransactionPage',
headers=headers,
json=json_data,
)
print(response.json()["data"]["accounts"][0]["available_balance"])
for i in response.json()["data"]["dataList"]:
print(i)
# Note: json_data will not be serialized by requests
# exactly as it was in the original request.
# data = '{"filterContractIdList":[10000002],"limit":100,"languageType":0,"sign":"SIGN","timeZone":"string"}'
# response = requests.post(
# 'https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderFillTransactionPage',
# headers=headers,
# data=data,
# )

441
交易/weex_交易.py Normal file
View File

@@ -0,0 +1,441 @@
import re
import time
import datetime
from tqdm import *
from loguru import *
from DrissionPage import *
from bs4 import BeautifulSoup
from curl_cffi import requests
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
class WeexTransaction:
def __init__(self, tge_id):
self.tge_port = None # tge浏览器使用端口
self.tge_id = tge_id # tge id
self.tge_url = "http://127.0.0.1:50326" # tge本地服务url
self.tge_headers = {
"Authorization": f"Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91",
"Content-Type": "application/json"
}
# 替换为你自己的钉钉机器人 Webhook 地址
self.webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=e2fafb3f46866d50fe52cbb29650ba9ef1cbc97915dde238192f04c906fe4125"
# 替换为你自己的钉钉机器人秘钥
self.secret = "SEC5f320e72d7a4eaca540c66c3d09edff2f74936517390dee99ece6dd1b3611998"
self.page = None # 浏览器对象
self.start = 0 # 持仓状态 -1:做空0维持仓1做多
self.kline_1 = None # 01
self.kline_2 = None # 01
self.direction = None # 信号类型
self.pbar = None # 进度条对象
self.session = requests.Session() # 接口请求对象
def send_dingtalk_message(self, message_content):
pass
# url = "http://8.137.99.82:9005/api/send_click?token=fegergauiernguie&phone=8613661496481"
#
# res = requests.post(
# url=url,
# json={
# "phone": "8613661496481",
# "bot_name": "ergggreef",
# "datas": [
# {"send_message": [message_content], "click_button": [""], },
# ]
#
# }
# )
#
# print(res.json())
def openBrowser(self, ): # 直接指定ID打开窗口也可以使用 createBrowser 方法返回的ID
try:
response = requests.post(
f"{self.tge_url}/api/browser/start",
json={"envId": self.tge_id},
headers=self.tge_headers
)
self.tge_port = response.json()["data"]["port"]
return True
except:
return False
def take_over_browser(self):
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except:
return False
def is_bullish(self, c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(self, c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(self, prev, curr):
"""
包住形态信号判定仅15分钟K线
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and int(c_open) <= int(p_close) and int(c_close) >= int(p_open):
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and int(c_open) >= int(p_close) and int(c_close) <= int(p_open):
return "short", "bull_bear_engulf"
return None, None
def get_price(self):
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'origin': 'https://derivatives.bitmart.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://derivatives.bitmart.com/',
'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
}
params = {
'unit': '30',
'resolution': 'M',
'contractID': '2',
'offset': '340',
'endTime': str(int(time.time())),
}
datas = []
for i in range(3):
logger.info(f"获取最新数据:{i + 1}次。。。")
try:
response = self.session.get('https://contract-v2.bitmart.com/v1/ifcontract/quote/kline', params=params,
headers=headers, timeout=5)
for i in response.json()["data"]:
insert_data = {
'id': int(i["timestamp"]) - 1,
'open': float(i["open"]),
'high': float(i["high"]),
'low': float(i["low"]),
'close': float(i["close"])
}
datas.append(insert_data)
return datas
except:
time.sleep(1)
return datas
def remove_tags_and_spaces(self, html):
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')
# 获取去除标签后的文本
text = soup.get_text()
# 去除所有空格
text = text.replace(" ", "")
return text
def to_do_page(self):
# self.page.get("https://www.weeaxs.site/zh-CN/futures/demo-trading/ETH-SUSDT")
self.mn_tab.ele('x:(//button[normalize-space(text()) = "市价"])').click()
time.sleep(1)
num = self.get_num()
if num:
logger.info("获取可用余额成功!!!")
else:
logger.error("获取可用余额失败!!!")
return
self.mn_tab.ele('x://input[@placeholder="请输入数量"]').input(float(num) / 100)
time.sleep(1)
if self.direction == "long" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
elif self.direction == "long" and self.start == -1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and self.start == 1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
def get_text(self, target_text):
# 去除目标文本中的空白字符
cleaned_target_text = re.sub(r'\s', '', target_text)
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(self.mn_tab.html, 'html.parser')
# 遍历所有标签的文本内容
for tag in soup.find_all():
tag_text = tag.get_text()
# 去除标签文本中的空白字符
cleaned_tag_text = re.sub(r'\s', '', tag_text)
if cleaned_target_text in cleaned_tag_text:
return True
else:
return False
def get_now_time(self):
# 获取当前时间戳
current_timestamp = time.time()
# 将当前时间戳转换为 datetime 对象
current_datetime = datetime.datetime.fromtimestamp(current_timestamp)
# 计算距离当前时间最近的整点或 30 分时刻
if current_datetime.minute < 30:
target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0)
else:
target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0)
# 将目标 datetime 对象转换为时间戳
target_timestamp = target_datetime.timestamp()
return int(target_timestamp)
def close_extra_tabs_in_browser(self):
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
return True
except:
pass
return False
def get_num(self):
for i in range(3):
try:
response = self.session.post(
'https://gateway2.ngsvsfx.cn/v1/gw/assetsWithBalance/new',
)
return response.json()["data"]["newContract"]["balanceList"][0]["accountRights"]
except:
time.sleep(1)
return False
def get_token(self):
tab = self.page.new_tab()
tab.listen.start("gateway2.ngsvsfx.cn/v1/user/security/getLanguageType")
tab.get(url="https://www.weeaxs.site/zh-CN/futures/ETH-USDT")
res = tab.listen.wait()
self.headers = res.request.headers
self.session.headers.update(self.headers)
tab.close()
return True
def get_position_status(self):
json_data = {
'filterContractIdList': [
10000002,
],
'limit': 100,
'languageType': 0,
'sign': 'SIGN',
'timeZone': 'string',
}
for i in range(3):
try:
response = self.session.post(
'https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderFillTransactionPage',
json=json_data,
)
datas = []
for i in response.json()["data"]["dataList"]:
datas.append(i)
if datas[0]["legacyOrderDirection"] == "OPEN_LONG":
self.start = 1
elif datas[0]["legacyOrderDirection"] == "OPEN_SHORT":
self.start = -1
else:
self.start = 0
return True
except:
time.sleep(1)
return False
def action(self):
# 获取比特端口
if self.openBrowser():
logger.info("获取打开比特成功,成功获取端口!!!")
else:
logger.error("打开比特失败!!!")
return
# 接管浏览器
if self.take_over_browser():
logger.info("接管比特浏览器成功!!!")
else:
logger.error("接管浏览器失败!!!")
return
if self.close_extra_tabs_in_browser():
logger.info('关闭多余标签页成功!!!')
else:
logger.info('关闭多余标签页失败!!!')
self.mn_tab = self.page.new_tab(url="https://www.weeaxs.site/zh-CN/futures/ETH-USDT") # 打开网页
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
while True:
# 获取当前时间
current_time = time.localtime()
current_minute = current_time.tm_min
if current_minute < 30:
self.pbar.n = current_minute
self.pbar.refresh()
else:
self.pbar.n = current_minute - 30
self.pbar.refresh()
# if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, ]: # 判断是否是 新的30分钟了
if current_minute not in range(60): # 判断是否是 新的30分钟了
time.sleep(10)
continue
self.get_token()
new_price_datas = self.get_price()
if new_price_datas:
logger.success("获取最新交易价格成功!!!")
else:
logger.info("获取最新价格有问题!!!")
continue
new_price_datas1 = sorted(new_price_datas, key=lambda x: x["id"])
self.kline_1, self.kline_2, self.kline_3 = new_price_datas1[-3:]
# 判断抓取的数据是否正确
if self.get_now_time() != self.kline_3["id"]:
continue
if self.get_position_status():
logger.info("获取仓位信息成功!!!")
else:
logger.info("获取仓位信息失败!!!")
continue
if self.start == 1:
if is_bearish(self.kline_1) and is_bearish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
elif self.start == -1:
if is_bullish(self.kline_1) and is_bullish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
self.direction, signal_key = self.check_signal(prev=self.kline_1, curr=self.kline_2) # 判断信号
if self.direction:
try:
self.to_do_page()
except Exception as e:
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()}{e}")
self.pbar.reset() # 重置进度条
self.send_dingtalk_message(
message_content=
f"{datetime.datetime.now()}"
f"目前有持仓:{"" if self.start == 0 else ("" if self.start == 1 else "")}"
f"当前信号:{"" if not self.direction else ("" if self.direction == "long" else "")}"
)
if __name__ == '__main__':
WeexTransaction(
tge_id=146473,
).action()