admin
2025-04-08 70b51a2636858fb8cfbf39d3764d88d07286d8ad
strategy/kpl_api.py
@@ -12,12 +12,11 @@
import constant
from log_module import async_log_util
from log_module.log import logger_common, logger_kpl_jingxuan_in, logger_Overall_market_strength_score, \
    logger_stock_of_markets_plate
    logger_stock_of_markets_plate, logger_debug
# import requests
from strategy import data_cache
from strategy import basic_methods
from strategy.index_market_trend_strategy import index_trend_expectation
from strategy.kpl_data_manager import KPLStockOfMarketsPlateLogManager
from trade import middle_api_protocol
from utils import hx_qc_value_util, tool
@@ -186,37 +185,60 @@
    return json.dumps({"errcode": 0, "list": fresults})
# if __name__ == "__main__":
# print(f"打板列表t(pidType)====={daBanList(2)}")
# print(f"获取个股代码的板块==={getStockIDPlate('002766')}")
# print((f"获取个股代码的精选板块==={getCodeJingXuanBlocks('002878')}"))
# print(f"获取该概念下的个股代码及其他====={getCodesByPlate(885500)}")   《《《《《《《《《《
# print(f"获取概念中的板块中的子板块====={json.loads(getSonPlate(801085))}")
# 获取涨停信息数据
def get_limit_up_info():
    # 获取涨停信息列表
    limit_up_info = json.loads(getLimitUpInfoNew())['list']
    return limit_up_info
# print(f"获取概念中的板块强度====={getSonPlate(getCodesByPlate(getCodeJingXuanBlocks('002452')[2][0]))}")
# print(f"市场行情-行业板块 数==={len(getMarketIndustryRealRankingInfo(True))}")
# print(f"市场行情-行业板块==={json.loads(getMarketIndustryRealRankingInfo(True))}")
# 返回格式:['板块ID','板块名称','强度','涨幅','未知','成交额','''''''''强度','未知']
# print(f"市场行情-精选板块 数==={getMarketJingXuanRealRankingInfo(True)}")
# print(f"市场行情-精选板块==={json.loads(getMarketJingXuanRealRankingInfo(True))}")
# print(f"股票代码:{Market_situation_selected_sectors_No1[0]}")
# jingxuanbankuai = json.loads(getMarketJingXuanRealRankingInfo(True))
# print(f"jingxuanbankuai==={type(jingxuanbankuai)}")
# print(f"板块代码:{jingxuanbankuai['list'][0][0]},板块名称:{jingxuanbankuai['list'][0][1]},强度:{jingxuanbankuai['list'][0][2]},涨幅:{jingxuanbankuai['list'][0][3]},未知:{jingxuanbankuai['list'][0][4]},成交额:{round(jingxuanbankuai['list'][0][5]/100000000)}亿,主力净额:{round(jingxuanbankuai['list'][0][6]/100000000,2)}亿,主买:{round(jingxuanbankuai['list'][0][7]/100000000,2)}亿,主卖:{round(jingxuanbankuai['list'][0][8]/100000000,2)}亿,未知:{jingxuanbankuai['list'][0][9]},流通值:{round(jingxuanbankuai['list'][0][10]/100000000,2)}亿,未知/或为最大涨跌幅:{round(jingxuanbankuai['list'][0][11],2)},未知:{round(jingxuanbankuai['list'][0][12]/100000000,2)}亿,总市值:{round(jingxuanbankuai['list'][0][13]/100000000,2)}亿,第一季度机构持仓:{round(jingxuanbankuai['list'][0][14]/100000000,2)}亿,未知:{round(jingxuanbankuai['list'][0][15],2)},未知:{round(jingxuanbankuai['list'][0][16],2)},强度:{round(jingxuanbankuai['list'][0][17],2)}")
# # 部分板块没有子板块
# print(f"获取概念中的板块中的子板块====={json.loads(getSonPlate(801248))}")
# 获取市场情绪综合强度【完整】
def changeStatistics():
    """
    获取市场强度
    :return:
    """
    result = __base_request("https://apphwhq.longhuvip.com/w1/api/index.php",
                            f"a=ChangeStatistics&apiv=w35&c=HomeDingPan&PhoneOSNew=1&UserID=0&DeviceID=d6f20ce9-fa08-31c9-a493-536ebb8e9774&VerSion=5.13.0.0&Token=0&")
    # data = result.text
    data = json.loads(result)
    return data["info"][0]
