From 5969f427a5130d41252d68c10bcbfe8ca0b12cbb Mon Sep 17 00:00:00 2001 From: blade <8019068@qq.com> Date: Fri, 8 Aug 2025 14:25:01 +0800 Subject: [PATCH] support output last huge volume record --- config.py | 1 + .../market_monitor.cpython-312.pyc | Bin 15077 -> 17964 bytes core/biz/market_monitor.py | 59 +++++++++++++++++- market_monitor_main.py | 5 +- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/config.py b/config.py index 4cf6311..58ef29b 100644 --- a/config.py +++ b/config.py @@ -76,6 +76,7 @@ WINDOW_SIZE = {"window_sizes":[50, 80, 100, 120]} BAR_THRESHOLD = { "5m": 1000 * 60 * 5, "15m": 1000 * 60 * 15, + "30m": 1000 * 60 * 30, "1H": 1000 * 60 * 60, "4H": 1000 * 60 * 60 * 4, "1D": 1000 * 60 * 60 * 24 diff --git a/core/biz/__pycache__/market_monitor.cpython-312.pyc b/core/biz/__pycache__/market_monitor.cpython-312.pyc index ec5390a6f6255ca1b3fd8033b0e20ed4393c04f2..93d3cf58c818f8c7d79c2f046a0b1af4ed9c64a6 100644 GIT binary patch delta 7140 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 Yx4Y`s$~w}P^8xs~rOtoHGQNZV2lK1zQvd(} delta 3855 zcmb_fZ)_Xo8Gqlq^ZDP|j$=EQi(@-~?8J_prcRrLrAgYRp){pQSxPAjD_O$1p&_-m zv%|*pdZiK*8X%$YA~DoOQ>7s>l@CMNmrdFb)AnimKqV%+023O@rb(M*)O|uo+w;E?s?zm_db8$fA`i)cy}ZDdymJ3;P-y^)hA=42z|;L=Fd}Q?tOtall>`i zQN&0^DqgoQ+BuZ7ueF%S`Wt#%>Dyc&EWBmA%^Cd|IrYElRmB`$3xYf-RGEOyVR8{? z&aJxOap$Bfk}5rCTl6@Q>Z=V3^fQT|dO+fR2B%v7&h*cx@Q!!x{)ZQ4PhD6#b$;rTQuTUp9c}c80hTOpO@Z6h`5qb@+qOwRJ7zMh@cHlUja{$NdoD(=f=Ul+qbk0q9 z?LlIvTU;vOxQSE;aRPM`7f=^*(?4-X_U(`H`}gPgB`ncvqD(*H+v#uNk%V^oFL+PD zI}Xpf(C%&_f|evLYUnAB-r^G3eJq3hwk_vvY{ZMvGah1B#ix=8X{|)0@7hB2bHR%Z zE^3o(wi{8Szh5DBeI0rvVPd<9wj6bB`G|p4_F_AUn_=n8E}8z!=H>l5vfHqfh!F`q z>mnYY-NXyDhxn|z4b6dG(gOWl-KNpc$BCaVi3yyb*8~~2LayEo_>3qKg1QW_y4=R} zqWuq?F~l?6tR!}Xw1VlQBmi`T1i_HljERhr5J<;J8%Tu)sbVHDa9_PQe~idxKmEud z+51Vm*$#|1-~yyWGg1>ZN*=oGjC00naZFxC`f8z%kIJ2-OBKzv zQ|>0+P{jMRDOn5ytBqmkXWlRm2>PNcoIYu!$4FSYr(`Z^mbz(+ zte3v-3P<7=#Eb=zpm$th+(-ZE3e$hMytK{jy`EIhlvD5wz>|h2LweO&HtmWMNvLO^ zMnwnd)87I~vbV;m50=w_I#)x@RZ;BCQ1I4K8OXzwK84ws6tqs%S_6ik_p!hrlzEGz zgCwOruTGT@k+jCE=gUKRPJO66RPq~XK&YDZ`G%xB$stQ?sG-$K1{(@;m>k|ykgt-# zrh+g`LqUf2A_lbYlMMK`P|kvX7s}a#{kv}UFZ=)Xj|czQgb6=v$>gwlkqkpQYEv)# z2pP6Us$Mb?Y~n@s$oE9`sKxW1hRhxzN18Lse~t9eUr7qqr*#BcR_h09r(u`Jca$8h zD(x`WPw%2R`>o1!Br6&qSukIQvlz|#f_6(p@rH;-$VhWUk*||@lUasom@9h`2N|Rv zcon|7G2qM8;|o`Fb(tirb}U-ph;}^Q;5Vf{*;XqvzeM`z9iPmz{Uqy;g!>Lqb;}>4 zE29DWSWDfJWxCm7I?V9O=~9hATrwKp$H-^vyPj2b+u!tv6WIyt;w3ywNBU-j;{c#H`ljfw`!4$P&|u#M#a~DWJ&P)B z+wuN0ocLZa{l1XdE~Q?;+o|+l9NWK{oZw@1&vmBhl8yEC!t!b+jAZaBp5u5qiWemY?nZj_Mjh diff --git a/core/biz/market_monitor.py b/core/biz/market_monitor.py index 84fdeb5..cbc5942 100644 --- a/core/biz/market_monitor.py +++ b/core/biz/market_monitor.py @@ -1,6 +1,7 @@ import pandas as pd import numpy as np from metrics_config import METRICS_CONFIG +from config import BAR_THRESHOLD from time import time import logging @@ -12,6 +13,7 @@ def create_metrics_report( row: pd.Series, next_bar_row: pd.Series, btc_bar_row: pd.Series, + all_data: pd.DataFrame, only_output_huge_volume: bool = False, only_output_rise: bool = False, now_datetime_str: str = None, @@ -64,7 +66,7 @@ def create_metrics_report( k_shape = str(row["k_shape"]) contents.append(f"### 价格信息") contents.append(f"当前价格: {close}, 开盘价: {open}, 最高价: {high}, 最低价: {low}") - contents.append(f"涨跌幅: {pct_chg}") + contents.append(f"涨跌幅: {pct_chg}%") contents.append(f"当前K线形态: {k_shape}") volume = round(float(row["volume"]), 4) @@ -95,6 +97,10 @@ def create_metrics_report( elif close_10_low: contents.append(f"当前价格处于滑动窗口期10%分位数低点") + timestamp = int(row["timestamp"]) + last_huge_volume_info = get_last_huge_volume_record(all_data, bar, timestamp) + contents.extend(last_huge_volume_info) + long_short_info = {"多": [], "空": []} ma_long_short = str(row["ma_long_short"]) ma_long_short_value = METRICS_CONFIG.get("ma_long_short", {}).get(ma_long_short, 1) @@ -300,6 +306,57 @@ def create_metrics_report( return mark_down_text +def get_last_huge_volume_record(all_data: pd.DataFrame, bar: str, timestamp: int): + """ + 1. 获取最近一次巨量记录 + a. 获取最近一次巨量记录的日期时间 + b. 获取最近一次巨量记录的日期时间距今多少个K线 + c. 获取最近一次巨量记录的涨跌幅 + d. 获取最近一次巨量记录的成交量比率 + 2. 获得最近十个周期内,出现巨量的次数 + """ + last_record_title = f"#### 最近一次{bar}周期巨量记录信息" + results = [] + results.append(last_record_title) + try: + # 根据timestamp降序排序 + all_data = all_data.sort_values(by="timestamp", ascending=False) + # 获取timestamp小于等于timestamp的行 + earlier_huge_volume_data = all_data[(all_data["timestamp"] < timestamp) & (all_data["huge_volume"] == 1)] + + if earlier_huge_volume_data.empty: + results.append(f"窗口周期内无其他巨量记录,当前为首次出现巨量") + return results + else: + #a. 获取最近一次巨量记录的日期时间 + #b. 获取最近一次巨量记录的日期时间距今多少个K线 + #c. 获取最近一次巨量记录的涨跌幅 + #d. 获取最近一次巨量记录的成交量比率 + last_record = earlier_huge_volume_data.iloc[0] + last_record_date_time = last_record["date_time"] + last_record_timestamp = last_record["timestamp"] + last_record_pct_chg = float(round(last_record["pct_chg"], 4)) + last_record_volume_ratio = float(round(last_record["volume_ratio"], 4)) + + bar_threshold = BAR_THRESHOLD.get(bar, 1000 * 60 * 60 * 24) + period_diff = int((timestamp - last_record_timestamp) / bar_threshold) + last_record_text = f"日期时间: {last_record_date_time}" + last_record_text += f",距今{period_diff}个K线" + last_record_text += f",涨跌幅: {last_record_pct_chg}%" + last_record_text += f",成交量比率: {last_record_volume_ratio}" + results.append(last_record_text) + # 2. 获得最近十个周期内,出现巨量的次数 + # 从第2行开始取,取10行 + ten_period_data = all_data.iloc[1:11] + huge_volume_in_ten_period_count= int(ten_period_data["huge_volume"].sum()) + results.append(f"最近十个周期内,出现巨量的次数: {huge_volume_in_ten_period_count}") + return results + except Exception as e: + logging.error(f"获取最近一次巨量记录信息失败: {e}") + results.append(f"获取最近一次巨量记录信息失败: {e}") + return results + + def get_long_short_over_buy_sell( row: pd.Series, now_datetime_str: str = None, diff --git a/market_monitor_main.py b/market_monitor_main.py index 59b955f..4ba0f20 100644 --- a/market_monitor_main.py +++ b/market_monitor_main.py @@ -161,6 +161,7 @@ class MarketMonitorMain: realtime_row, next_bar_row, btc_bar_row, + real_time_data, only_output_huge_volume, only_output_rise, now_datetime_str, @@ -258,6 +259,6 @@ if __name__ == "__main__": market_monitor_main.monitor_realtime_market( symbol="PUMP-USDT", bar="15m", - only_output_huge_volume=True, - only_output_rise=True, + only_output_huge_volume=False, + only_output_rise=False, )