| | |
| | | |
| | | # 设置历史K线 |
| | | def set_record_datas(code, limit_up_price, record_datas): |
| | | k_format = get_k_format(limit_up_price, record_datas) |
| | | k_format = get_k_format(float(limit_up_price), record_datas) |
| | | CodeNatureRecordManager.save_k_format(code, k_format) |
| | | natures = get_nature(record_datas) |
| | | CodeNatureRecordManager.save_nature(code, natures) |
| | | |
| | | |
| | | # 获取K线形态 |
| | | # 返回 (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V) |
| | | def get_k_format(limit_up_price, record_datas): |
| | | p1 = get_lowest_price_rate(record_datas) >= 0.249 |
| | | p1_data = get_lowest_price_rate(record_datas) |
| | | p1 = p1_data[0] >= 0.249, p1_data[1] |
| | | p2 = __is_new_top(limit_up_price, record_datas) |
| | | p3 = __is_lowest(record_datas) |
| | | p4 = __is_near_new_top(limit_up_price, record_datas) |
| | |
| | | p6 = __is_v_model(record_datas) |
| | | # N字型包含了N字型 |
| | | if p5: |
| | | p6 = False |
| | | p6 = False, '' |
| | | return (p1, p2, p3, p4, p5, p6) |
| | | |
| | | |
| | | # 是否具有K线形态 |
| | | def is_has_k_format(limit_up_price, record_datas): |
| | | is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v = get_k_format(limit_up_price, record_datas) |
| | | is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v = get_k_format(float(limit_up_price), record_datas) |
| | | |
| | | # if is_too_high: |
| | | # return False, "15个交易日涨幅大于24.9%" |
| | |
| | | def get_nature(record_datas): |
| | | limit_up = is_have_limit_up(record_datas) |
| | | premium_rate = get_limit_up_premium_rate(record_datas) |
| | | result = (limit_up, premium_rate >= 0.6) |
| | | result = (limit_up, premium_rate >= 0.6,premium_rate) |
| | | |
| | | return result |
| | | |
| | |
| | | datas.sort(key=lambda x: x["bob"]) |
| | | datas = datas[-15:] |
| | | low_price = datas[0]["close"] |
| | | date = None |
| | | for data in datas: |
| | | if low_price > data["close"]: |
| | | low_price = data["close"] |
| | | return (datas[-1]["close"] - low_price) / low_price |
| | | date = data['bob'].strftime("%Y-%m-%d") |
| | | return (datas[-1]["close"] - low_price) / low_price, date |
| | | |
| | | |
| | | # 是否有涨停 |
| | |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["close"]) < 0.01: |
| | | return True |
| | | return False |
| | | |
| | | |
| | | def is_have_limit_up_by_code(code): |
| | | return False |
| | | return True, item['bob'].strftime("%Y-%m-%d") |
| | | return False, '' |
| | | |
| | | |
| | | # 是否破前高 |
| | |
| | | for data in datas: |
| | | if max_price < data["high"]: |
| | | max_price = data["high"] |
| | | if limit_up_price > max_price: |
| | | return True |
| | | return False |
| | | if limit_up_price >= max_price: |
| | | return True, '' |
| | | return False, '' |
| | | |
| | | |
| | | def is_new_top(limit_up_price, datas): |
| | | return __is_new_top(float(limit_up_price), datas)[0] |
| | | |
| | | |
| | | # 接近新高 |
| | |
| | | datas.sort(key=lambda x: x["bob"]) |
| | | datas = datas[-80:] |
| | | max_volume = 0 |
| | | price = 0 |
| | | for data in datas: |
| | | max_volume_index = 0 |
| | | |
| | | for index in range(0, len(datas)): |
| | | data = datas[index] |
| | | if max_volume < data["volume"]: |
| | | max_volume = data["volume"] |
| | | max_volume_index = index |
| | | |
| | | price = 0 |
| | | price_index = 0 |
| | | for index in range(max_volume_index, len(datas)): |
| | | data = datas[index] |
| | | if data["high"] > price: |
| | | price = data["high"] |
| | | price_index = index |
| | | |
| | | index = price_index |
| | | # 最大量当日最高价比当日之后的最高价涨幅在15%以内 |
| | | if (price - datas[max_volume_index]["high"]) / datas[max_volume_index]["high"] < 0.15: |
| | | price = datas[max_volume_index]["high"] |
| | | index = max_volume_index |
| | | |
| | | print(max_volume) |
| | | if limit_up_price < price and (price - limit_up_price) / limit_up_price < 0.03: |
| | | return True |
| | | return False |
| | | rate = (price - limit_up_price) / limit_up_price |
| | | if 0 < rate < 0.03: |
| | | return True, datas[index]['bob'].strftime("%Y-%m-%d") |
| | | return False, '' |
| | | |
| | | |
| | | # 是否跌破箱体 |
| | |
| | | if min_price > data["low"]: |
| | | min_price = data["low"] |
| | | # 近5天内的最低价 |
| | | date = '' |
| | | min_price_5 = 10000 |
| | | for data in datas[-5:]: |
| | | if min_price_5 > data["low"]: |
| | | min_price_5 = data["low"] |
| | | date = data['bob'] |
| | | if abs(min_price_5 - min_price) / min_price < 0.015: |
| | | return True |
| | | return False |
| | | return True, date.strftime("%Y-%m-%d") |
| | | return False, '' |
| | | |
| | | |
| | | # N字形 |
| | |
| | | if min_price > item["low"]: |
| | | min_price = item["low"] |
| | | if max_price > min_price: |
| | | return True |
| | | return False |
| | | return True, '' |
| | | return False, '' |
| | | |
| | | |
| | | # V字形 |
| | |
| | | min_price_index = i |
| | | |
| | | if (max_price - min_price) / max_price > 0.249: |
| | | return True |
| | | return True, '' |
| | | |
| | | return False |
| | | return False, '' |
| | | |
| | | |
| | | # 首板涨停溢价率 |
| | |
| | | rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"] |
| | | first_rate_list.append(rate) |
| | | if not first_rate_list: |
| | | return 1 |
| | | return 0 |
| | | count = 0 |
| | | for rate in first_rate_list: |
| | | if rate >= 0.01: |
| | | count += 1 |
| | | return count / len(first_rate_list) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(CodeNatureRecordManager.get_k_format("603717")) |
| | |
| | | # 设置历史量 |
| | | # max60 60天最大量 |
| | | # yesterday 昨天的量 |
| | | import json |
| | | |
| | | import global_util |
| | | import gpcode_manager |
| | | from db import redis_manager |
| | |
| | | |
| | | |
| | | # 设置历史量 |
| | | def set_histry_volumn(code, max60, yesterday): |
| | | def set_histry_volumn(code, max60, yesterday, max60_day=''): |
| | | redis = __redis_manager.getRedis() |
| | | global_util.max60_volumn[code] = max60 |
| | | global_util.yesterday_volumn[code] = yesterday |
| | | redis.setex("volumn_max60-{}".format(code), tool.get_expire(), max60) |
| | | redis.setex("volumn_max60-{}".format(code), tool.get_expire(), json.dumps((max60,max60_day))) |
| | | redis.setex("volumn_yes-{}".format(code), tool.get_expire(), yesterday) |
| | | |
| | | |
| | |
| | | redis = __redis_manager.getRedis() |
| | | if max60 is None: |
| | | max60 = redis.get("volumn_max60-{}".format(code)) |
| | | if max60: |
| | | max60 = json.loads(max60) |
| | | if yesterday is None: |
| | | yesterday = redis.get("volumn_yes-{}".format(code)) |
| | | return max60, yesterday |
| | |
| | | |
| | | |
| | | # 获取量比(今日量/max(60天最大量,昨日量)) |
| | | def get_volume_rate(code): |
| | | def get_volume_rate(code, with_info=False): |
| | | today = get_today_volumn(code) |
| | | max60, yesterday = get_histry_volumn(code) |
| | | if today is None or max60 is None or yesterday is None: |
| | | raise Exception("获取量失败") |
| | | return round(int(today) / max(int(max60), int(yesterday)), 2) |
| | | rate = round(int(today) / max(int(max60[0]), int(yesterday)), 2) |
| | | if not with_info: |
| | | return rate |
| | | return rate, (today, max(int(max60[0]), int(yesterday))) |
| | | |
| | | |
| | | # 获取量比索引 |
| | |
| | | if keys is not None: |
| | | for k in keys: |
| | | code = k.split("-")[1] |
| | | global_util.max60_volumn[code] = redis.get(k) |
| | | max60_volumn = redis.get(k) |
| | | if max60_volumn: |
| | | max60_volumn = json.loads(max60_volumn) |
| | | global_util.max60_volumn[code] = max60_volumn |
| | | keys = redis.keys("volumn_yes-*") |
| | | if keys is not None: |
| | | for k in keys: |
| | |
| | | global_util.yesterday_volumn[code] = redis.get(k) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(get_histry_volumn("603717")) |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | codes = ["000977"] |
| | | codes = ["003021"] |
| | | for code in codes: |
| | | export_l2_excel(code) |
| | |
| | | |
| | | |
| | | # 解析最大量 |
| | | def parse_max_volume(datas): |
| | | def parse_max_volume(datas, is_new_top=False): |
| | | max_volume = 0 |
| | | for i in range(len(datas)): |
| | | # 查询涨停 |
| | | item = datas[i] |
| | | volume = item["volume"] |
| | | if max_volume < volume: |
| | | max_volume = volume |
| | | # 是否有涨停 |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["high"]) < 0.01: |
| | | next_volume = 0 |
| | | if i > 0: |
| | | next_volume = datas[i - 1]["volume"] |
| | | volume = max(volume, next_volume) |
| | | return (volume, volume) |
| | | return (max_volume, max_volume) |
| | | |
| | | max_volume_date = None |
| | | if is_new_top: |
| | | # 如果是突破前高就取最大量 |
| | | for item in datas: |
| | | if max_volume < item["volume"]: |
| | | max_volume = item["volume"] |
| | | max_volume_date = item["bob"] |
| | | else: |
| | | date = None |
| | | for i in range(len(datas)): |
| | | # 查询涨停 |
| | | item = datas[i] |
| | | volume = item["volume"] |
| | | if max_volume < volume: |
| | | max_volume = volume |
| | | max_volume_date = item['bob'] |
| | | # 是否有涨停 |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["high"]) < 0.01: |
| | | next_volume = 0 |
| | | if i > 0: |
| | | next_volume = datas[i - 1]["volume"] |
| | | date = datas[i]["bob"] |
| | | if volume < next_volume: |
| | | volume = next_volume |
| | | date = datas[i - 1]["bob"] |
| | | return volume, volume, date.strftime("%Y-%m-%d") |
| | | return max_volume, max_volume, max_volume_date.strftime("%Y-%m-%d") |
| | | |
| | | |
| | | # 是否有涨停 |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | datas=(get_volumns_by_code("603083", 150)) |
| | | datas = (get_volumns_by_code("603083", 150)) |
| | | print(datas) |
| | | print(get_limit_up_money_percent(datas)) |
| | |
| | | import ths_industry_util |
| | | import tool |
| | | from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ |
| | | trade_result_manager |
| | | trade_result_manager, first_code_score_manager |
| | | from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager |
| | | from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \ |
| | | L2LimitUpSellStatisticUtil |
| | |
| | | __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager() |
| | | __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager() |
| | | __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager() |
| | | __l2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager() |
| | | __l2PlaceOrderParamsManagerDict = {} |
| | | |
| | | @classmethod |
| | | # 数据处理入口 |
| | |
| | | "l2数据预处理时间") |
| | | |
| | | if len(add_datas) > 0: |
| | | # 是否为首板代码 |
| | | is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code) |
| | | # 计算量 |
| | | volume_rate = code_volumn_manager.get_volume_rate(code) |
| | | volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate) |
| | | l2_log.debug(code,"量比:{},量索引:{}",volume_rate,volume_rate_index) |
| | | # 计算分值 |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | if limit_up_time is None: |
| | | limit_up_time = tool.get_now_time_str() |
| | | score = first_code_score_manager.get_score(code, volume_rate, limit_up_time) |
| | | cls.__l2PlaceOrderParamsManagerDict[code] = l2_trade_factor.L2PlaceOrderParamsManager(code, is_first_code, |
| | | volume_rate, |
| | | volume_rate_index, |
| | | score) |
| | | l2_log.debug(code, "量比:{},量索引:{}", volume_rate, volume_rate_index) |
| | | cls.volume_rate_info[code] = (volume_rate, volume_rate_index) |
| | | # 是否为首板代码 |
| | | is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code) |
| | | |
| | | latest_time = add_datas[len(add_datas) - 1]["val"]["time"] |
| | | # 时间差不能太大才能处理 |
| | | if not l2_trade_util.is_in_forbidden_trade_codes(code): |
| | |
| | | b_need_cancel, b_cancel_data = SecondCancelBigNumComputer.need_cancel(code, buy_single_index, |
| | | buy_exec_index, start_index, |
| | | end_index, total_data, |
| | | code_volumn_manager.get_volume_rate_index(buy_volume_rate), |
| | | code_volumn_manager.get_volume_rate_index( |
| | | buy_volume_rate), |
| | | cls.volume_rate_info[code][1], |
| | | is_first_code) |
| | | if b_need_cancel: |
| | |
| | | @classmethod |
| | | def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code): |
| | | __start_time = tool.get_now_timestamp() |
| | | can, need_clear_data, reason = cls.__can_buy(code, is_first_code) |
| | | can, need_clear_data, reason = False,False,"" |
| | | if not is_first_code: |
| | | can, need_clear_data, reason = cls.__can_buy(code) |
| | | else: |
| | | can, need_clear_data, reason = cls.__can_buy_first(code) |
| | | __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True) |
| | | # 删除虚拟下单 |
| | | if code in cls.unreal_buy_dict: |
| | |
| | | # 是否可以买 |
| | | # 返回是否可以买,是否需要清除之前的买入信息,原因 |
| | | @classmethod |
| | | def __can_buy(cls, code, is_first_code): |
| | | def __can_buy(cls, code): |
| | | __start_time = t.time() |
| | | # 判断是否为首板代码 |
| | | if is_first_code: |
| | | if not gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | | gpcode_manager.FirstCodeManager.add_limited_up_record([code]) |
| | | if not code_price_manager.Buy1PriceManager.is_can_buy(code): |
| | | return False, True, "首板代码,没在想要买名单中且未打开涨停板" |
| | | if not is_limited_up: |
| | | return False, True, "首板代码,没在想要买名单中且未涨停过" |
| | | |
| | | # 之前的代码 |
| | | # 首板代码且尚未涨停过的不能下单 |
| | | # is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | |
| | | |
| | | # 量比超过1.3的不能买 |
| | | volumn_rate = cls.volume_rate_info[code][0] |
| | | if not is_first_code and volumn_rate >= 1.3: |
| | | if volumn_rate >= 1.3: |
| | | return False, False, "最大量比超过1.3不能买" |
| | | elif is_first_code and volumn_rate >= 1.1: |
| | | return False, False, "首板最大量比超过1.1不能买" |
| | | |
| | | |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | if limit_up_time is not None: |
| | | limit_up_time_seconds = l2.l2_data_util.L2DataUtil.get_time_as_second( |
| | | limit_up_time) |
| | | if not is_first_code and limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second( |
| | | if limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second( |
| | | "13:00:00"): |
| | | return False, False, "二板下午涨停的不能买,涨停时间为{}".format(limit_up_time) |
| | | if limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second("14:55:00"): |
| | |
| | | return True, False, None |
| | | finally: |
| | | l2_data_log.l2_time(code, round((t.time() - __start_time) * 1000), "是否可以下单计算") |
| | | |
| | | @classmethod |
| | | def __can_buy_first(cls, code): |
| | | |
| | | if not gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | # 查看分数等级 |
| | | score_index = cls.__l2PlaceOrderParamsManagerDict[code].score_index |
| | | score = cls.__l2PlaceOrderParamsManagerDict[code].score |
| | | if score_index < 0: |
| | | return False, True, f"分值:{score}未达到需要买入的分数线" |
| | | if -1 < score_index < 3: |
| | | return True, False, f"分值:{score}达到主动买入的分数线,买入等级:f{score_index}" |
| | | is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | | gpcode_manager.FirstCodeManager.add_limited_up_record([code]) |
| | | if not code_price_manager.Buy1PriceManager.is_can_buy(code): |
| | | return False, True, f"首板代码,没在想要买名单中且未打开涨停板,分数:{score}" |
| | | if not is_limited_up: |
| | | return False, True, f"首板代码,没在想要买名单中且未涨停过,分数:{score}" |
| | | return True, False, "" |
| | | else: |
| | | return True, False, "在想买名单中" |
| | | |
| | | @classmethod |
| | | def __cancel_buy(cls, code): |
| | |
| | | # 是否为新获取到的位置 |
| | | new_get_single = False |
| | | if buy_single_index is None: |
| | | continue_count = cls.__l2PlaceOrderParamsManager.get_begin_continue_buy_count(cls.volume_rate_info[code][1]) |
| | | continue_count = cls.__l2PlaceOrderParamsManagerDict[code].get_begin_continue_buy_count() |
| | | # 有买入信号 |
| | | has_single, _index = cls.__compute_order_begin_pos(code, max( |
| | | (compute_start_index - continue_count - 1) if new_add else compute_start_index, 0), continue_count, |
| | |
| | | return |
| | | |
| | | if compute_index is not None: |
| | | l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{}", compute_index, threshold_money, buy_nums, |
| | | buy_count, total_datas[compute_index]) |
| | | l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{} ,量比:{} ", compute_index, threshold_money, buy_nums, |
| | | buy_count, total_datas[compute_index],cls.volume_rate_info[code][0]) |
| | | |
| | | f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index, |
| | | buy_nums, buy_count, max_num_set_new, |
| | |
| | | |
| | | @classmethod |
| | | def __get_threshmoney(cls, code): |
| | | return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code, cls.volume_rate_info[code][1]) |
| | | return cls.__l2PlaceOrderParamsManagerDict[code].get_m_val() |
| | | |
| | | # 计算万手哥笔数 |
| | | @classmethod |
| | |
| | | |
| | | # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | # 目标订单数量 |
| | | threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code, |
| | | cls.__l2PlaceOrderParamsManager.get_safe_count_rate( |
| | | cls.volume_rate_info[code][1])) |
| | | threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count() |
| | | |
| | | buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"]) |
| | | |
| | |
| | | trigger_buy = True |
| | | |
| | | # 间隔最大时间依次为:3,9,27,81 |
| | | max_space_time = cls.__l2PlaceOrderParamsManager.get_time_range(cls.volume_rate_info[code][1]) |
| | | max_space_time = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() |
| | | # 最大买量 |
| | | max_buy_num = 0 |
| | | max_buy_num_set = set(max_num_set) |
| | | |
| | | # 需要的最小大单笔数 |
| | | big_num_count = cls.__l2PlaceOrderParamsManager.get_big_num_count(cls.volume_rate_info[code][1]) |
| | | big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count() |
| | | |
| | | # 较大单的手数 |
| | | bigger_num = round(5900 / limit_up_price) |
| | |
| | | except Exception as e: |
| | | pass |
| | | |
| | | # @unittest.skip("跳过此单元测试") |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_trade(self): |
| | | code = "603801" |
| | | clear_trade_data(code) |
| | |
| | | import base64 |
| | | import json |
| | | import logging |
| | | import socketserver |
| | |
| | | import ths_industry_util |
| | | from ocr import ocr_util |
| | | from ocr.ocr_util import OcrUtil |
| | | from third_data import kpl_util |
| | | from trade import bidding_money_manager |
| | | |
| | | |
| | | class OCRServer(BaseHTTPRequestHandler): |
| | |
| | | try: |
| | | data = "" |
| | | try: |
| | | data = json.loads(_str) |
| | | except: |
| | | if type(_str) == str: |
| | | data = json.loads(_str) |
| | | else: |
| | | data = _str |
| | | except Exception as e1: |
| | | raise Exception("json解析失败") |
| | | type = data["type"] |
| | | if type == 100: |
| | | _type = data["type"] |
| | | if _type == 100: |
| | | data = data["data"] |
| | | matId = data["matId"] |
| | | index = data["index"] |
| | |
| | | return_str = json.dumps({"code": 2, "msg": "数据出错"}) |
| | | else: |
| | | return_str = json.dumps({"code": 1, "msg": "数据尚未上传完"}) |
| | | elif type == 101: |
| | | elif _type == 101: |
| | | data = data["data"] |
| | | matId = data["matId"] |
| | | index = data["index"] |
| | |
| | | return_str = json.dumps({"code": 2, "msg": "数据出错"}) |
| | | else: |
| | | return_str = json.dumps({"code": 1, "msg": "数据尚未上传完"}) |
| | | elif _type == 201: |
| | | imgdata = base64.b64decode(data["img"]) |
| | | results = ocr_util.OcrUtil.easy_ocr(imgdata) |
| | | print(results) |
| | | kpl_datas = kpl_util.parse_kpl_datas(results) |
| | | if kpl_datas: |
| | | bidding_money_manager.set_bidding_money(kpl_datas) |
| | | with open("D:/kpl.png", mode="wb") as f: |
| | | f.write(imgdata) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | if str(e).__contains__("json解析失败"): |
| | |
| | | datas = self.rfile.read(int(self.headers['content-length'])) |
| | | _str = str(datas, encoding="gbk") |
| | | # print(_str) |
| | | start = 0 |
| | | while True: |
| | | start = _str.find("Content-Disposition: form-data;", start + 1) |
| | | if start <= 0: |
| | | break |
| | | name_start = start + len("Content-Disposition: form-data;") |
| | | name_end = _str.find("\r\n\r\n", start) |
| | | if _str.find("Content-Disposition: form-data;") > -1: |
| | | start = 0 |
| | | while True: |
| | | start = _str.find("Content-Disposition: form-data;", start + 1) |
| | | if start <= 0: |
| | | break |
| | | name_start = start + len("Content-Disposition: form-data;") |
| | | name_end = _str.find("\r\n\r\n", start) |
| | | |
| | | val_end = _str.find("------", name_end) |
| | | key = _str[name_start:name_end].strip()[6:-1] |
| | | val = _str[name_end:val_end].strip() |
| | | params[key] = val |
| | | val_end = _str.find("------", name_end) |
| | | key = _str[name_start:name_end].strip()[6:-1] |
| | | val = _str[name_end:val_end].strip() |
| | | params[key] = val |
| | | else: |
| | | params = json.loads(_str) |
| | | return params |
| | | |
| | | |
| | |
| | | httpd = socketserver.TCPServer((addr, port), handler) |
| | | print("HTTP server is at: http://%s:%d/" % (addr, port)) |
| | | httpd.serve_forever() |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | str_={"id":"123"} |
| | | print(type(str_)==str) |
| | |
| | | res = cls.__ocr.ocr(mat) |
| | | return res |
| | | |
| | | @classmethod |
| | | def easy_ocr(cls, mat): |
| | | res = cls.reader.readtext(mat, detail=1) |
| | | return res |
| | | |
| | | # 返回(识别内容,位置信息) |
| | | @classmethod |
| | | def ocr_with_key(cls, mat, key): |
New file |
| | |
| | | """ |
| | | 代码信息对外输出 |
| | | """ |
| | | |
| | | # score_info 得分信息 |
| | | # 下单参数信息 |
| | | # 选股宝 |
| | | # 市场热度 |
| | | import code_volumn_manager |
| | | import global_data_loader |
| | | import global_util |
| | | import gpcode_manager |
| | | import juejin |
| | | import limit_up_time_manager |
| | | import tool |
| | | from l2 import l2_data_manager, l2_data_util, transaction_progress |
| | | from third_data import hot_block_data_process |
| | | from trade import first_code_score_manager, l2_trade_factor |
| | | from trade.l2_trade_factor import L2TradeFactorUtil |
| | | |
| | | |
| | | def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos): |
| | | html = "" |
| | | html += f"<h2>{code_info[1]} {code_info[0]}</h2><br>" |
| | | if score_info: |
| | | html += "-----买前评分-------<br>" |
| | | score_types = ["换手量能", "竞价强度", "资金力度", "日线形态", "历史股性", "板块热度", "上板时间", "市值大小", "股价大小"] |
| | | html += "<table style='font-size:25px'>" |
| | | for i in range(0, len(score_info[1])): |
| | | html += f"<tr><td>{score_types[i]}</td><td>{score_info[1][i]}</td><td>{score_info[2][i]}</td></tr>" |
| | | html += f"<tr><td><b>评分求和:</td><td>{score_info[0]}</b></td><td></td></tr>" |
| | | html += f"</table>" |
| | | |
| | | if buy_params_info: |
| | | html += "<br>-----交易参数-------<br><table>" |
| | | titles = ["买入意愿", "安全笔数", "动态M值", "买前大单", "成交进度", "买入信号", "买入执行位"] |
| | | for i in range(0, len(titles)): |
| | | html += f"<tr><td>{titles[i]}:</td><td>{buy_params_info[i]}</td></tr>" |
| | | html += "</table>" |
| | | |
| | | if xgb_code_info: |
| | | html += "<br>-----选股宝---------<br>" |
| | | xgb_code_info_dates = ["今天", "昨天", "前天", "之前"] |
| | | for i in range(0, len(xgb_code_info)): |
| | | html += f"{xgb_code_info_dates[i]}:<br>" |
| | | if xgb_code_info[i]: |
| | | for info in xgb_code_info[i]: |
| | | if i == 0: |
| | | html += f"【<font color='red'>{info[0]}</font>】,共【<font color='red'>{info[1]}</font>】只票涨停<br>第【<font color='red'>{info[2]}</font>】涨停,现价【<font color='red'>{info[3]}</font>】元,涨幅【<font color='red'>{info[4]}</font>】<br><br>" |
| | | else: |
| | | html += f"【{info[0]}】,共【{info[1]}】只票涨停<br>第【{info[2]}】涨停,现价【{info[3]}】元,涨幅【{info[4]}】<br><br>" |
| | | else: |
| | | html += f"无<br>" |
| | | if xgb_infos: |
| | | html += "<br>-----市场热度-------<br><table>" |
| | | for info in xgb_infos: |
| | | html += f"<tr><td>{info}</td></tr>" |
| | | html += "</tr>" |
| | | return html |
| | | |
| | | |
| | | def get_output_html(code): |
| | | day = tool.get_now_date_str() |
| | | is_target_code = gpcode_manager.FirstCodeManager.is_in_first_record(code) |
| | | code_info = [code, gpcode_manager.get_code_name(code)] |
| | | score_info = None |
| | | buy_params_info = None |
| | | xgb_infos = None |
| | | if is_target_code: |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, True) |
| | | (score, score_list), score_source_list = first_code_score_manager.get_score(code, volume_rate, limit_up_time, |
| | | True) |
| | | ################################买前评分################################ |
| | | # ["换手量能", "竞价强度", "资金力度", "K线形态", "历史股性", "板块热度", "上板时间", "市值大小","股价大小"] |
| | | score_list_new = [] |
| | | score_source_list_new = [] |
| | | # 换手量能 |
| | | score_list_new.append(score_list[6]) |
| | | # 获取当前量信息 |
| | | max_60, yest = code_volumn_manager.get_histry_volumn(code) |
| | | today = code_volumn_manager.get_today_volumn(code) |
| | | score_source_list_new.append(f"实时量【{round(int(today)/10000,2)}万手】÷前高量【{round(max_60[0]/10000,2)}万手-{max_60[1]}】=【{round(score_source_list[6]*100,2)}%】") |
| | | # 竞价强度 |
| | | score_list_new.append(score_list[2]) |
| | | score_source_list_new.append(f"开盘啦今日委停【{score_source_list[2] if score_source_list[2] else 0}万】") |
| | | # 资金力度 |
| | | score_list_new.append(score_list[8]) |
| | | score_source_list_new.append(f"累计金额【{score_source_list[8][0] / 10000}万】&固定m值【{score_source_list[8][1] / 10000}万】") |
| | | # K线形态 |
| | | k_score = 0 |
| | | k_source = [] |
| | | for k in score_list[3]: |
| | | k_score += k |
| | | |
| | | # (15个交易日是否涨幅24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V) |
| | | for k in range(0, len(score_source_list[3])): |
| | | if k == 0: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append("【涨幅过高】") |
| | | elif k == 1: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append("【突破前高】") |
| | | elif k == 2: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append("【超跌补涨】") |
| | | elif k == 3: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append(f"【逼近前高-{score_source_list[3][k][1]}】") |
| | | elif k == 4: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append("【N字型】") |
| | | elif k == 5: |
| | | if score_source_list[3][k][0]: |
| | | k_source.append("【V字型】") |
| | | |
| | | if not score_source_list[3][1][0] and not score_source_list[3][2][0] and not score_source_list[3][4][0] and not \ |
| | | score_source_list[3][5][0]: |
| | | k_source.append("【不满足任何形态】") |
| | | |
| | | score_list_new.append(k_score) |
| | | score_source_list_new.append("/".join(k_source)) |
| | | # 历史股性 |
| | | nature_score = 0 |
| | | nature_source = [] |
| | | for k in score_list[4]: |
| | | nature_score += k |
| | | |
| | | for n in range(0, len(score_source_list[4])): |
| | | if n == 0: |
| | | if not score_source_list[4][n]: |
| | | nature_source.append("无涨停") |
| | | else: |
| | | nature_source.append("有涨停") |
| | | if n == 1: |
| | | nature_source.append(f"首板溢价率【{score_source_list[4][2]}】") |
| | | |
| | | score_list_new.append(nature_score) |
| | | score_source_list_new.append(",".join(nature_source)) |
| | | |
| | | # 板块热度 |
| | | hot_block_score = 0 |
| | | hot_block_source = [] |
| | | for k in score_list[5]: |
| | | hot_block_score += k |
| | | for n in range(0, len(score_source_list[5])): |
| | | if n == 1: |
| | | hot_block_source.append(f"【{score_source_list[5][0]}】共{score_source_list[5][n]}个涨停") |
| | | elif n == 2: |
| | | hot_block_source.append(f"共{score_source_list[5][n]}个炸板") |
| | | score_list_new.append(hot_block_score) |
| | | score_source_list_new.append(",".join(hot_block_source)) |
| | | |
| | | # 上板时间 |
| | | score_list_new.append(score_list[7]) |
| | | score_source_list_new.append(f"上板时间【{score_source_list[7]}】") |
| | | # 市值大小 |
| | | score_list_new.append(score_list[0]) |
| | | score_source_list_new.append(f"自由市值【{round(score_source_list[0] / 100000000, 2)}亿】") |
| | | # 股价大小 |
| | | score_list_new.append(score_list[1]) |
| | | score_source_list_new.append(f"现价【{score_source_list[1]}】元") |
| | | |
| | | score_info = (score, score_list_new, score_source_list_new) |
| | | |
| | | # zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time, |
| | | # deal_big_money |
| | | |
| | | ###############################下单信息############################### |
| | | # 获取买入意愿 |
| | | volume_rate = score_source_list[6] |
| | | __L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, True, volume_rate, |
| | | code_volumn_manager.get_volume_rate_index( |
| | | volume_rate), |
| | | (score, score_list)) |
| | | __base_L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, False, volume_rate, |
| | | code_volumn_manager.get_volume_rate_index( |
| | | volume_rate), |
| | | (score, score_list)) |
| | | buy_params_info = [] |
| | | if -1 < __L2PlaceOrderParamsManager.score_index < 3: |
| | | buy_params_info.append("<font color='red'>【主动买入】</font>") |
| | | elif __L2PlaceOrderParamsManager.score_index < 0: |
| | | buy_params_info.append("【不执行买入】") |
| | | else: |
| | | buy_params_info.append("【被动买入】") |
| | | # 安全笔数 |
| | | safe_count = __L2PlaceOrderParamsManager.get_safe_count() |
| | | base_safe_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(code, True) |
| | | buy_params_info.append(f"固定安全笔数【{base_safe_count}】笔,衰减后安全笔数【{safe_count}】笔") |
| | | # 动态M值 |
| | | m = __L2PlaceOrderParamsManager.get_m_val() |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb is None: |
| | | global_data_loader.load_zyltgb() |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb) |
| | | buy_params_info.append(f"固定M值【{base_m / 10000}万】,动态M值【{m[0] / 10000}万】 ") |
| | | # 买前大单 |
| | | big_num = __L2PlaceOrderParamsManager.get_big_num_count() |
| | | base_big_num = __base_L2PlaceOrderParamsManager.get_big_num_count() |
| | | buy_params_info.append(f"固定买前大单【{base_big_num}】笔,衰减后买前大单【{big_num}】笔") |
| | | # 成交进度 |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if total_datas is None: |
| | | l2_data_util.load_l2_data(code) |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | trade_progress, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) |
| | | if trade_progress is None or trade_progress < 0 or is_default: |
| | | buy_params_info.append("未识别") |
| | | else: |
| | | data = total_datas[trade_progress] |
| | | buy_params_info.append( |
| | | f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】") |
| | | |
| | | # 买入信号 |
| | | buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | code) |
| | | |
| | | if buy_single_index is None: |
| | | buy_params_info.append("无信号") |
| | | else: |
| | | data = total_datas[buy_single_index] |
| | | buy_params_info.append( |
| | | f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】") |
| | | |
| | | if buy_exec_index is None or buy_exec_index < 0: |
| | | buy_params_info.append("未下单") |
| | | else: |
| | | data = total_datas[buy_exec_index] |
| | | buy_params_info.append( |
| | | f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】") |
| | | |
| | | ##############################选股宝################################## |
| | | xgb_code_info = [] |
| | | for i in range(0, 4): |
| | | xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day) |
| | | datas = [] |
| | | if xgb_datas: |
| | | for data in xgb_datas: |
| | | block = data[2] |
| | | block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day) |
| | | block_datas = list(block_datas) |
| | | limit_up_count = 0 |
| | | limit_up_time = None |
| | | for d in block_datas: |
| | | if len(d[4]) > 6: |
| | | limit_up_count += 1 |
| | | if d[3] == code: |
| | | limit_up_time = d[4] |
| | | |
| | | # 根据涨停时间排序 |
| | | block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00')) |
| | | |
| | | for i in range(len(block_datas)): |
| | | if block_datas[i][3] == code: |
| | | datas.append( |
| | | (block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1), |
| | | block_datas[i][5], block_datas[i][6])) |
| | | break |
| | | xgb_code_info.append(datas) |
| | | day = juejin.JueJinManager.get_previous_trading_date(day) |
| | | |
| | | ##############################热门风口################################## |
| | | xgb_infos = [] |
| | | xgb_latest_datas = hot_block_data_process.XGBHotBlockDataManager.latest_datas |
| | | if not xgb_latest_datas: |
| | | xgb_infos.append('暂未获取到数据') |
| | | else: |
| | | for block in xgb_latest_datas: |
| | | limit_up_count = 0 |
| | | for code_data in block[2]: |
| | | if len(code_data[4]) > 6: |
| | | limit_up_count += 1 |
| | | xgb_infos.append(f"【{block[0]}】,涨幅【{block[1]}】,共【{limit_up_count}】个涨停") |
| | | |
| | | return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos) |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | code = "002410" |
| | | day = '2023-03-27' |
| | | xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day) |
| | | datas = [] |
| | | if xgb_datas: |
| | | for data in xgb_datas: |
| | | block = data[2] |
| | | block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day) |
| | | block_datas = list(block_datas) |
| | | limit_up_count = 0 |
| | | limit_up_time = None |
| | | for d in block_datas: |
| | | if len(d[4]) > 6: |
| | | limit_up_count += 1 |
| | | if d[3] == code: |
| | | limit_up_time = d[4] |
| | | |
| | | # 根据涨停时间排序 |
| | | block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00')) |
| | | |
| | | for i in range(len(block_datas)): |
| | | if block_datas[i][3] == code: |
| | | datas.append((block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1), |
| | | block_datas[i][5], block_datas[i][6])) |
| | | break |
| | |
| | | import ths_industry_util |
| | | import ths_util |
| | | import tool |
| | | from output import code_info_output |
| | | from third_data import hot_block_data_process |
| | | from ths import l2_listen_pos_health_manager |
| | | from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager |
| | | from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager, \ |
| | | first_code_score_manager |
| | | import l2_code_operate |
| | | from code_data_util import ZYLTGBUtil |
| | | import l2.transaction_progress |
| | |
| | | logger_first_code_record.info("新增首板:{}", new_add_codes) |
| | | # 获取60天最大记录 |
| | | for code in codes: |
| | | need_get_volumn = False |
| | | if code not in global_util.max60_volumn or global_util.max60_volumn.get(code) is None: |
| | | need_get_volumn = True |
| | | if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature( |
| | | code) is None: |
| | | need_get_volumn = True |
| | | if need_get_volumn: |
| | | volumes_data = juejin.get_volumns_by_code(code, 150) |
| | | volumes = juejin.parse_max_volume(volumes_data[:60]) |
| | | volumes = juejin.parse_max_volume(volumes_data[:60], code_nature_analyse.is_new_top( |
| | | gpcode_manager.get_limit_up_price(code), volumes_data[:60])) |
| | | logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes) |
| | | code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1]) |
| | | code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2]) |
| | | # 判断K线形态 |
| | | is_has_k_format, msg = code_nature_analyse.is_has_k_format( |
| | | gpcode_manager.get_limit_up_price(code), volumes_data) |
| | |
| | | bad_codes.add(code) |
| | | # 加入禁止交易代码 |
| | | l2_trade_util.forbidden_trade(code) |
| | | break |
| | | else: |
| | | code_nature_analyse.set_record_datas(code, |
| | | gpcode_manager.get_limit_up_price(code), |
| | | volumes_data) |
| | | code_nature_analyse.set_record_datas(code, |
| | | gpcode_manager.get_limit_up_price(code), |
| | | volumes_data) |
| | | |
| | | # 移除代码 |
| | | listen_codes = gpcode_manager.get_listen_codes() |
| | |
| | | {"block_name": block, "block_size": len(block_datas), "index": i, |
| | | "price": block_datas[i][5], "rate": block_datas[i][6]}) |
| | | break |
| | | final_data = {'code': code, 'today': today_datas, 'last_day': last_datas} |
| | | final_data = {'code': code, 'data': code_info_output.get_output_html(code)} |
| | | return_str = json.dumps({"code": 0, "data": final_data}) |
| | | pass |
| | | # 获取最近2个交易日涨停代码 |
| | | elif type == 72: |
| | | day = tool.get_now_date_str() |
| | | last_day = juejin.JueJinManager.get_previous_trading_date(day) |
| | | data_list = list(hot_block_data_process.XGBHotBlockDataManager.list_all(day)) |
| | | data_list_last = list(hot_block_data_process.XGBHotBlockDataManager.list_all(last_day)) |
| | | data_list.extend(data_list_last) |
| | | codes_set = set() |
| | | if data_list: |
| | | for d in data_list: |
| | | if len(d[4]) > 6: |
| | | codes_set.add(d[3]) |
| | | return_str = json.dumps({"code": 0, "data": list(codes_set)}) |
| | | elif type == 201: |
| | | # 加入黑名单 |
| | | data = json.loads(_str) |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | codes = ["601698"] |
| | | codes = ["002153", "002253", "002351"] |
| | | for code in codes: |
| | | volumes_data = juejin.get_volumns_by_code(code, 150) |
| | | volumes_data = volumes_data[1:] |
| | | global_data_loader.load_zyltgb() |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price(code)) |
| | | # 判断股性 |
| | | # is_k_format, msg = code_nature_analyse.is_has_k_format(float(limit_up_price), volumes_data) |
| | | # print(code, is_k_format, msg) |
| | | volumes_data = juejin.get_volumns_by_code(code, 150) |
| | | volumes_data = volumes_data[1:] |
| | | volumes = juejin.parse_max_volume(volumes_data[:60], |
| | | code_nature_analyse.is_new_top(gpcode_manager.get_limit_up_price(code), |
| | | volumes_data[:60])) |
| | | logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes) |
| | | code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2]) |
| | | # 判断K线形态 |
| | | is_has_k_format, msg = code_nature_analyse.is_has_k_format( |
| | | gpcode_manager.get_limit_up_price(code), volumes_data) |
| | | if not is_has_k_format: |
| | | logger_first_code_record.info("{}首板K线形态不好,{}", code, msg) |
| | | # 加入禁止交易代码 |
| | | l2_trade_util.forbidden_trade(code) |
| | | |
| | | code_nature_analyse.set_record_datas(code, |
| | | limit_up_price, |
| | | gpcode_manager.get_limit_up_price(code), |
| | | volumes_data) |
| | | |
| | | print(code_nature_analyse.get_k_format(float(limit_up_price), volumes_data)) |
| | | # code_nature_analyse.set_record_datas(code, |
| | | # limit_up_price, |
| | | # volumes_data) |
| | |
| | | time.sleep(3) |
| | | # 交易时间才识别 |
| | | time_str = datetime.datetime.now().strftime("%H%M%S") |
| | | if int(time_str) < int("092500") or int(time_str) > int("150000"): |
| | | continue |
| | | if int("113000") < int(time_str) < int("130000"): |
| | | continue |
| | | # if int(time_str) < int("092500") or int(time_str) > int("150000"): |
| | | # continue |
| | | # if int("113000") < int(time_str) < int("130000"): |
| | | # continue |
| | | try: |
| | | day, result = __parseData(driver) |
| | | callback(day, result) |
| | |
| | | |
| | | class XGBHotBlockDataManager: |
| | | total_datas = [] |
| | | __last_datas={} |
| | | __last_datas = {} |
| | | latest_datas = None |
| | | |
| | | @classmethod |
| | | def save(cls,day, datas): |
| | | def save(cls, day, datas): |
| | | cls.latest_datas = datas |
| | | mysqldb = mysql_data.Mysqldb() |
| | | # 统计代码所属板块 |
| | | code_block_dict = {} |
| | |
| | | code = code_info[0].split(".")[0] |
| | | _id = f"{day}_{data[0]}_{code}" |
| | | |
| | | result = mysqldb.select_one("select count(*) from xgb_hot_block where _id='{}'".format(_id)) |
| | | if not result[0]: |
| | | result = mysqldb.select_one("select * from xgb_hot_block where _id='{}'".format(_id)) |
| | | limit_up_time = code_info[4] |
| | | if len(limit_up_time) <= 6: |
| | | limit_up_time = '' |
| | | if not result: |
| | | mysqldb.execute( |
| | | f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now())") |
| | | f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time,_first_limit_up_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now(),'{limit_up_time}')") |
| | | else: |
| | | # 如果上次的数据和这次一样就不更新,否则需要更新数据 |
| | | if cls.__last_datas.get(_id) != code_info: |
| | | # 更新 |
| | | mysqldb.execute(f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}' where _id='{_id}'") |
| | | mysqldb.execute( |
| | | f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}',_update_time=now() where _id='{_id}'") |
| | | if (not result[8] or len(result[8]) <= 6) and len(limit_up_time) >= 6: |
| | | mysqldb.execute( |
| | | f"update xgb_hot_block set _first_limit_up_time='{limit_up_time}',_update_time=now() where _id='{_id}'") |
| | | |
| | | cls.__last_datas[_id] = code_info |
| | | # 获取原来的代码所属板块,删除之前错误的板块 |
| | | old_datas = XGBHotBlockDataManager.list_by_code(code, day) |
| | |
| | | return None |
| | | |
| | | limit_up_codes_set = set() |
| | | for block in latest_datas: |
| | | if block[0] == target_block: |
| | | for code_data in block[2]: |
| | | if len(code_data[4]) > 6: |
| | | limit_up_codes_set.add(code_data[0].split('.')[0]) |
| | | if XGBHotBlockDataManager.latest_datas: |
| | | for block in XGBHotBlockDataManager.latest_datas: |
| | | if block[0] == target_block: |
| | | for code_data in block[2]: |
| | | if len(code_data[4]) > 6: |
| | | limit_up_codes_set.add(code_data[0].split('.')[0]) |
| | | limit_up_codes_set.discard(code) |
| | | limit_up_count = len(limit_up_codes_set) |
| | | |
| | | total_datas = XGBHotBlockDataManager.total_datas |
| | | codes = set() |
| | | break_codes = set() |
| | | for data in total_datas: |
| | | block = data[2] |
| | | if block != target_block: |
| | | continue |
| | | code = data[3] |
| | | limit_up_time = data[4] |
| | | if len(limit_up_time) > 6: |
| | | codes.add(code) |
| | | codes.discard(code) |
| | | codes.difference(limit_up_codes_set) |
| | | first_limit_up_time = data[8] |
| | | if len(limit_up_time) <= 6 and first_limit_up_time and len(first_limit_up_time) > 6: |
| | | break_codes.add(code) |
| | | # 排除自己 |
| | | break_codes.discard(code) |
| | | # 排除已经涨停的代码 |
| | | break_codes = break_codes.difference(limit_up_codes_set) |
| | | # 炸板个数 |
| | | break_size = len(codes) |
| | | return (limit_up_count,break_size) |
| | | |
| | | |
| | | latest_datas = [] |
| | | break_size = len(break_codes) |
| | | return target_block, limit_up_count, break_size |
| | | |
| | | |
| | | # 保存数据 |
| | | def save_datas(day, datas): |
| | | latest_datas = datas |
| | | XGBHotBlockDataManager.save(day, datas) |
| | | code_block_dict = {} |
| | | block_codes_dict = {} |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23") |
| | | get_info('002230') |
| | | # XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23") |
| | | # get_info('002230') |
| | | codes = set([1, 2, 3, 4]) |
| | | print(codes.difference(set([1, 2]))) |
New file |
| | |
| | | def parse_kpl_datas(results): |
| | | start_y = -1 |
| | | end_x = -1 |
| | | index = 0 |
| | | datas = [] |
| | | for result in results: |
| | | text = result[1] |
| | | if text.find("股票名称") > -1: |
| | | start_y = result[0][0][1] |
| | | |
| | | if text.find("竞价涨幅") > -1: |
| | | end_x = result[0][0][0] |
| | | if start_y > 0 and end_x > 0: |
| | | if result[0][0][0] < end_x and result[0][0][1] > start_y and (result[0][1][0] - result[0][0][0]) > 30: |
| | | datas.append(text) |
| | | index += 1 |
| | | datas = datas[:3 * 5] |
| | | fdatas = [] |
| | | temp = [] |
| | | for data in datas: |
| | | temp.append(data) |
| | | if len(temp) == 3: |
| | | fdatas.append((temp[2][:6], temp[1])) |
| | | temp = [] |
| | | return fdatas |
| | |
| | | |
| | | |
| | | # 获取竞价金额 |
| | | def get_bidding_money(code): |
| | | def get_bidding_money(code) -> object: |
| | | val = __get_redis().get("bidding_money") |
| | | if not val: |
| | | return None |
| | |
| | | if v[0] == code: |
| | | return v[1] |
| | | return None |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | # datas = [('002229', '10.92亿'), ('000977', '2592万'), ('000829', '2294万'), ('002467', '1869万'), ('002217', '1546万')] |
| | | # set_bidding_money(datas) |
| | | print(get_bidding_money("000977")) |
| | |
| | | return None |
| | | |
| | | |
| | | def __save_traded_index(code, index): |
| | | __get_redis().sadd(f"deal_indexes-{code}", index) |
| | | __get_redis().expire(f"deal_indexes-{code}", tool.get_expire()) |
| | | |
| | | |
| | | def __get_traded_indexes(code): |
| | | return __get_redis().smembers(f"deal_indexes-{code}") |
| | | |
| | | |
| | | # 获取成交的索引 |
| | | def get_traded_indexes(code): |
| | | return __get_traded_indexes(code) |
| | | |
| | | # 获取成交计算进度 |
| | | def __get_deal_compute_progress(code): |
| | | val = __get_redis().get(f"deal_compute_info-{code}") |
| | |
| | | cancel_data = __get_cancel_data(code, data, local_today_num_operate_map) |
| | | if cancel_data is None: |
| | | deal_num += val["num"] |
| | | __save_traded_index(code, data["index"]) |
| | | __set_deal_compute_progress(code, progress, deal_num) |
| | | |
| | | |
| | |
| | | |
| | | def __get_score(zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time, |
| | | deal_big_money): |
| | | score = 0 |
| | | score_list = [] |
| | | # 开盘前竞价 |
| | | if bidding: |
| | | score += 25 |
| | | score_list.append(25) |
| | | else: |
| | | score_list.append(0) |
| | | # 大单成交 |
| | | if deal_big_money: |
| | | score += 30 |
| | | score_list.append(30) |
| | | else: |
| | | score_list.append(0) |
| | | # 量 |
| | | volume_score = [0, 40, 50, 40, 30, 10, -150, -1000] |
| | | volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399] |
| | | for i in range(1, len(volume_rates)): |
| | | if volume_rates[i - 1] <= volume_rate < volume_rates[i]: |
| | | score += volume_score[i - 1] |
| | | score_list.append(volume_score[i - 1]) |
| | | break |
| | | |
| | | # 15个交易日是否涨幅24.9% |
| | | if k_form[0]: |
| | | score += -100 |
| | | score_list.append(-100) |
| | | else: |
| | | score_list.append(0) |
| | | # 是否破前高 |
| | | if k_form[1]: |
| | | score += 50 |
| | | score_list.append(50) |
| | | else: |
| | | score_list.append(0) |
| | | # 是否超跌 |
| | | if k_form[2]: |
| | | score += 40 |
| | | score_list.append(40) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | # 是否接近前高 |
| | | if k_form[3]: |
| | | score += -50 |
| | | score_list.append(-50) |
| | | else: |
| | | score_list.append(0) |
| | | # 是否N |
| | | if k_form[4]: |
| | | score += 35 |
| | | score_list.append(35) |
| | | else: |
| | | score_list.append(0) |
| | | # 是否V |
| | | if k_form[5]: |
| | | score += 30 |
| | | score_list.append(30) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | if not code_nature[0]: |
| | | score += 5 |
| | | score_list.append(5) |
| | | else: |
| | | score_list.append(0) |
| | | if code_nature[1]: |
| | | score += 20 |
| | | score_list.append(20) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | if hot_block[0] >= 2: |
| | | score += 40 |
| | | score_list.append(40) |
| | | else: |
| | | score += 30 |
| | | score_list.append(30) |
| | | if hot_block[1] > 0: |
| | | score += 10 |
| | | score_list.append(10) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | if zyltgb: |
| | | score += -80 |
| | | score_list.append(-80) |
| | | zyltgbs = [0, 10, 31, 51, 101, 150, 250, 1000000] |
| | | zyltgb_score = [5, 25, 20, 15, 10, 5, -80] |
| | | for i in range(1, len(zyltgbs)): |
| | | if zyltgbs[i - 1] <= zyltgb / 100000000 < zyltgbs[i]: |
| | | score_list.append(zyltgb_score[i - 1]) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | if limit_price: |
| | | score += -1000 |
| | | score_list.append(-1000) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | # 开盘前竞价 |
| | | if bidding: |
| | | score_list.append(25) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | k_score = [] |
| | | # 15个交易日是否涨幅24.9% |
| | | if k_form[0]: |
| | | k_score.append(-25) |
| | | else: |
| | | k_score.append(0) |
| | | # 是否破前高 |
| | | |
| | | if k_form[1]: |
| | | k_score.append(50) |
| | | else: |
| | | k_score.append(0) |
| | | # 是否超跌 |
| | | if k_form[2]: |
| | | k_score.append(40) |
| | | else: |
| | | k_score.append(0) |
| | | |
| | | # 是否接近前高 |
| | | if k_form[3]: |
| | | k_score.append(-25) |
| | | else: |
| | | k_score.append(0) |
| | | # 是否N |
| | | if k_form[4]: |
| | | k_score.append(35) |
| | | else: |
| | | k_score.append(0) |
| | | # 是否V |
| | | if k_form[5]: |
| | | k_score.append(30) |
| | | else: |
| | | k_score.append(0) |
| | | score_list.append(k_score) |
| | | |
| | | nature_score = [] |
| | | |
| | | if code_nature is None: |
| | | code_nature = [True, False] |
| | | |
| | | if not code_nature[0]: |
| | | nature_score.append(5) |
| | | else: |
| | | nature_score.append(0) |
| | | if code_nature[1]: |
| | | nature_score.append(20) |
| | | else: |
| | | nature_score.append(0) |
| | | |
| | | score_list.append(nature_score) |
| | | |
| | | hot_block_score = [] |
| | | |
| | | if hot_block[1] >= 2: |
| | | hot_block_score.append(40) |
| | | else: |
| | | hot_block_score.append(30) |
| | | if hot_block[2] > 0: |
| | | hot_block_score.append(10) |
| | | else: |
| | | hot_block_score.append(0) |
| | | score_list.append(hot_block_score) |
| | | |
| | | # 量 |
| | | volume_score = [0, 40, 50, 40, 30, 10, -15, -35] |
| | | volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399] |
| | | volume_add = False |
| | | for i in range(1, len(volume_rates)): |
| | | if volume_rates[i - 1] <= volume_rate < volume_rates[i]: |
| | | score_list.append(volume_score[i - 1]) |
| | | volume_add = True |
| | | break |
| | | if not volume_add: |
| | | score_list.append(volume_score[-1]) |
| | | |
| | | if limit_up_time: |
| | | score += 20 |
| | | score_list.append(20) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | # 大单成交 |
| | | if deal_big_money: |
| | | score_list.append(30) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | score = 0 |
| | | for s in score_list: |
| | | if type(s) == list: |
| | | for ss in s: |
| | | score += ss |
| | | else: |
| | | score += s |
| | | return score, score_list |
| | | |
| | | |
| | | def get_score(code, volume_rate, limit_up_time): |
| | | bidding_money = bidding_money_manager.get_bidding_money(code) |
| | | bidding = False |
| | | if bidding_money and bidding_money >= 5000: |
| | | bidding = True |
| | | def get_score(code, volume_rate, limit_up_time, with_source_data=False): |
| | | source_datas = [] |
| | | |
| | | # 获取自由流通股本 |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb is None: |
| | | global_data_loader.load_zyltgb() |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb is None: |
| | | zyltgb = 100 * 100000000 |
| | | source_datas.append(zyltgb) |
| | | |
| | | limit_price = float(gpcode_manager.get_limit_up_price(code)) |
| | | source_datas.append(limit_price) |
| | | |
| | | # 竞价金额 |
| | | bidding_money = bidding_money_manager.get_bidding_money(code) |
| | | source_datas.append(bidding_money) |
| | | bidding = False |
| | | if bidding_money and bidding_money >= 5000: |
| | | bidding = True |
| | | |
| | | k_form = code_nature_analyse.CodeNatureRecordManager.get_k_format(code) |
| | | if k_form is None: |
| | | k_form = [True, False, False, False, False, False] |
| | | k_form = [(True, ''), (False, ''), (False, ''), (False, ''), (False, ''), (False, '')] |
| | | source_datas.append(k_form) |
| | | |
| | | code_nature = code_nature_analyse.CodeNatureRecordManager.get_nature(code) |
| | | source_datas.append(code_nature) |
| | | |
| | | hot_block = hot_block_data_process.get_info(code) |
| | | if hot_block is None: |
| | | hot_block = (1, 0) |
| | | hot_block = ('无板块', 1, 0) |
| | | else: |
| | | # 加上自己 |
| | | hot_block = (hot_block[0] + 1, hot_block[1]) |
| | | hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2]) |
| | | |
| | | source_datas.append(hot_block) |
| | | |
| | | source_datas.append(volume_rate) |
| | | |
| | | source_datas.append(limit_up_time) |
| | | if limit_up_time and tool.trade_time_sub(limit_up_time, "10:00:00") < 0: |
| | | limit_up_time = True |
| | | else: |
| | | limit_up_time = False |
| | | |
| | | # 获取成交大单 |
| | | deal_big_num = deal_big_money_manager.get_deal_big_money_num(code) |
| | | m = l2_trade_factor.L2TradeFactorUtil.get_base_safe_val(zyltgb) |
| | | limit_price = float(gpcode_manager.get_limit_up_price(code)) |
| | | source_datas.append((deal_big_num * limit_price * 100, m)) |
| | | |
| | | if deal_big_num * limit_price * 100 > m: |
| | | deal_big_num = True |
| | | else: |
| | | deal_big_num = False |
| | | |
| | | return __get_score(zyltgb >= 250 * 100000000, limit_price > 100, bidding, k_form, code_nature, hot_block, |
| | | volume_rate, limit_up_time, deal_big_num) |
| | | k_form_1 = [] |
| | | for d in k_form: |
| | | k_form_1.append(d[0]) |
| | | |
| | | result = __get_score(zyltgb, limit_price > 100, bidding, k_form_1, code_nature, hot_block, |
| | | volume_rate, limit_up_time, deal_big_num) |
| | | if with_source_data: |
| | | return result, source_datas |
| | | return result |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | global_data_loader.load_zyltgb() |
| | | score = get_score("601698", 1.2, "15:00:01") |
| | | score = get_score("000779", 1.2, "15:00:01", True) |
| | | print(score) |
| | |
| | | |
| | | # 下单参数 |
| | | class L2PlaceOrderParamsManager: |
| | | |
| | | # 得分 |
| | | def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score): |
| | | self.code = code |
| | | self.is_first_code = is_first_code |
| | | score_ranks = [200, 190, 180, 100] |
| | | self.score = score[0] |
| | | # 为分数设置等级 |
| | | score_index = -1 |
| | | for i in range(0, len(score_ranks)): |
| | | if self.score >= score_ranks[i]: |
| | | score_index = i |
| | | break |
| | | self.score_index = score_index |
| | | self.volume_rate = volume_rate |
| | | self.volume_rate_index = volume_rate_index |
| | | |
| | | # 获取信号连续买笔数 |
| | | @staticmethod |
| | | def get_begin_continue_buy_count(volume_rate_index): |
| | | |
| | | def get_begin_continue_buy_count(self): |
| | | counts = [3, 3, 3, 2, 2, 2, 2] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取时间计算范围,返回s |
| | | @staticmethod |
| | | def get_time_range(volume_rate_index): |
| | | def get_time_range(self): |
| | | ts = [pow(3, 1), pow(3, 1), pow(3, 1), pow(3, 2), pow(3, 2), pow(3, 3), pow(3, 3), pow(3, 3)] |
| | | if volume_rate_index >= len(ts): |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(ts): |
| | | volume_rate_index = -1 |
| | | return ts[volume_rate_index] |
| | | |
| | | # 获取需要的大单个数 |
| | | @staticmethod |
| | | def get_big_num_count(volume_rate_index): |
| | | def get_big_num_count(self): |
| | | if self.is_first_code: |
| | | if self.score_index == 0: |
| | | return 0 |
| | | elif self.score_index == 1: |
| | | return 0 |
| | | elif self.score_index == 2: |
| | | return 1 |
| | | elif self.score_index < 0: |
| | | return 65535 |
| | | counts = [3, 1, 1, 1, 0, 0, 0, 0] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取安全笔数影响比例 |
| | | @staticmethod |
| | | def get_safe_count_rate(volume_rate_index): |
| | | def get_safe_count_rate(self): |
| | | rates = [0, -0.1, -0.2, -0.4, -0.6, -0.8, -0.8, -0.8] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | def get_safe_count(self): |
| | | if self.is_first_code: |
| | | if 3 > self.score_index > -1: |
| | | return 0 |
| | | elif self.score_index < 0: |
| | | return 65535 |
| | | base_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(self.code, True) |
| | | rate = self.get_safe_count_rate() |
| | | count = int(round(base_count * (1 + rate))) |
| | | return count |
| | | |
| | | # 获取m值影响比例 |
| | | @staticmethod |
| | | def get_m_val_rate(volume_rate_index): |
| | | @classmethod |
| | | def get_m_val_rate(cls, volume_rate_index): |
| | | rates = [0.0, 0.0, 0.0, -0.3, -0.4, -0.5, -0.6, -0.7] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | # 获取m值 |
| | | def get_m_val(self): |
| | | if self.is_first_code: |
| | | if self.score_index == 0: |
| | | return 0, "" |
| | | elif self.score_index == 1: |
| | | return 1000 * 10000, "" |
| | | elif self.score_index == 2: |
| | | return 1000 * 10000, "" |
| | | elif self.score_index < 0: |
| | | return 65535 * 10000, "" |
| | | # 获取固定m值 |
| | | zyltgb = global_util.zyltgb_map.get(self.code) |
| | | if zyltgb is None: |
| | | global_data_loader.load_zyltgb() |
| | | zyltgb = global_util.zyltgb_map.get(self.code) |
| | | |
| | | base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb) |
| | | rate = self.get_m_val_rate(self.volume_rate_index) |
| | | m = round(base_m * (1 + rate)) |
| | | return m, "" |
| | | |
| | | |
| | | # S撤参数 |
| | |
| | | # 获取基础m值,返回单位为元 |
| | | @classmethod |
| | | def get_base_safe_val(cls, zyltgb): |
| | | if zyltgb is None: |
| | | return 10000000 |
| | | yi = round(zyltgb / 100000000) |
| | | if yi < 1: |
| | | yi = 1 |
| | | m = 5000000 + (yi - 1) * 500000 |
| | | return round(m*(1-0.3)) |
| | | return round(m * (1 - 0.3)) |
| | | |
| | | # 获取行业影响比例 |
| | | # total_limit_percent为统计的比例之和乘以100 |
| | |
| | | if today is None: |
| | | return 0 |
| | | old_volumn = int(yest) |
| | | if int(day60_max) > int(yest): |
| | | old_volumn = int(day60_max) |
| | | if int(day60_max[0]) > int(yest): |
| | | old_volumn = int(day60_max[0]) |
| | | r = round(int(today) / old_volumn, 2) |
| | | if r < 0.01: |
| | | r = 0.01 |
| | |
| | | MAX_VAL = 13 |
| | | if not gb: |
| | | # 默认8笔 |
| | | return MIN_VAL |
| | | return MIN_VAL,MIN_VAL, MAX_VAL |
| | | count = gb // 100000000 |
| | | if True: |
| | | if count < 8: |
| | |
| | | main_hwnds = [] |
| | | win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList) |
| | | for hwnd in hWndList: |
| | | if THSGuiUtil.getText(hwnd) == "专业版下单": |
| | | if win32gui.IsWindowVisible(hwnd) and THSGuiUtil.getText(hwnd) == "专业版下单": |
| | | main_hwnds.append(hwnd) |
| | | if not main_hwnds: |
| | | raise Exception("专业版下单未打开") |