diff --git a/telegram/8619211027341.session b/telegram/8619211027341.session index c008fb3..4d4e536 100644 Binary files a/telegram/8619211027341.session and b/telegram/8619211027341.session differ diff --git a/telegram/bot_session.session b/telegram/bot_session.session index 33d0125..9fe0992 100644 Binary files a/telegram/bot_session.session and b/telegram/bot_session.session differ diff --git a/telegram/bot_session.session-journal b/telegram/bot_session.session-journal index 2c8066e..f1aaf4d 100644 Binary files a/telegram/bot_session.session-journal and b/telegram/bot_session.session-journal differ diff --git a/交易/bitmart_优化版.py b/交易/bitmart_优化版.py index d26dd9c..ceb1071 100644 --- a/交易/bitmart_优化版.py +++ b/交易/bitmart_优化版.py @@ -120,10 +120,12 @@ class WeexTransaction: for _ in range(3): try: tab.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT") - res = tab.listen.wait(timeout=5) + res = tab.listen.wait(timeout=15) # 请求头 + Cookies - self.session.headers.update(res.request.headers) + for i in res.request.headers: + if ":" not in i: + self.session.headers[i] = res.request.headers[i] for c in res.request.cookies: self.cookies[c["name"]] = c["value"] @@ -309,93 +311,89 @@ class WeexTransaction: self.pbar = tqdm(total=30, desc="等待半小时周期", ncols=80) - now = time.localtime() - minute = now.tm_min + while True: + now = time.localtime() + minute = now.tm_min - # 更新进度条 - self.pbar.n = minute if minute < 30 else minute - 30 - self.pbar.refresh() + # 更新进度条 + self.pbar.n = minute if minute < 30 else minute - 30 + self.pbar.refresh() - # 必须是整点或半点及前 5 分钟 - if minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 35]: - time.sleep(8) - return + # # 必须是整点或半点及前 5 分钟 + # if minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 35]: + # time.sleep(8) + # return - # 时间重复跳过 - if self.time_start == self.get_half_hour_timestamp(): - time.sleep(5) - return - - # ---- 获取 Token ---- - if not self.get_token(): - self.ding("获取 token 失败!", error=True) - return - logger.info("Token 获取成功") - - # ---- 获取价格 ---- - kdatas = self.get_price() - if not kdatas: - self.ding("获取价格失败!", error=True) - return - - self.kline_1, self.kline_2, self.kline_3 = kdatas[-3:] - if int(self.kline_3["id"]) != self.get_half_hour_timestamp(): - return - - logger.success("K线获取成功") - - self.time_start = self.get_half_hour_timestamp() - - # ---- 刷新页面 ---- - self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT") - - for i in range(3): - # ---- 获取仓位 ---- - if not self.get_position_status(): - self.ding("获取仓位失败!", error=True) + # 时间重复跳过 + if self.time_start == self.get_half_hour_timestamp(): + time.sleep(5) continue - if self.start: - break + # ---- 获取 Token ---- + if not self.get_token(): + self.ding("获取 token 失败!", error=True) + return + logger.info("Token 获取成功") - # ---- 止损平仓 ---- - try: - if self.start == 1 and is_bearish(self.kline_1) and is_bearish(self.kline_2): - self.ding("两根大阴线,平多") - self.click_safe('x://span[normalize-space(text()) ="市价"]') - self.start = 0 + # ---- 获取价格 ---- + kdatas = self.get_price() + if not kdatas: + self.ding("获取价格失败!", error=True) + return - elif self.start == -1 and is_bullish(self.kline_1) and is_bullish(self.kline_2): - self.ding("两根大阳线,平空") - self.click_safe('x://span[normalize-space(text()) ="市价"]') - self.start = 0 - except: - self.ding("止损平仓错误!", error=True) - # continue - return + self.kline_1, self.kline_2, self.kline_3 = kdatas[-3:] + if int(self.kline_3["id"]) != self.get_half_hour_timestamp(): + continue - # ---- 生成新信号 ---- - self.direction = self.check_signal(prev=self.kline_1, curr=self.kline_2) + logger.success("K线获取成功") - # ---- 执行交易 ---- - if self.direction: + self.time_start = self.get_half_hour_timestamp() + + # ---- 刷新页面 ---- + self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT") + + for i in range(3): + # ---- 获取仓位 ---- + if not self.get_position_status(): + self.ding("获取仓位失败!", error=True) + continue + + if self.start: + break + + # ---- 止损平仓 ---- try: - self.do_order() - except: - self.ding("下单失败!", error=True) + if self.start == 1 and is_bearish(self.kline_1) and is_bearish(self.kline_2): + self.ding("两根大阴线,平多") + self.click_safe('x://span[normalize-space(text()) ="市价"]') + self.start = 0 - # ---- 周期结束消息 ---- - self.pbar.reset() - self.ding( - f"持仓:{'无' if self.start == 0 else ('多' if self.start == 1 else '空')}," - f"信号:{'无' if not self.direction else ('多' if self.direction == 'long' else '空')}" - ) + elif self.start == -1 and is_bullish(self.kline_1) and is_bullish(self.kline_2): + self.ding("两根大阳线,平空") + self.click_safe('x://span[normalize-space(text()) ="市价"]') + self.start = 0 + except: + self.ding("止损平仓错误!", error=True) + # continue + return + + # ---- 生成新信号 ---- + self.direction = self.check_signal(prev=self.kline_1, curr=self.kline_2) + + # ---- 执行交易 ---- + if self.direction: + try: + self.do_order() + except: + self.ding("下单失败!", error=True) + + # ---- 周期结束消息 ---- + self.pbar.reset() + self.ding( + 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__': - while True: - try: - WeexTransaction(tge_id=196495).action() - except: - pass - time.sleep(30) + WeexTransaction(tge_id=196495).action() diff --git a/交易/weex_交易.py b/交易/weex_交易.py index f47a602..672a385 100644 --- a/交易/weex_交易.py +++ b/交易/weex_交易.py @@ -353,17 +353,18 @@ class WeexTransaction: self.pbar.refresh() if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 35]: # 判断是否是 新的30分钟了 - # if current_minute not in range(60): # 判断是否是 新的30分钟了 + # if current_minute not in range(60): # 判断是否是 新的30分钟了 time.sleep(10) continue - if not self.kline_3 or self.get_now_time() != self.kline_3["id"]: - if self.get_token(): # 获取token - logger.info("获取token成功!!!") - else: - logger.info("获取token失败!!!") - self.send_dingtalk_message(message_content=f"获取token失败!!!", type=0) - continue + if self.kline_3 and self.get_now_time() == self.kline_3["id"]: + continue + + if self.get_token(): # 获取token + logger.info("获取token成功!!!") + else: + logger.info("获取token失败!!!") + self.send_dingtalk_message(message_content=f"获取token失败!!!", type=0) new_price_datas = self.get_price() if not new_price_datas: diff --git a/交易/weex_优化版.py b/交易/weex_优化版.py deleted file mode 100644 index ba4a105..0000000 --- a/交易/weex_优化版.py +++ /dev/null @@ -1,357 +0,0 @@ -import time -import datetime -import asyncio -from tqdm import tqdm -from loguru import logger -from DrissionPage import ChromiumOptions, ChromiumPage -from curl_cffi import requests - -from 交易.tools import send_dingtalk_message - - -# ---------------------------------------------- -# 工具函数 -# ---------------------------------------------- -def is_bullish(candle): # 阳线 - return float(candle["close"]) > float(candle["open"]) - - -def is_bearish(candle): # 阴线 - return float(candle["close"]) < float(candle["open"]) - - -def now_str(): - return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - -# ---------------------------------------------- -# 主类 -# ---------------------------------------------- -class WeexTransaction: - def __init__(self, tge_id): - # ===================== 基础配置 ===================== - self.tge_id = tge_id - self.tge_port = None - self.tge_url = "http://127.0.0.1:50326" - - self.tge_headers = { - "Authorization": "Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91", - "Content-Type": "application/json" - } - - # 浏览器 - self.page: ChromiumPage = None - - # 当前仓位状态 -1空仓,0无仓位,1多仓 - self.start = 0 - - # 保存 k 线 - self.kline_1 = None - self.kline_2 = None - self.kline_3 = None - - # 当前信号方向 - self.direction = None - - # 进度条 - self.pbar = None - - # HTTP session - self.session = requests.Session() - self.session.headers = {} - - # 避免同一分钟重复触发 - self.last_action_time = None - - # ------------------------------------------------------- - # DingTalk 通知 - # ------------------------------------------------------- - def send_msg(self, msg, err=False): - prefix = "❌" if err else "🔔" - send_dingtalk_message(f"{prefix}weex:{now_str()},{msg}") - - # ------------------------------------------------------- - # BitBrowser 控制 - # ------------------------------------------------------- - def open_browser(self): - try: - resp = requests.post( - f"{self.tge_url}/api/browser/start", - json={"envId": self.tge_id}, - headers=self.tge_headers - ) - - self.tge_port = resp.json()["data"]["port"] - return True - except Exception as e: - logger.error(f"打开 TGE 浏览器失败:{e}") - return False - - def takeover_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 Exception as e: - logger.error(f"接管浏览器失败:{e}") - return False - - # ------------------------------------------------------- - # 数据接口 - # ------------------------------------------------------- - def get_price(self): - params = { - 'unit': '30', - 'resolution': 'M', - 'contractID': '2', - 'offset': '340', - 'endTime': str(int(time.time())), - } - - for _ in range(3): - try: - resp = self.session.get( - 'https://contract-v2.bitmart.com/v1/ifcontract/quote/kline', - params=params, - timeout=5 - ) - result = [] - for i in resp.json()["data"]: - result.append({ - 'id': int(i["timestamp"]) - 1, - 'open': float(i["open"]), - 'high': float(i["high"]), - 'low': float(i["low"]), - 'close': float(i["close"]), - }) - return sorted(result, key=lambda x: x["id"]) - except: - time.sleep(1) - - return None - - # ------------------------------------------------------- - # Token 获取 - # ------------------------------------------------------- - def get_token(self): - tab = self.page.new_tab() - tab.listen.start("/user/security/getLanguageType") - - for _ in range(3): - try: - tab.get("https://www.weeaxs.site/zh-CN/futures/ETH-USDT") - res = tab.listen.wait(timeout=5) - - token = res.request.headers.get("U-TOKEN") - if token: - self.session.headers["U-TOKEN"] = token - tab.close() - return True - except: - time.sleep(1) - - tab.close() - return False - - # ------------------------------------------------------- - # 获取账户余额 - # ------------------------------------------------------- - def get_balance(self): - for _ in range(3): - try: - resp = self.session.post( - "https://gateway2.ngsvsfx.cn/v1/gw/assetsWithBalance/new" - ) - return resp.json()["data"]["newContract"]["balanceList"][0]["accountRights"] - except: - time.sleep(1) - return None - - # ------------------------------------------------------- - # 查询仓位状态 - # ------------------------------------------------------- - def get_position(self): - payload = { - 'filterContractIdList': [10000002], - 'limit': 100, - 'languageType': 0, - 'sign': 'SIGN', - 'timeZone': 'string', - } - - for _ in range(3): - try: - resp = self.session.post( - "https://http-gateway2.ngsvsfx.cn/api/v1/private/order/v2/getHistoryOrderFillTransactionPage", - json=payload, - ) - lst = resp.json()["data"]["dataList"] - last = lst[0]["legacyOrderDirection"] - - if last == "OPEN_LONG": - self.start = 1 - elif last == "OPEN_SHORT": - self.start = -1 - else: - self.start = 0 - - return True - except: - time.sleep(1) - - return False - - # ------------------------------------------------------- - # 信号判断:包住形态 - # ------------------------------------------------------- - def check_signal(self, prev, curr): - p_open, p_close = prev["open"], prev["close"] - c_open, c_close = curr["open"], curr["close"] - - # 前跌后涨包住 → 多 - if is_bearish(prev) and is_bullish(curr) and c_open <= p_close and c_close >= p_open: - return "long" - - # 前涨后跌包住 → 空 - if is_bullish(prev) and is_bearish(curr) and c_open >= p_close and c_close <= p_open: - return "short" - - return None - - # ------------------------------------------------------- - # 下单逻辑 - # ------------------------------------------------------- - def place_order(self): - # 刷新余额 - balance = self.get_balance() - if not balance: - self.send_msg("获取余额失败", err=True) - return - - amount = float(balance) / 100 - self.page.ele('x://input[@placeholder="请输入数量"]').input(amount) - time.sleep(1) - - # 开仓和平仓统一逻辑 - def click(btn_text): - self.page.ele(f'x://*[contains(text(), "{btn_text}")]').click() - - if self.direction == "long": - if self.start == 0: - click("买入开多") - self.send_msg(f"开多:{amount}") - self.start = 1 - elif self.start == -1: - click("闪电平仓") - time.sleep(2) - click("买入开多") - self.send_msg(f"反手做多:{amount}") - self.start = 1 - - elif self.direction == "short": - if self.start == 0: - click("卖出开空") - self.send_msg(f"开空:{amount}") - self.start = -1 - elif self.start == 1: - click("闪电平仓") - time.sleep(2) - click("卖出开空") - self.send_msg(f"反手做空:{amount}") - self.start = -1 - - # ------------------------------------------------------- - # 主执行循环 - # ------------------------------------------------------- - def action(self): - # 1. 打开浏览器 - if not self.open_browser(): - logger.error("无法打开比特浏览器") - return - - # 2. 接管浏览器 - if not self.takeover_browser(): - logger.error("接管浏览器失败") - return - - # 3. 打开交易页 - self.page.get("https://www.weeaxs.site/zh-CN/futures/ETH-USDT") - - self.pbar = tqdm(total=30, desc="等待中", ncols=80) - - while True: - minute = datetime.datetime.now().minute - - # 更新进度条 - self.pbar.n = minute if minute < 30 else minute - 30 - self.pbar.refresh() - - # 非关键时间跳过 - if minute not in {0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 35}: - time.sleep(10) - continue - - # 避免同一分钟重复操作 - if self.kline_3 and self.last_action_time == self.kline_3["id"]: - continue - - # 获取新 token - if not self.get_token(): - self.send_msg("获取 token 失败", err=True) - continue - - # 获取 K 线 - prices = self.get_price() - if not prices: - self.send_msg("获取价格失败", err=True) - continue - - self.kline_1, self.kline_2, self.kline_3 = prices[-3:] - - self.last_action_time = self.kline_3["id"] - - # 获取仓位状态 - if not self.get_position(): - self.send_msg("获取仓位状态失败", err=True) - continue - - # 止损逻辑 - try: - if self.start == 1 and is_bearish(self.kline_1) and is_bearish(self.kline_2): - self.send_msg("平多") - self.page.ele('x://*[contains(text(), "闪电平仓")]').click() - self.start = 0 - - if self.start == -1 and is_bullish(self.kline_1) and is_bullish(self.kline_2): - self.send_msg("平空") - self.page.ele('x://*[contains(text(), "闪电平仓")]').click() - self.start = 0 - except: - self.send_msg("止损出错", err=True) - continue - - # 判断信号 - self.direction = self.check_signal(self.kline_1, self.kline_2) - - # 执行下单 - if self.direction: - try: - self.place_order() - except Exception as e: - self.send_msg(f"下单失败:{e}", err=True) - - # 推送当前状态 - self.send_msg(f"持仓:{self.start},信号:{self.direction or '无'}") - - # 重置进度条 - self.pbar.reset() - - -# ---------------------------------------------- -# 程序主入口 -# ---------------------------------------------- -if __name__ == '__main__': - WeexTransaction(tge_id=146473).action()