From 2f00a0565dcf8d652b8bb5c4caefbce1c2c92d62 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期一, 23 六月 2025 09:58:15 +0800
Subject: [PATCH] bug修复/策略完善

---
 strategy/data_analyzer.py |   92 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 83 insertions(+), 9 deletions(-)

diff --git a/strategy/data_analyzer.py b/strategy/data_analyzer.py
index 7971c9d..3c98352 100644
--- a/strategy/data_analyzer.py
+++ b/strategy/data_analyzer.py
@@ -280,8 +280,12 @@
         @param pre_close:
         @return:
         """
-        return abs(close - cls.calculate_upper_limit_price(code,
-                                                           pre_close)) < 0.01
+        return round(abs(close - cls.calculate_upper_limit_price(code,
+                                                                 pre_close)), 4) < 0.01
+
+    @classmethod
+    def is_limit_up(cls, code, close, pre_close):
+        return cls.__is_limit_up(code, close, pre_close)
 
     @classmethod
     def get_third_limit_up_days(cls, k_data, days):
@@ -422,25 +426,88 @@
         return count
 
     @classmethod
-    def is_too_high_and_not_relase_volume(cls, code, k_data):
+    def is_too_high_and_not_release_volume(cls, k_data):
         """
-        闀垮緱澶珮涓旀病鏀鹃噺锛�30涓氦鏄撴棩鍐咃紝鍑虹幇杩囨渶浣庝环锛堟渶楂樹环涔嬪墠鐨勪氦鏄撴棩锛夊埌鏈�楂樹环涔嬮棿鐨勬定骞呪墺35%鐨勭エ锛屼笖浠婃棩璺濈鏈�楂樹环閭f棩鏃犳定鍋�/鏃犵偢鏉�
+        闀垮緱澶珮涓旀病鏀鹃噺锛�30涓氦鏄撴棩鍐咃紝鍑虹幇杩囨渶浣庝环锛堟渶楂樹环涔嬪墠鐨勪氦鏄撴棩锛夊埌鏈�楂樹环涔嬮棿鐨勬定骞呪墺35%鐨勭エ锛屼笖浠婃棩璺濈鏈�楂樹环閭f棩鏃犳定鍋�/鏃犵偢鏉夸笖>=3鏉夸笖蹇呴』鏈�2杩炴澘
         @param k_data: K绾挎暟鎹垪琛�(杩�150涓氦鏄撴棩锛屼笉鍖呭惈褰撳墠浜ゆ槗鏃ワ紝鏃堕棿鍊掑簭)
         @return: 鍥涜穼鍋滃強浠ヤ笂澶╂暟
         """
         k_data = k_data[:30]
+        code = k_data[0]["sec_id"]
         # 鑾峰彇鏈�楂樹环淇℃伅
         max_high_price_data = max(k_data, key=lambda x: x["high"])
-        min_close_price_data = min([d for d in k_data if d['bob'] < max_high_price_data['bob']], key=lambda x: x["close"])
-        if (max_high_price_data['high'] - min_close_price_data['close'])/min_close_price_data['close'] < 0.35:
+        before_datas = [d for d in k_data if d['bob'] < max_high_price_data['bob']]
+        after_datas = [d for d in k_data if d['bob'] >= max_high_price_data['bob']]
+        if not before_datas:
+            return False
+        if len(before_datas) > 15:
+            # 浠庢渶楂樹环鏃ユ湡鍚戝墠鏈�澶氱湅15涓氦鏄撴棩
+            before_datas = before_datas[:15]
+        min_close_price_data = min(before_datas, key=lambda x: x["close"])
+        rate = (max_high_price_data['high'] - min_close_price_data['close']) / min_close_price_data['close']
+        rate = round(rate, 4)
+        if rate < 0.35:
             # 娑ㄥ箙灏忎簬35%
             return False
+        before_k_datas = [d for d in k_data if min_close_price_data['bob'] <= d['bob'] <= max_high_price_data['bob']]
+        before_k_datas.sort(key=lambda x: x['bob'])
+        # [鏈�浣庝环-鏈�楂樹环]鏃ユ湡鍐呮湁3涓澘涓旀湁涓よ繛鎵�
+
+        continue_2_limit_up_date = None
+        for i in range(len(before_k_datas) - 1):
+            if cls.__is_limit_up(code, before_k_datas[i]["close"],
+                                 before_k_datas[i]["pre_close"]) and cls.__is_limit_up(code,
+                                                                                       before_k_datas[i + 1]["close"],
+                                                                                       before_k_datas[i + 1][
+                                                                                           "pre_close"]):
+                continue_2_limit_up_date = before_k_datas[i + 1]['bob'][:10]
+                break
+        if not continue_2_limit_up_date:
+            # 鏃犱袱杩炴澘
+            return False
+        # 涓よ繛鏉夸箣鍚庢槸鍚︽湁鐐告澘/娑ㄥ仠
+        # 鍙�2杩炴澘涔嬪悗鐨�3涓氦鏄撴棩
+        temp_k_datas = [d for d in before_k_datas if d['bob'][:10] > continue_2_limit_up_date][:3]
+        if len([d for d in temp_k_datas if cls.__is_limit_up(code, d["high"], d["pre_close"])]) < 1:
+            # 涓よ繛鏉夸箣鍚庢湁涓定鍋�/鐐告澘涓旀椂闂村湪2杩炴澘涔嬪悗鐨�3涓氦鏄撴棩鍐�
+            return False
+
         k_data = [d for d in k_data if d['bob'] > max_high_price_data['bob']]
         # 鍒ゆ柇鏄惁娑ㄥ仠杩�
-        if len([d for d in k_data if cls.__is_limit_up(code, d["high"], d["pre_close"])]) >0:
-            # 鏈�楂樹环涔嬪悗鏈夎繃娑ㄥ仠
+        threshold_day_count = min(int(20*rate + 3), 30)
+        if len([d for d in k_data if cls.__is_limit_up(code, d["high"], d["pre_close"])]) > 0 or len(after_datas) >= threshold_day_count:
+            # 鏈�楂樹环涔嬪悗鏈夎繃娑ㄥ仠鎴栬�呮槸鏈�楂樹环鍚�10涓氦鏄撴棩
             return False
-        return True
+        return True, f"楂樹环鏃ユ湡锛歿max_high_price_data['bob'][:10]}锛屼綆浠锋棩鏈燂細{min_close_price_data['bob'][:10]}锛屼袱杩炴壋鏃ユ湡锛歿continue_2_limit_up_date}"
+
+    @classmethod
+    def is_latest_limit_up_with_no_release_volume(cls, k_data, days_count=7):
+        """
+        鏈�杩�7涓氦鏄撴棩鍐呮湁鐐告澘/棣栨澘娑ㄥ仠娆℃棩鏃犳孩浠凤紝涓旂偢鏉�/娑ㄥ仠閭f棩璺濅粖鏃ョ殑鏈�楂樹环鏃犳硶瓒呰繃鐐告澘閭f棩鐨勬渶楂樹环
+        @param days_count:
+        @param k_data: K绾挎暟鎹垪琛�(杩�150涓氦鏄撴棩锛屼笉鍖呭惈褰撳墠浜ゆ槗鏃ワ紝鏃堕棿鍊掑簭)
+        @return: 鍥涜穼鍋滃強浠ヤ笂澶╂暟
+        """
+        k_data = k_data[:days_count]
+        code = k_data[0]["sec_id"]
+        # 鎵惧埌鏈�杩戠殑娑ㄥ仠/鐐告澘
+        latest_limited_up_data = None
+        for item in k_data:
+            if cls.__is_limit_up(code, item['high'], item['pre_close']):
+                latest_limited_up_data = item
+                break
+        if not latest_limited_up_data:
+            # 鏈�杩戞病鏈夋定鍋�/鐐告澘
+            return False
+        after_datas = [x for x in k_data if x['bob'] > latest_limited_up_data['bob']]
+        if not after_datas:
+            # 鐐告澘涔嬪悗娌℃湁鏁版嵁
+            return False
+        after_max_price_data = max(after_datas, key=lambda x: x["high"])
+        if after_max_price_data['high'] > latest_limited_up_data['high']:
+            # 鏈夋渶楂樹环瑕嗙洊鐐告澘/娑ㄥ仠閭f棩鏈�楂樹环
+            return False
+        return True, f"鐐告澘/娑ㄥ仠鏃ユ湡锛歿latest_limited_up_data['bob'][:10]}"
 
 
 class K60SLineAnalyzer:
@@ -569,3 +636,10 @@
                         block_days[reason].add(date)
             return set([b for b in block_days if len(block_days[b]) == len(days_list)])
         return set()
+
+
+if __name__ == "__main__":
+    item = {'sec_id': '000037', 'open': 9.11, 'high': 9.91, 'low': 9.07, 'close': 9.25, 'volume': 34540400,
+            'pre_close': 9.02,
+            'bob': '2025-06-13 00:00:00', 'amount': 326110864}
+    print(KTickLineAnalyzer.is_limit_up(item['sec_id'], item['high'], item['pre_close']))

--
Gitblit v1.8.0