# print(f"自由流通市值==={getZYLTAmount('603319')}")
# print((f"获取个股代码的精选板块列表==={getCodeJingXuanBlocks('002452')}"))
# print((f"获取个股代码的精选第一板块代码==={getCodeJingXuanBlocks('002452')[0][0]}"))
# print(f"获取该概念下的个股代码及其他====={json.loads(getCodesByPlate(getCodeJingXuanBlocks('002452')[0][0]))}")
# print(f"获取该概念下的个股代码及其他dddddd====={json.loads(its_strongest_sector_situation)}")
# print(f"涨停列表及概念板块={json.loads(getLimitUpInfoNew())['list']}")
########################################################################################################################################################################################################################
# 获取市场情绪综合强度
def get_market_strong():
    """
    获取市场强度
    :return:
    """
    result = __base_request("https://apphwhq.longhuvip.com/w1/api/index.php",
                            f"a=DiskReview&apiv=w35&c=HomeDingPan&VerSion=5.13.0.0&PhoneOSNew=1&DeviceID=d6f20ce9-fa08-31c9-a493-536ebb8e9773&")
    data = json.loads(result)
    return int(data["info"]["strong"])
# 市场情绪--涨跌统计
# 数据格式:
# SJZT:实际涨停  SJDT:实际跌停 SZJS:涨数量 ZT:涨停 DT:跌停  XDJS:跌数量  sign:人气概述
def getMarketFelling():
    result = __base_request("https://apphwhq.longhuvip.com/w1/api/index.php",
                            f"a=ZhangFuDetail&apiv=w35&c=HomeDingPan&PhoneOSNew=1&DeviceID=d6f20ce9-fa08-31c9-a493-536ebb8e9774&VerSion=5.13.0.0&")
    data = json.loads(result)
    return data["info"]
# market_strong = get_market_strong()
# print(f"market_strong==={market_strong}")
if __name__ == "__main__":
    MarketFelling = getMarketFelling()
    print(f"MarketFelling==={MarketFelling}")
    changeStatistics = changeStatistics()
    print(f"changeStatistics==={changeStatistics}")
