From c79f968ad75f9afbfd9d814874d6779d0099c72c Mon Sep 17 00:00:00 2001 From: freedakgmail Date: Wed, 22 Jul 2026 08:07:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20DB=20K=E7=BA=BF=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=94=B9=E7=94=A8LIMIT=E9=99=90=E5=88=B6=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E6=97=A5=E6=9D=A1=E6=95=B0=EF=BC=8C=E4=B8=8EAPI=E8=A1=8C?= =?UTF-8?q?=E4=B8=BA=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先DB用 trade_date >= now-120天(自然日)过滤,只返回~82个交易日; API用 limit=120 返回120个交易日。K线条数不一致导致指标计算结果 不同,进而导致信号判定不同。 改为 ORDER BY trade_date DESC LIMIT min(days,300) + reversed, 与API的limit参数行为完全一致。 --- stock-html/services/stock_algorithms.py | 26 +++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/stock-html/services/stock_algorithms.py b/stock-html/services/stock_algorithms.py index 0ff2e48..ebcc882 100644 --- a/stock-html/services/stock_algorithms.py +++ b/stock-html/services/stock_algorithms.py @@ -165,27 +165,30 @@ def get_kline_data(stock_code, days=120, use_local_db=True): def _get_kline_from_local_db(stock_code, days=120): - """从本地数据库读取K线(最快,毫秒级)""" + """从本地数据库读取K线(最快,毫秒级) + 使用 LIMIT 限制交易日条数,与外部 API 的 limit=days 行为一致。 + """ import pandas as pd try: from db import get_db, put_db conn = get_db() if not conn: return None - start_date = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d') try: with conn.cursor() as cur: cur.execute(""" SELECT trade_date, open, high, low, close, volume FROM stock_kline_daily - WHERE code = %s AND trade_date >= %s - ORDER BY trade_date - """, (stock_code, start_date)) + WHERE code = %s + ORDER BY trade_date DESC + LIMIT %s + """, (stock_code, min(days, 300))) rows = cur.fetchall() finally: put_db(conn) if rows and len(rows) >= 30: + rows = list(reversed(rows)) df = pd.DataFrame(rows, columns=['date', 'open', 'high', 'low', 'close', 'volume']) df['date'] = df['date'].astype(str) for col in ('open', 'high', 'low', 'close', 'volume'): @@ -201,7 +204,9 @@ _thread_local = threading.local() def get_kline_from_local_db_threaded(stock_code, days=120): - """多线程扫描专用:使用线程本地连接从本地DB读取K线""" + """多线程扫描专用:使用线程本地连接从本地DB读取K线 + 使用 LIMIT 限制交易日条数,与外部 API 的 limit=days 行为一致。 + """ import pandas as pd try: conn = getattr(_thread_local, 'kline_conn', None) @@ -214,17 +219,18 @@ def get_kline_from_local_db_threaded(stock_code, days=120): conn.autocommit = True _thread_local.kline_conn = conn - start_date = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d') with conn.cursor() as cur: cur.execute(""" SELECT trade_date, open, high, low, close, volume FROM stock_kline_daily - WHERE code = %s AND trade_date >= %s - ORDER BY trade_date - """, (stock_code, start_date)) + WHERE code = %s + ORDER BY trade_date DESC + LIMIT %s + """, (stock_code, min(days, 300))) rows = cur.fetchall() if rows and len(rows) >= 30: + rows = list(reversed(rows)) df = pd.DataFrame(rows, columns=['date', 'open', 'high', 'low', 'close', 'volume']) df['date'] = df['date'].astype(str) for col in ('open', 'high', 'low', 'close', 'volume'):