From d397986bad33cc7758a7af4b2bb9598b049435ab Mon Sep 17 00:00:00 2001 From: blade <8019068@qq.com> Date: Thu, 21 Aug 2025 15:19:41 +0800 Subject: [PATCH] support price abnormal monitor --- .../market_monitor.cpython-312.pyc | Bin 18009 -> 18180 bytes core/biz/market_monitor.py | 7 ++++- market_monitor_main.py | 20 +++++++++++++-- sql/query/sql_playground.sql | 24 ++++++++++-------- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/core/biz/__pycache__/market_monitor.cpython-312.pyc b/core/biz/__pycache__/market_monitor.cpython-312.pyc index 82415c4f2c1442645e0417d094a01c5c5db71aca..9ad5f2596c2d855f07f6013697995d9b49698d68 100644 GIT binary patch delta 3201 zcmb_eNo*U}8J@?T6jyQASR}P@vq@2sBU7Se?Xu#;$|BowBrmd@k>!P^oT22l$zx~) z1za0Oob*4`K;j^WqHyabaKQi#+5~nF4uZ64)E}?g z=AVE0{^h;@e>3y-b@Jmki1m*ai%G!ii%)-X#y0jF>wk&L;45iV_f!jl)Z|A?!9`uN ziyGe+Bm*@e6=@^qok(|32hwJ0d0V*EP;lp*--!#9anvB`&c_5n_JG~s)d#5?qlCb$ z4R7%+(5sE=TWJI8+u*b|ZrSA9sTnhA;O`c%EzGLBLs<1#C67cRFsN&BMp+&yMy*KW z)P{5?SanhTE?#W{26SzXB=ukw;OP!CT;9t5F%;+s<$#qAy72OY)HQs1f zZN?gF)3R+7CkRxKx?xr?!uxtF*#RHxMO(AN+5;cxMY0Dz*NcaI8K_EhNVfcTm8W&X++t1 zj=@fI%zlPZBL+^GMEJsFB{BHMB--MN^atS2CXr0RzfEHC8O34~3f!{_TT)?rPGRei zo-d^E?!>zb?`|5Grr8{J=4%6iWLmQm3M*BZ{JS)0BKgnk+m)yJWTWVxcFel4c4$%kFX~&Upm*#MnrV zu$_lKbBOft9_+5^!5+G2TMuUG?z$c@jG_n8?U+t1W7a#;6HYsx_lZI=*~Lt{`v~Y z0vvNJmOaR6SaXOdZLaM!-NmXSi+lnW8!M5?8F;6$iaSFS9Cw!E+ME?!@ElFnRWMjz zff_MYZ?U6hx`yZwqLnB7Jng89$S{iOQX__S*O^sxcNho#H9k>cSaS`kio<-IJT(bN z=*YH&7wSJIMTSu%bZ^7p7*|p`gXAb?3Ve?VyS61P4of+H>?P`u+u58+r-FGE4arF?#f#g|qVv&mEZ4+fwQwyIz2*j9A1|8g$R+lXv;3fnr%^cR4F-Q$ zqrtVXRu@KDB+iYoZy3z@+=RlCFGgO0yM7n^+Lt1)vUpxv^By8z1{~VgE?4LDrvy9)IVSTts<{!-M*9I(|@yUoQR4pCZE#Ef?jpFD=Z?=aw$a zXMeO}#PFd(_3F{_*?YqDs$IoQEdyvHBqimn=ID ztNa~k;127zu6+Bud+XQkt^fSPOh`__tAPjjb1)JNlf9+I;IA}f0vg-1R=F8H9%@g? zXBSS(0l3~iq>>ZxS$o3Y$qdd5^K;py+~QpR%#yr3cWFMmvH;JF1XOYwlHqPL2q(h_ z$S}MgzD^E6CNhp;i;+oq5IJmG!2k_-=MR%X`!I7gy}^)Yp2~S5E(%v70S7 z$8Pq#XS|)b9k~1QN1l%i_f_}P_v4=puFlS_&YWDe&tKK9eJ3)#dho^7>6umg>`%07 zrN^-s8c3q_)DwTukOY|f9*`jXweK34hU1xl`+2NIevT0hBS#oH1aD?s{wZW1Y8PaA zNsc>Y)&behNTT#frkU858GpD;21<|mk7?oE(KeEXvm?iKNoE;>KaKRHN0E)IgAGQh}QM)ooCB=nBP8lPh9(?~GDLB>ymJQ`(rl4&L$MUrPfm?7mQ z^YUgHgpsAvqtSm7JPNDhGx%q+b0X5oqp@zthZx~2VbEU+@+GEV0sdzgxUeLxWETeI zTX1=zZ!V`HO9l!*v8pY;M=!X!?OP$2Y2JP delta 2883 zcmb_eS!@$$5Z>Qc5<5O}*qimnu>)}&CpbliBfyWyb{ zg(9v&Dk_IksfU0UDpxA4)B>$|s7l+sRHAvPDj`a#DiIa>!c*t}li1$yilv?X|Cw** zn}23@*YBPpznvtuAFWoifWP`HSN5%sd~SP2bU%wpgYK5DH0PqAWK%OrH_hkk0+ce% zLs@*;oG646V`-L$7UI4Hx{UtWwHH)lAj?NBs4s;HV{mr8049wd`$7rXt`o*72ni=l zWQ(K>Hke8a{M3pb<8gy3IO819&gdZaP?j9n0@poBAh6K;*IMq`sTwpxv?81`q$@J*JDEP;Djvb|1Y z^}@GVGV#F_N~{8&vVotnk-G3?O;kkLOp7iGmrYDBweT9ZQVBJNx%v=+7QZU*DcS`1*pt*Z5g@(>VXMSg2&mGdd)G~HHj`5%S)9;PtA0}b^UB97s3X~wU{nU z#~cs_1SN7wmna*vrkn&NstM?aYKNCZVS~df`xR5FGv%~gF&*d-1XZMEN(bDwO5RTD z$Mfpa3><^KRTuGB6(lj|Z@P8`i{O@fPQwR%kHNGzc>s$S_y)Q#wr-b5WQa5pP3 zjvh+rxBBG88KquIm%dQySLot-rDhmSsRJ)!!pPr+{I$rxEm4pB+Y|Nk`AI!*_Dje> zj~TFL%R4l6Xi#3I4Oq<7;COb@2JLB-*HVa?u|Wj*93irc=N8DQP9ts9ROhHo_5`%i zI3iseM36u_8a%eSjPAK1&UqdC#s?65c9H9O21c%jVn;3fVDrHzc9$`gzjqG}&SPwz z-wi!t7$^50b`P3_@ru^y%nJqpN+9u1z_>A8Li> zDNg>H>%*tlMQdV(bCV(tWxVLZXscCIwu0ddTdC@t^Kp)(^&>^pm$pFIWvLq>IRb4{ z4sz-(oSM~TJ$1)Sv>4w)B{3cKsv%58#1^oyd^q8KSFVwfcfo|KESK_Zc&6M;V(g=2 z9ZPf5a`;g6LW`JNfOE)tn`me5d=+6II5;3$;JIia?QpFqARgW?&wV1&_wjc4t0)9t ziMg=d)`i=yNRxFq&Jg8lb+8$OjnFe=r|?kVo0i2GaeW<_aqs}M{i z9qur3#&eLs_xRZ9N2iW8`;O?EeN)5_X5A`osFF{pTQ{SM0 zxbNp!PD{t7X+7Kgkze>h@N96}$Trg^0k_gwX*!E7nC8(>Z)=7D^UOTlg|p Y5anqrU)luG{nXBv+u-}IWd_FnKMF>zJpcdz diff --git a/core/biz/market_monitor.py b/core/biz/market_monitor.py index bde56d3..b98cd48 100644 --- a/core/biz/market_monitor.py +++ b/core/biz/market_monitor.py @@ -56,7 +56,12 @@ def create_metrics_report( return volume_ratio = round(float(row["volume_ratio"]), 4) change = "涨" if pct_chg > 0 else "跌" - brief = f"{symbol} {bar} 量率: {volume_ratio} {change}: {pct_chg}%" + price_anomaly = row["price_anomaly"] + if price_anomaly: + brief = f"{symbol} {bar} 量率: {volume_ratio} {change}: {pct_chg}% 异动 价: {close}" + else: + brief = f"{symbol} {bar} 量率: {volume_ratio} {change}: {pct_chg}% 价: {close}" + if huge_volume == 1: contents.append(f"## {brief} 交易巨量报告") else: diff --git a/market_monitor_main.py b/market_monitor_main.py index 3782b2f..d289417 100644 --- a/market_monitor_main.py +++ b/market_monitor_main.py @@ -131,7 +131,7 @@ class MarketMonitorMain: ) return realtime_row = real_time_data.iloc[-1] - + real_time_data = self.calculate_price_anomaly(real_time_data, realtime_row) if only_output_huge_volume: if realtime_row["huge_volume"] == 1: logger.info(f"监控到巨量: {symbol} {bar} 窗口大小: {self.window_size}") @@ -212,6 +212,22 @@ class MarketMonitorMain: self.latest_record[symbol][bar]["timestamp"] = latest_realtime_timestamp with open(self.latest_record_file_path, "w", encoding="utf-8") as f: json.dump(self.latest_record, f, ensure_ascii=False, indent=4) + + def calculate_price_anomaly(self, data: pd.DataFrame, realtime_row: pd.Series): + k = 2 + # 计算均值和标准差 + data = data.copy()[0:-1] + pct_chg = realtime_row["pct_chg"] + pct_chg_mean = data['pct_chg'].mean() + pct_chg_std = data['pct_chg'].std() + pct_chg_upper_bound = pct_chg_mean + k * pct_chg_std + pct_chg_lower_bound = pct_chg_mean - k * pct_chg_std + if pct_chg > pct_chg_upper_bound or pct_chg < pct_chg_lower_bound: + realtime_row["price_anomaly"] = True + else: + realtime_row["price_anomaly"] = False + + return realtime_row def get_other_realtime_data( self, symbol: str, bar: str, end_time: int, next: bool = True @@ -270,7 +286,7 @@ if __name__ == "__main__": market_monitor_main = MarketMonitorMain() market_monitor_main.monitor_realtime_market( symbol="PUMP-USDT", - bar="15m", + bar="5m", only_output_huge_volume=False, only_output_rise=False, ) diff --git a/sql/query/sql_playground.sql b/sql/query/sql_playground.sql index bfa99f0..8a4248d 100644 --- a/sql/query/sql_playground.sql +++ b/sql/query/sql_playground.sql @@ -1,24 +1,27 @@ -select * from crypto_market_monitor; +select * from crypto_market_monitor +order by date_time desc; -select date_time, open, high, low, close, k_shape from crypto_market_data -WHERE symbol='DOGE-USDT' and bar='5m' and date_time > '2025-08-04 15:00:00' -order by timestamp ; +select symbol, bar, date_time, close, +pct_chg, kdj_k, kdj_d, kdj_k, kdj_pattern, +rsi_14, rsi_signal, +boll_upper, boll_middle, boll_lower, boll_pattern, boll_signal +from crypto_market_data +WHERE close > boll_upper +order by timestamp desc; select symbol, bar, window_size, date_time, close, volume, volume_ratio, huge_volume, close_20_low, low_20_low, close_10_low, low_10_low, close_80_high, close_90_high, high_80_high, high_90_high from crypto_huge_volume -WHERE symbol='BTC-USDT' and bar='5m' and window_size=100# and low_10_low=1 -order by timestamp; +WHERE symbol='XCH-USDT' and bar='5m' and window_size=120# and low_10_low=1 +order by timestamp desc; select * from crypto_huge_volume -WHERE symbol='XCH-USDT' and bar='5m' #and date_time > '2025-08-04 15:00:00' -order by timestamp asc; +WHERE symbol='BTC-USDT' and bar='5m' #and date_time > '2025-08-04 15:00:00' +order by timestamp DESC; -delete FROM crypto_market_data where symbol != 'XCH-USDT'; - select * from crypto_trade_data where symbol='XCH-USDT' order by ts desc; @@ -38,4 +41,5 @@ WHERE symbol='BTC-USDT' and bar='5m' order by timestamp desc limit 10; + SHOW VARIABLES LIKE 'max_connections'; \ No newline at end of file