# --------------------------------------------------------------------------------------------------------------------------------------------------------------
# 获取行情精选板块 强度排名
def get_market_sift_plate_its_stock_power():
@@ -226,59 +248,58 @@
    @dask.delayed
    def request_plate_codes(i):
        # 只在盘中时间获取
        now_time = tool.get_now_time_str()
        if data_cache.L1_DATA_START_TIME < now_time < data_cache.CLOSING_TIME:
            plate_name = i[1]
            # 尝试过滤掉无意义的概念板块(plate_name not in ['科创板', '北交所', '次新股', '无', 'ST板块', 'ST摘帽', '并购重组', '国企改革','超跌', '壳资源', '股权转让', '送转填权']) and '增长' in plate_name
            if (plate_name not in ['科创板', '北交所', '次新股', '无', 'ST板块', 'ST摘帽', '并购重组', '国企改革', '超跌',
                                   '壳资源', '股权转让', '送转填权']) or ('增长' in plate_name):
                # print(f"{i[1]} 强度:{i[2]}")
                # 通过板块ID获取其下面的个股强度列表
                # print(f"======={i[0]}=======")
        plate_name = i[1]
        log_data = None
        its_stock = json.loads(getCodesByPlate(i[0]))
        now_time_str = tool.get_now_time_str()
        if data_cache.OPENING_TIME < now_time_str < data_cache.NOON_MARKET_TIME:
            log_data = {plate_name: its_stock['list']}
        # 尝试过滤掉无意义的概念板块(plate_name not in ['科创板', '北交所', '次新股', '无', 'ST板块', 'ST摘帽', '并购重组', '国企改革','超跌', '壳资源', '股权转让', '送转填权']) and '增长' in plate_name
        if (plate_name not in ['科创板', '北交所', '次新股', '无', 'ST板块', 'ST摘帽', '并购重组', '国企改革', '超跌',
                               '壳资源', '股权转让', '送转填权']) or ('增长' in plate_name):
                its_stock = json.loads(getCodesByPlate(i[0]))
            # print(f"{i[1]} 强度:{i[2]}")
            # 通过板块ID获取其下面的个股强度列表
            # print(f"======={i[0]}=======")
                logger.info(f"its_stock['list']  ===》》  {its_stock['list']}")
                # logger.info(f"its_stock['list'][0]  ===  {its_stock['list'][0]}")
                async_log_util.info(logger_stock_of_markets_plate, f"{its_stock['list']}")
                its_stock_list_info = its_stock['list']
                logger.info(f"its_stock_list_info==={its_stock_list_info}")
                # 将板块强度下面对应的个股列表打印到日志中
                # for i in its_stock_list_info:
                #     if i[0] != 1:
                #         logger.info(
                #             f"l === 个股代码:{i[0]},公司名称:{i[1]},主力资金推测:{i[2]},未知0值:{i[3]},概念:{i[4]},最新价:{i[5]},当日当时涨幅:{i[6]}%,"
                #             f"成交额:{round(i[7] / 100000000, 2)} 亿,实际换手率:{i[8]}%,未知0值:{i[9]},实际流通:{round(i[10] / 100000000, 2)}亿,"
                #             f"主力买:{round(i[11] / 100000000, 2)}亿,"
                #             f"主力卖:{round(i[12] / 100000000, 2)}亿,"
                #             f"主力净额:{round(i[13] / 10000, 2)}万,买成占比:{i[14]}%,卖成占比:{i[15]}%,净成占比:{i[16]}%,买流占比:{i[17]}%,卖流占比:{i[18]}%,净流占比:{i[19]}%,"
                #             f"区间涨幅:{i[20]}%,量比:{i[21]},未知0:{i[22]},上板情况:{i[23]},上板排名:{i[24]},换手率:{i[25]}%,"
                #             f"未知空值:{i[26]},未知零值:{i[27]},收盘封单:{i[28]},最大封单:{i[29]},未知空值?:{i[30]},"
                #             f"?:{i[30]}%,?:{i[31]},??:{i[32]},振幅:{i[33]}%,未知0????:{i[34]},未知0?????:{i[35]},"
                #             f"?=:{i[36]},?总市值:{i[37]},?流通市值:{i[38]},最终归属概念(收盘后出数据?):{i[39]},领涨次数:{i[40]},"
                #             f"41未知1值:{i[41]},第三季度机构持仓【str数据勿用运算符】:{i[42]}万,?年预测净利润:{i[43]},上年预测净利润:{i[44]},年内预测净利润:{i[45]}"
                #         )
            # its_stock_list_info = its_stock['list']
            # logger.info(f"its_stock_list_info==={its_stock_list_info}")
            # 将板块强度下面对应的个股列表打印到日志中
            # for i in its_stock_list_info:
            #     if i[0] != 1:
            #         logger.info(
            #             f"l === 个股代码:{i[0]},公司名称:{i[1]},主力资金推测:{i[2]},未知0值:{i[3]},概念:{i[4]},最新价:{i[5]},当日当时涨幅:{i[6]}%,"
            #             f"成交额:{round(i[7] / 100000000, 2)} 亿,实际换手率:{i[8]}%,未知0值:{i[9]},实际流通:{round(i[10] / 100000000, 2)}亿,"
            #             f"主力买:{round(i[11] / 100000000, 2)}亿,"
            #             f"主力卖:{round(i[12] / 100000000, 2)}亿,"
            #             f"主力净额:{round(i[13] / 10000, 2)}万,买成占比:{i[14]}%,卖成占比:{i[15]}%,净成占比:{i[16]}%,买流占比:{i[17]}%,卖流占比:{i[18]}%,净流占比:{i[19]}%,"
            #             f"区间涨幅:{i[20]}%,量比:{i[21]},未知0:{i[22]},上板情况:{i[23]},上板排名:{i[24]},换手率:{i[25]}%,"
            #             f"未知空值:{i[26]},未知零值:{i[27]},收盘封单:{i[28]},最大封单:{i[29]},未知空值?:{i[30]},"
            #             f"?:{i[30]}%,?:{i[31]},??:{i[32]},振幅:{i[33]}%,未知0????:{i[34]},未知0?????:{i[35]},"
            #             f"?=:{i[36]},?总市值:{i[37]},?流通市值:{i[38]},最终归属概念(收盘后出数据?):{i[39]},领涨次数:{i[40]},"
            #             f"41未知1值:{i[41]},第三季度机构持仓【str数据勿用运算符】:{i[42]}万,?年预测净利润:{i[43]},上年预测净利润:{i[44]},年内预测净利润:{i[45]}"
            #         )
                # 初始化股票强度列表
                stock_power_list = []
                for s in its_stock['list']:
                    # 过滤掉涨幅大于  and s[6] < 6.5 且小于0%的 和 名称中包含ST的 和 涨速小于等于0%的 和 只要昨日未涨停 和 上证或深证的正股    and s[9] > 0.0025
                    if s[6] > 0 and s[1].find("ST") < 0 and s[1].find("XD") < 0 and s[23].find("板") < 0 and s[24].find("板") < 0 and (s[0].startswith('60') or s[0].startswith('00')) and s[9] > 1:
                        # print(f"{s[1]},个股代码:{s[0]},   涨幅:{s[6]}%   涨速:{s[9]}%   概念:{s[4]}   主力资金推测:{s[2]}   领涨次数:{s[40]}  今日第几板:{s[23]} 是否破版{s[24]}")
                        # 对个股强度 主要 属性列表进行装填
                        its_stock_power = [s[1], s[0], s[6], s[9], s[4], s[2], s[40]]
                        # 逐个选择性添加its_stock中的元素到个股强度列表中
                        # print(f"its_stock_power===={its_stock_power}")
                        # 整体将添加完善的个股强度列表添加到股票列表中
                        stock_power_list.append(its_stock_power)
                # print(f"stock_power_list===={stock_power_list}")
                # 过滤掉没有瞬时高强度个股的空概念
                if len(stock_power_list) != 0:
                    # 将对应板块的股票强度列表新建一个字典
                    stock_power_item = {i[1]: stock_power_list}
                    # 并更新到精选板块个股字典中
                    market_sift_plate_stock_dict.update(stock_power_item)
            # 初始化股票强度列表
            stock_power_list = []
            for s in its_stock['list']:
                # 过滤掉涨幅大于  and s[6] < 6.5 且小于0%的 和 名称中包含ST的 和 涨速小于等于0%的 和 只要昨日未涨停 和 上证或深证的正股    and s[9] > 0.0025
                if s[6] > 0 and s[1].find("ST") < 0 and s[1].find("XD") < 0 and s[23].find("板") < 0 and s[24].find("板") < 0 and (s[0].startswith('60') or s[0].startswith('00')) and s[9] > 1:
                    # print(f"{s[1]},个股代码:{s[0]},   涨幅:{s[6]}%   涨速:{s[9]}%   概念:{s[4]}   主力资金推测:{s[2]}   领涨次数:{s[40]}  今日第几板:{s[23]} 是否破版{s[24]}")
                    # 对个股强度 主要 属性列表进行装填
                    its_stock_power = [s[1], s[0], s[6], s[9], s[4], s[2], s[40]]
                    # 逐个选择性添加its_stock中的元素到个股强度列表中
                    # print(f"its_stock_power===={its_stock_power}")
                    # 整体将添加完善的个股强度列表添加到股票列表中
                    stock_power_list.append(its_stock_power)
            # print(f"stock_power_list===={stock_power_list}")
            # 过滤掉没有瞬时高强度个股的空概念
            if len(stock_power_list) != 0:
                # 将对应板块的股票强度列表新建一个字典
                stock_power_item = {i[1]: stock_power_list}
                # 并更新到精选板块个股字典中
                market_sift_plate_stock_dict.update(stock_power_item)
        return log_data
    data = (getMarketJingXuanRealRankingInfo())
    market_sift_plate = json.loads(data)
