From b84cfc6b028a07afe08ea933132e504cbff70bbd Mon Sep 17 00:00:00 2001 From: aszerW Date: Thu, 30 Oct 2025 21:56:02 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=BD=93=E5=A4=A9=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E6=8C=87=E6=95=B0=E5=B9=B6=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E5=A4=A9=E5=92=8C=E5=91=A8cci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- em_browser_state.json | 1 - em_index_sport.py | 121 ------------------------------------------ signal_calc.py | 33 +++++++++--- 3 files changed, 27 insertions(+), 128 deletions(-) delete mode 100644 em_browser_state.json delete mode 100644 em_index_sport.py diff --git a/em_browser_state.json b/em_browser_state.json deleted file mode 100644 index c80caae..0000000 --- a/em_browser_state.json +++ /dev/null @@ -1 +0,0 @@ -{"cookies": [{"name": "fullscreengg", "value": "1", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "fullscreengg2", "value": "1", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "qgqp_b_id", "value": "3998be81d9d8e920bf1a47e9d7b68329", "domain": ".eastmoney.com", "path": "/", "expires": 1796311917.296861, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_nvi", "value": "pcDSsW8vzKoZZ2lzT5Z2i07df", "domain": ".eastmoney.com", "path": "/", "expires": 1793287917, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_si", "value": "92630991205653", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_pvi", "value": "92887489601905", "domain": ".eastmoney.com", "path": "/", "expires": 1796311917.368717, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_sp", "value": "2025-10-29%2023%3A31%3A57", "domain": ".eastmoney.com", "path": "/", "expires": 1796311917.369031, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_inirUrl", "value": "", "domain": ".eastmoney.com", "path": "/", "expires": 1796311917.369443, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_sn", "value": "1", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_psi", "value": "20251029233157369-113200313003-0751845929", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "st_asi", "value": "delete", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "nid", "value": "03decfaee3d761b8ded27f8ee073dc4b", "domain": ".eastmoney.com", "path": "/", "expires": 1769527917, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "nid_create_time", "value": "1761751917950", "domain": ".eastmoney.com", "path": "/", "expires": 1769527917, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "gvi", "value": "ppXpL14DB48utbjDwaDu6785e", "domain": ".eastmoney.com", "path": "/", "expires": 1769527917, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "gvi_create_time", "value": "1761751917950", "domain": ".eastmoney.com", "path": "/", "expires": 1769527917, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "wsc_checkuser_ok", "value": "1", "domain": ".eastmoney.com", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax"}], "origins": [{"origin": "https://quote.eastmoney.com", "localStorage": [{"name": "st_inirUrl", "value": ""}, {"name": "st_pvi", "value": "92887489601905"}, {"name": "st_sp", "value": "2025-10-29 23:31:57"}]}]} \ No newline at end of file diff --git a/em_index_sport.py b/em_index_sport.py deleted file mode 100644 index 4544e73..0000000 --- a/em_index_sport.py +++ /dev/null @@ -1,121 +0,0 @@ -import time -from playwright.sync_api import sync_playwright -from loguru import logger -import datetime -import re -import json -import pandas as pd - - -def index_data_scraper(index_code: str, data_file_path: str): - - with sync_playwright() as p: - - def on_response(response): - if "push2.eastmoney.com/api/qt/clist/get" in response.url: - try: - if response.request.failure is None and response.status == 200: - data = response.text() - # logger.info(f"最新数据: \n{data}") - - # 保存响应数据 - with open(data_file_path, "a", encoding="utf-8") as f: - f.write(data) - f.write("\n") - except Exception as e: - logger.error(f"处理响应数据失败: {e}") - - browser_state_file_path = "./em_browser_state.json" - browser = p.chromium.launch(args=["--start-maximized"], headless=True) - context = browser.new_context( - storage_state=browser_state_file_path, no_viewport=True - ) - page = context.new_page() - page.on("response", on_response) - url = f"https://quote.eastmoney.com/center/gridlist.html#{index_code}" - page.goto(url) - # page.pause() - for i in range(1, 500): - logger.info(f"第{i}次点击") - try: - page.get_by_role("link", name=">", exact=True).click(timeout=30000) - except Exception as e: - break - time.sleep(30) - - -def get_state(): - with sync_playwright() as p: - browser_state_file_path = "./em_browser_state.json" - browser = p.chromium.launch(args=["--start-maximized"], headless=False) - page = browser.new_page() - url = f"https://quote.eastmoney.com/center/gridlist.html#index_sh" - page.goto(url) - page.pause() - browser.contexts[0].storage_state(path=browser_state_file_path) - - - -def parse_data(data_file_path: str): - df_list = [] - with open(data_file_path, "r", encoding="utf-8") as f: - for line in f: - match = re.search(r"\((\{.*\})\);?$", line) - json_str = match.group(1) - data = json.loads(json_str) - inner_temp_df = pd.DataFrame(data["data"]["diff"]) - df_list.append(inner_temp_df) - temp_df = pd.concat(df_list, ignore_index=True) - temp_df["f3"] = pd.to_numeric(temp_df["f3"], errors="coerce") - temp_df.sort_values(by=["f3"], ascending=False, inplace=True, ignore_index=True) - temp_df.reset_index(inplace=True) - temp_df["index"] = temp_df["index"].astype(int) + 1 - col_name_map = { - "f12": "代码", - "f14": "名称", - "f2": "最新价", - "f3": "涨跌幅", - "f4": "涨跌额", - "f5": "成交量", - "f6": "成交额", - "f7": "振幅", - "f15": "最高", - "f16": "最低", - "f17": "今开", - "f18": "昨收", - "f10": "量比", - } - temp_df.rename( - columns=col_name_map, - inplace=True, - ) - new_cols = col_name_map.values() - temp_df = temp_df[new_cols] - for col in new_cols: - if col in [ - "代码", - "名称", - ]: - continue - temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce") - return temp_df - - -def get_index_latest_data(): - today = datetime.datetime.now().strftime("%Y%m%d") - data_file_path = f"./{today}.txt" - index_code = "index_sh" - index_code_list = ["index_sh", "index_sz", "index_components", "index_zzzs"] - for index_code in index_code_list: - logger.info(f"开始更新指数数据: {index_code}") - index_data_scraper(index_code=index_code, data_file_path=data_file_path) - df = parse_data(data_file_path) - return df - - -if __name__ == "__main__": - # df = get_index_latest_data() - # code = "000001" - # df = df[df["代码"] == code] - # print(df) - get_state() diff --git a/signal_calc.py b/signal_calc.py index c05de48..04db06e 100644 --- a/signal_calc.py +++ b/signal_calc.py @@ -70,6 +70,10 @@ def main_calc_process(): continue # 将 'date' 列转换为 datetime 类型,并设置为索引 df["date"] = pd.to_datetime(df["date"]) + # 判断最新日期是否为今天,如果不是则跳过 + today_str = datetime.now().strftime("%Y-%m-%d") + if df["date"].max().strftime("%Y-%m-%d") != today_str: + continue df = df.sort_values("date") df.set_index("date", inplace=True) @@ -93,23 +97,40 @@ def main_calc_process(): timeperiod=14, ) df_weekly = df_weekly.tail(1) - cci = df_weekly["cci"].values[0] - logger.info(f"{i}/{len(code_list)}: {code} cci: {cci}") + week_cci = df_weekly["cci"].values[0] + + df["cci"] = ta.CCI( + high=df["high"], + low=df["low"], + close=df["close"], + timeperiod=14, + ) + cci = df["cci"].tail(1).values[0] + logger.info(f"{i}/{len(code_list)}: {code} week_cci: {week_cci} day_cci: {cci}") if cci < -100: signal_list.append( - {"code": code, "name": code_info["指数名称"], "cci": cci} + { + "code": code, + "name": code_info["指数名称"], + "天cci": cci, + "周cci": week_cci, + } ) # break signal_df = pd.DataFrame(signal_list) # dingtalk.send_markdown( # f"CCI信号", signal_df.to_markdown(tablefmt="simple", index=False) # ) - dingtalk.send_text( - tabulate(signal_df, tablefmt="plain", headers="keys", showindex=False) - ) + if len(signal_list) > 0: + dingtalk.send_text( + tabulate(signal_df, tablefmt="plain", headers="keys", showindex=False) + ) + else: + logger.info("无信号") if __name__ == "__main__": + # main_calc_process() ... # main() # logger.info(datetime.now())