From 06c178f6e7ef31463c9e1479038b18bd936afbac Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sat, 3 May 2025 21:50:09 +0800 Subject: [PATCH] update --- .../__pycache__/binance_api.cpython-313.pyc | Bin 6825 -> 7875 bytes cryptoai/api/binance_api.py | 24 ++++++- cryptoai/config/config.yaml | 1 + cryptoai/monitor_endpoint.py | 28 ++++++++ cryptoai/monitors/volume_growup.py | 68 ++++++++++++++++++ cryptoai/{main.py => task_endpoint.py} | 13 +--- docker-compose.yml | 11 +++ run.py | 4 +- run_monitor.py | 4 ++ 9 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 cryptoai/monitor_endpoint.py create mode 100644 cryptoai/monitors/volume_growup.py rename cryptoai/{main.py => task_endpoint.py} (88%) create mode 100644 run_monitor.py diff --git a/cryptoai/api/__pycache__/binance_api.cpython-313.pyc b/cryptoai/api/__pycache__/binance_api.cpython-313.pyc index 9085f492b357f1b561f92946b6f17425dd64ffbc..01b0d34723e84bbbc8a29a3abdb9ac7730c7e5c2 100644 GIT binary patch delta 2174 zcma)7|4&m_6u+;peQh7~3k3>ApmczBt1JuPBka=Ft`?w(sG6ujn+R z{8+balf5Wz*&-&(qRW!GG;z+KjQ-+}Hcl}w`$D2Hmt`A@f56UtEd!ZLcGLUmz2|(+ zd7pRh>FK2%H`}c%77L4DyjAWT``9&OU7+e_{&J>V933=pdYFbF)535}1sd0nQ`pEE zgQlRt01+)Z&P1%(%vEqKFbiN7!n6coM;O2@@RyV9&yE(Bv*zV{pA+&pGn`;=I2Yq?W)e4VG|DnCtnasHKoA z%LkNl<=8oD_Eu%|y0bK^GB_$Hu@I(|qXi{~uR!VV)hNA_7#8D_${tOMa?~eDQCZawaNPlwkz`&@N~$s7_jUL5?Eynd zBYSCV2RUldXjBeGkB7&2VKf?w2_vG)@DmeJA>!5JVqoA3LWA>^l5rWkVI%1Qh(26O zTsD${kHb<=dDph>^5(1M+3lUzV|TajyKi^ST4pTgM&<^y)s6S; zO^*$zta{mm?9Q}h1=6EFO{!{&333!q@^RG+CxPXVBzv%Ggx7-=4zIsOBSg_KSMDhb zhEMdIaVM=T>q-jAFKG2jm6J?^#hfb$j#;I&a_kyqfZ@z9LK?0BDytGI%Q!en0{j+$ z4P(fv{KC{%k&DoV5%HuJO+)11wZRoC9%H-9BA9%pI>c$;Bh(0Lr`>3T@>(;;j84i< zZUt{9K%R`ZD4(0YO>Kpxs!K=#uTIq`g_x|;NjV(O7biG#uS*`aQU`Db4Iuw|FJZvo zsMWWxLzi@YCoDcG#y4@KV8-~^B}!%G6QQsuOh&N`JLK`FQ9^JSIe?#*-l?Y({DktS+4Jw)bF)UE->fxsZOM!lT%Z`Okopv> z#pmfJdfy;mBH#e<8gd;W&zi8*Q2Uh`i-$U#$ylyXRKGHA+uNS=l9&>JXPX5c0F&z4 zPzfTAL~&?X6px6R729tVNQw!u+BHAPD7I8Sb76W}wll*MDBq_UxSKnX!;LOtOl||)% zv!(PoG#paSJ3A;P^Rsg|MU^S_<@-8G6T!6v7y@et*#%pbhK__uMPWSw(i*f=!H3AI zhrqbnVce<2r?L-EnC@3=-hA ysX9?onF(Hq@DlD;p18sllO&Ty(R#P3Eg?pd@n{F0QpAb|+c6#Ge1ZsSq`v{rSpCre delta 1149 zcmZXTO-vI(6vuaVyW1^ow=GKxE!Y->XeD5x800g7Dj$j;aUc>|Q%k#G32n{n_Ta$~ zFDAyQ!BG=W>XD;qLcD3<=EV>X#yt=YYGPtkB=Mxtd8L5pB=6U^^ZxJ6+c(?go`oaI zhTC1iv32LJ=W=89yt0P8^Irq)HCWI@Y-1*BQk#UO5I19+LBx)OSZ2EpW);kw8ha91 zK6Yu2b5-;#^3S=;S|<*bw2J21jKVp)7pv?ktKGQvFSVkHnx~D2%1q-eYrN&tUE1Gq z8}^msK8Uxmwknya%&N3X>}R$+!G#0m1Ql14s%d+yu2{oA6db25$+()G%+J!#_He|K zh;9~0E(Kj|Ejx1rW*hftz5Iyp;OVN|9JQB5AY!S5ACs_s9}{3%<%a4wE@vN~7AX>{ z`3VS$CMZ7N0d@$g&l38Iv@!jhIX#Ac+F%0S$n?fF=O6O7>IT-HaS`-rYf8 zyQBZt|Ltx;Ewn{xlAwn1ijFJig_ZCSeW?V5mB7W`aRr|ry?#1OTmUX5|+9U z^Ounrmx?oq8R5HXwqJqDvVxA?LB$?I?QpFw&m~a#p@q?<9 z-uKm`lf^~fB0?QBtB!1yf1y^RUiwxIql?8K>L-M1=$b#pcr0)f<%-t=7lb)D!?Nc| zS|`J4cIjr)EEwcC6dnK!0){{&jtrj~9<_wQ(RfVS>}^|SIn7K~AI=TrNlM?ziP`?q zl|lu$<@e8TeYpMLBgLV1f9XB9Yn9XK<4`ZUUR(_gAmpb_b!X-zXk}+y?2F+nA(Jyn zCj@K&7!BzK!~ur@qYRcmk$_jrq!LNfB$>&AsT+yJ0=L0}+~yqN&rbjjW(EXqaPMqG z>o!$9{6zT1(O-2we*FNA?s*eTZfRp4i_aUDbS0TfCk@g{UEx&d5=2W9xFAdJ&gRpF VS-qEJ=*@7mN9R%CI|nR@{s3RG?Xv&? diff --git a/cryptoai/api/binance_api.py b/cryptoai/api/binance_api.py index fe36c20..77d26ea 100644 --- a/cryptoai/api/binance_api.py +++ b/cryptoai/api/binance_api.py @@ -29,7 +29,25 @@ class BinanceAPI: print("Binance API连接成功") except BinanceAPIException as e: print(f"Binance API连接失败: {e}") - + + def get_all_symbols(self) -> List[str]: + """ + 获取所有合约交易对 + + Returns: + List[str]: 所有合约交易对列表 + """ + symbols = self.client.get_exchange_info()['symbols'] + + result = [] + # 选择USDT交易对以及 status 为 TRADING 的交易对 + for symbol in symbols: + if symbol['quoteAsset'] == 'USDT' and symbol['status'] == 'TRADING': + result.append(symbol['symbol']) + + return result + + def get_historical_klines(self, symbol: str, interval: str, start_str: str, end_str: Optional[str] = None) -> pd.DataFrame: """ 获取历史K线数据 @@ -59,8 +77,8 @@ class BinanceAPI: ]) # 转换数据类型 - df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms') - df['close_time'] = pd.to_datetime(df['close_time'], unit='ms') + df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True).map(lambda x: x.tz_convert('Asia/Shanghai')) + df['close_time'] = pd.to_datetime(df['close_time'], unit='ms', utc=True).map(lambda x: x.tz_convert('Asia/Shanghai')) for col in ['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume']: diff --git a/cryptoai/config/config.yaml b/cryptoai/config/config.yaml index 3ecc847..ec24ba8 100644 --- a/cryptoai/config/config.yaml +++ b/cryptoai/config/config.yaml @@ -71,6 +71,7 @@ discord: enabled: true crypto_webhook_url: "https://discord.com/api/webhooks/1286585288986198048/iQ-yr26ViW45GM48ql8rPu70Iumqcmn_XXAmxAcKGeiQBmTQoDPeq-TmlChvIHkw_HJ-" gold_webhook_url: "https://discord.com/api/webhooks/1367341235987021914/XVcjs6ZAZad3ZezzuudyiK_KqNUowqz2o2NJPdvwWY_EvwZVJcnVHq5M0-RQhkKV-FEQ" + volume_growup_webhook_url: "https://discord.com/api/webhooks/1368217200023961631/yl_zZK865YLNpq7F7ISwPa6ztXEjU8_V646XxL95RF7PIGEFoLCTa_dTiabkfUaUvme0" # 数据库配置 diff --git a/cryptoai/monitor_endpoint.py b/cryptoai/monitor_endpoint.py new file mode 100644 index 0000000..0df59a6 --- /dev/null +++ b/cryptoai/monitor_endpoint.py @@ -0,0 +1,28 @@ + +from cryptoai.monitors.volume_growup import VolumeGrowupMonitor +import schedule + +class MonitorEndpoint: + """ + 监控端点 + """ + def __init__(self): + self.volume_growup_monitor = VolumeGrowupMonitor() + + def run(self): + try: + print("☕️ 加密货币监控程序已启动") + times = [":00", ":05", ":10", ":15", ":20", ":25", ":30", ":35", ":40", ":45", ":50", ":55"] + for time in times: + schedule.every().hour.at(time).do(self.volume_growup_monitor.run, time_interval="5m") + + while True: + schedule.run_pending() + import time + time.sleep(1) + except Exception as e: + print(f"程序运行出错: {e}") + import traceback + traceback.print_exc() + + diff --git a/cryptoai/monitors/volume_growup.py b/cryptoai/monitors/volume_growup.py new file mode 100644 index 0000000..c45c81e --- /dev/null +++ b/cryptoai/monitors/volume_growup.py @@ -0,0 +1,68 @@ + +from cryptoai.api.binance_api import BinanceAPI +from cryptoai.utils.config_loader import ConfigLoader +import logging +from datetime import datetime, timedelta +from cryptoai.models.data_processor import DataProcessor +from cryptoai.utils.discord_bot import DiscordBot +import time +class VolumeGrowupMonitor: + """ + 成交量增长监控 + """ + def __init__(self): + self.config_loader = ConfigLoader() + self.binance_config = self.config_loader.get_binance_config() + self.discord_config = self.config_loader.get_discord_config() + self.binance_api = BinanceAPI( + api_key=self.binance_config['api_key'], + api_secret=self.binance_config['api_secret'], + test_mode=self.binance_config['test_mode'] + ) + + self.discord_bot = DiscordBot( + webhook_url=self.discord_config['volume_growup_webhook_url'] + ) + + def run(self, time_interval: str = "5m"): + binance_symbols = self.binance_api.get_all_symbols() + + # 计算开始时间 + start_time = datetime.now() - timedelta(days=1) # 3天前 + start_str = start_time.strftime("%Y-%m-%d") + + # 获取所有symbol的klines 数据 + for symbol in binance_symbols: + data = self.binance_api.get_historical_klines(symbol, time_interval, start_str) + + data_processor = DataProcessor() + processed_data = data_processor.preprocess_market_data(symbol, data) + + # 计算过去 30 根 K 线的平均交易量 + average_volume = processed_data['volume'].tail(30).mean() + + # 用上一根 k 线和过去 30 根 k 线的平均交易量计算增长率 + volume_growth = processed_data['volume'].iloc[-2] / average_volume + + print(f"{symbol} 过去 30 根 K 线的平均交易量为 {average_volume:.2f},当前交易量为 {processed_data['volume'].iloc[-1]:.2f},增长率为 {volume_growth:.2%}") + # 如果增加 5倍以上,则发送消息 + if volume_growth >= 5: + # markdown 格式,带上emoji + message = f"""🚀交易量暴涨提醒🚀 + +监控交易对:*** {symbol} *** +时间周期:***{time_interval}*** +30根K线平均交易量:***{average_volume:.2f}*** +当前交易量:***{processed_data['volume'].iloc[-2]:.2f}*** +增长率为 ***{volume_growth:.2%}*** + +""" + + self.discord_bot.send_message(message) + print(f"发送交易量上涨提醒消息到discord") + + time.sleep(1) + + + + diff --git a/cryptoai/main.py b/cryptoai/task_endpoint.py similarity index 88% rename from cryptoai/main.py rename to cryptoai/task_endpoint.py index 773d8c9..b5208b9 100644 --- a/cryptoai/main.py +++ b/cryptoai/task_endpoint.py @@ -16,14 +16,14 @@ from cryptoai.agents.crypto_agent import CryptoAgent from cryptoai.agents.gold_agent import GoldAgent from cryptoai.utils.config_loader import ConfigLoader -def main(): +def task_start(): try: # GoldAgent().start_agent() # # CryptoAgent().start_agent() # return - print("定时程序启动") + print("🚀 加密货币Agent程序已启动") # 设置 08:00, 20:00 运行一次 schedule.every().day.at("00:00").do(CryptoAgent().start_agent) schedule.every().day.at("08:00").do(CryptoAgent().start_agent) @@ -41,14 +41,7 @@ def main(): schedule.run_pending() time.sleep(1) - except KeyboardInterrupt: - print("\n程序已退出") - except Exception as e: print(f"程序运行出错: {e}") import traceback - traceback.print_exc() - - -if __name__ == "__main__": - main() \ No newline at end of file + traceback.print_exc() \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 12aee74..eca2a5c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,17 @@ services: networks: - app-network + cryptoai-monitor: + build: . + container_name: cryptoai-monitor + image: cryptoai-monitor:0.0.1 + restart: always + command: python monitor_endpoint.py + environment: + - TZ=Asia/Shanghai + networks: + - app-network + cryptoai-api: build: . container_name: cryptoai-api diff --git a/run.py b/run.py index ac1f3cc..32e5b02 100755 --- a/run.py +++ b/run.py @@ -7,7 +7,7 @@ CryptoAI 启动脚本 """ import sys -from cryptoai.main import main +from cryptoai.task_endpoint import task_start if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(task_start()) \ No newline at end of file diff --git a/run_monitor.py b/run_monitor.py new file mode 100644 index 0000000..7652245 --- /dev/null +++ b/run_monitor.py @@ -0,0 +1,4 @@ +from cryptoai.monitor_endpoint import MonitorEndpoint + +if __name__ == "__main__": + MonitorEndpoint().run() \ No newline at end of file