@@ -289,15 +310,24 @@
    # logger.info(f"market_sift_plate['list'][0]  ======{market_sift_plate['list'][0]}")
    # 初始化精选板块对应个股字典
    market_sift_plate_stock_dict = {}
    # if 'list' in market_sift_plate:
    #     ds = []
    #     for d in market_sift_plate['list']:
    #         ds.append(request_plate_codes(d))
    #     dask_result = batch_get_plate_codes(ds)
    #     dask_result.compute()
    #     now_time = tool.get_now_time_str()
    #     if data_cache.L1_DATA_START_TIME < now_time < data_cache.CLOSING_TIME:
    #         logger.info(f"精选板块股票强度数据更新 == {market_sift_plate_stock_dict}")
    if 'list' in market_sift_plate:
        ds = []
        for d in market_sift_plate['list']:
            ds.append(request_plate_codes(d))
        dask_result = batch_get_plate_codes(ds)
        compute_results = dask_result.compute()
        log_datas = {}
        for r in compute_results:
            if not r:
                continue
            for b in r:
                log_datas[b] = r[b]
        now_time = tool.get_now_time_str()
        if data_cache.L1_DATA_START_TIME < now_time < data_cache.NOON_MARKET_TIME:
            # logger.info(f"精选板块股票强度数据更新 == {market_sift_plate_stock_dict}")
            # 只在盘中时间获取
            KPLStockOfMarketsPlateLogManager().add_log(market_sift_plate['list'], log_datas)
    return market_sift_plate_stock_dict
@@ -319,32 +349,10 @@
                callback(its_stock_power)
                # print(f"精选板块拉升个股更新===={its_stock_power}")
        except Exception as e:
            logger_debug.exception(e)
            logger.error(f"开盘啦板块强度线程报错An error occurred: {e}")
        finally:
            time.sleep(2)
# 获取涨停信息数据
def get_limit_up_info():
    # 获取涨停信息列表
    limit_up_info = json.loads(getLimitUpInfoNew())['list']
    return limit_up_info
# 获取市场行情情绪综合强度
def get_market_strong():
    """
    获取市场强度
    :return:
    """
    result = __base_request("https://apphwhq.longhuvip.com/w1/api/index.php",
                            f"a=DiskReview&apiv=w35&c=HomeDingPan&VerSion=5.13.0.0&PhoneOSNew=1&DeviceID=d6f20ce9-fa08-31c9-a493-536ebb8e9773&")
    data = json.loads(result)
    return int(data["info"]["strong"])
# market_strong = get_market_strong()
# print(f"market_strong==={market_strong}")
# 获取涨停板块名称列表并存储本地的函数
@@ -732,68 +740,9 @@
    print(f"写入精选板块文件完成!::{now_time}")
# 获取实时大盘行情情绪综合强度 [分数] 函数 并 计算当日计划持仓数量
def get_real_time_market_strong():
    while True:
        try:
            if data_cache.position_automatic_management_switch is True:
                now_time = tool.get_now_time_str()
                if data_cache.SERVER_RESTART_TIME < now_time < data_cache.UPDATE_DATA_TIME:
                    # 获取大盘综合强度分数
                    data_cache.real_time_market_strong = get_market_strong()
                    # data_cache.time_sharing_market_strong_dirt = time_sharing_market_strong_dirt.update({now: data_cache.real_time_market_strong})
                    # 该logger.info的的日志不再需要打印,后续将转入到GUI客户端上直接显示,该数据的打印交由下方的打印机制异步执行单独存储,以便后续可视化呈现后进行更高效的数据分析
                    # logger.info(f"大盘行情情绪综合强度 [分数]==={data_cache.real_time_market_strong}分")
                    # 大盘综合强度分数 的 异步日志
                    # logger_Overall_market_strength_score.info(data_cache.real_time_market_strong)
                    async_log_util.info(logger_Overall_market_strength_score, f"{data_cache.real_time_market_strong}")
                    usefulMoney = data_cache.account_finance_dict[0].get('usefulMoney', 0)
                    logger.info(f"账户可用资金==={usefulMoney}元")
                    # 低迷情绪比例
                    low_emotion_mood_ratio = 1
                    # 33分是个两级分化阶梯不好,目前不好拿捏,暂时不用
                    # if data_cache.real_time_market_strong <= 33:
                    if data_cache.real_time_market_strong < 30:
                        low_emotion_mood_ratio = 0.1
                        if data_cache.real_time_market_strong <= 10:
                            low_emotion_mood_ratio = 0
                    logger.info(f"极端低迷情绪比例===={low_emotion_mood_ratio * 100}%")
                    data_cache.index_trend_expectation_score = index_trend_expectation()
                    logger.info(f"大盘指数情绪预期分数==={data_cache.index_trend_expectation_score}分")
                    # print(f"大盘指数情绪预期分数==={data_cache.index_trend_expectation_score}分")
                    # 目前大盘指数情绪预期分数 尚不科学 强制设置为初始0值
                    index_trend_expectation_score = 0
                    # 获取计算今天新增的持仓数量
                    addition_position_number = len(data_cache.addition_position_symbols_set)
                    # 定义一个今日的剩余新增持仓数量的变量
                    Unfinished_opening_plan_number = 3 - addition_position_number
                    if Unfinished_opening_plan_number != 0:
                        # 如果GUI看盘上没有手动设置具体的下单金额,就按照评分策略的金额下单,否则就按照GUI设置的金额下单。
                        if data_cache.BUY_MONEY_PER_CODE < 0:
                            # 根据账户可用金额 计算今日计划下单金额
                            #  ((大盘综合强度分数 + 大盘指数情绪预期分数) * 0.01) * (账户可用金额 * 极端低迷情绪比例 / 今日最大新增持仓票数)
                            data_cache.today_planned_order_amount = ((data_cache.real_time_market_strong + index_trend_expectation_score) * 0.01) * (usefulMoney * low_emotion_mood_ratio / Unfinished_opening_plan_number)
                        else:
                            data_cache.today_planned_order_amount = data_cache.BUY_MONEY_PER_CODE
        except Exception as error:
            logger.error(f"获取实时大盘行情情绪综合强度[分数] 函数报错: {error}")
        finally:
            time.sleep(3)
# kpl_stocks_list_selected_blocks_process()   #在 kpl_api.py中可以调用
# stocks_list_selected_blocks(min_stocks)   #在 kpl_api.py中可以调用
# list = ['SHSE.600805','SHSE.600804']
#
# all_stocks_plate_dict(list)
if __name__ == "__main__":
    # start_time = time.time()
    # get_market_sift_plate_its_stock_power()
    # print("耗时:", time.time() - start_time)
    get_market_sift_plate_its_stock_power_process(None)