| | |
| | | import win32gui |
| | | |
| | | import constant |
| | | import juejin_data_export |
| | | import ocr_util |
| | | import opencv_util |
| | | import setting |
| | | import socket_util |
| | | import ths_util |
| | | import win32_util |
| | | |
| | |
| | | elif result == wx.ID_NO: |
| | | callback(False) |
| | | toastone.Destroy() |
| | | |
| | | |
| | | # 掘金分时下载 |
| | | class JueJinTickDataDownloadFrame(wx.Frame): |
| | | def __init__(self): |
| | | wx.Frame.__init__(self, None, -1, "掘金分时数据下载", style=wx.SYSTEM_MENU ^ wx.CLOSE_BOX ^ wx.CAPTION ^ wx.STAY_ON_TOP, |
| | | size=(350, 250)) |
| | | |
| | | self.SetBackgroundColour(wx.Colour(224, 224, 224)) |
| | | boxsier = wx.BoxSizer() |
| | | flex = wx.FlexGridSizer(rows=4, cols=2, vgap=10, hgap=10) |
| | | # 策略 |
| | | label = wx.StaticText(self, label="代码:") |
| | | flex.Add(label, flag=wx.ALIGN_RIGHT) |
| | | self.edit_code = wx.TextCtrl(self, size=(100, -1)) |
| | | flex.Add(self.edit_code) |
| | | |
| | | # 目录 |
| | | label = wx.StaticText(self, label="目录选择:") |
| | | flex.Add(label) |
| | | |
| | | bs1 = wx.BoxSizer(wx.VERTICAL) |
| | | self.btn_dir = wx.Button(self, label="选择目录") |
| | | bs1.Add(self.btn_dir) |
| | | self.label_path = wx.StaticText(self, label="") |
| | | bs1.Add(self.label_path) |
| | | flex.Add(bs1) |
| | | |
| | | label = wx.StaticText(self, label="时间选择:") |
| | | flex.Add(label) |
| | | self.edit_start_time = wx.TextCtrl(self, size=(100, -1)) |
| | | self.edit_end_time = wx.TextCtrl(self, size=(100, -1)) |
| | | bs1 = wx.BoxSizer(wx.HORIZONTAL) |
| | | bs1.Add(self.edit_start_time, 1, wx.RIGHT, 10) |
| | | label = wx.StaticText(self, label="-") |
| | | bs1.Add(label) |
| | | bs1.Add(self.edit_end_time, 1, wx.LEFT, 10) |
| | | flex.Add(bs1) |
| | | |
| | | # 占位 |
| | | flex.Add(wx.StaticText(self, label="")) |
| | | # 确定按钮 |
| | | ID_SURE = wx.NewId() |
| | | self.btn_sure = wx.Button(self, label='确定', id=ID_SURE) |
| | | self.btn_sure.Bind(wx.EVT_BUTTON, self.__sure_btn) |
| | | self.btn_dir.Bind(wx.EVT_BUTTON, self.__choose_dir) |
| | | flex.Add(self.btn_sure, 1, wx.TOP | wx.LEFT, 20) |
| | | |
| | | boxsier.Add(flex, 1, wx.TOP | wx.LEFT, 20) |
| | | self.SetSizer(boxsier) |
| | | |
| | | # 赋初值 |
| | | self.edit_start_time.SetValue("09:30:00") |
| | | self.edit_end_time.SetValue("10:00:00") |
| | | |
| | | def __choose_dir(self, event): |
| | | dialog = wx.DirDialog(None, "选择保存目录:") |
| | | if dialog.ShowModal() == wx.ID_OK: |
| | | path = dialog.GetPath() |
| | | self.label_path.SetLabel(path) |
| | | dialog.Destroy() |
| | | |
| | | def __sure_btn(self, event): |
| | | code = self.edit_code.GetValue() |
| | | start_time = self.edit_start_time.GetValue() |
| | | end_time = self.edit_end_time.GetValue() |
| | | dir_path = self.label_path.GetLabel() |
| | | if code and start_time and end_time and dir_path: |
| | | juejin_data_export.export_tick_data(code, start_time, end_time, dir_path) |
| | | show_info("导出成功", None) |
| | | else: |
| | | show_warning("参数不完整", None) |
| | | |
| | | |
| | | class JueJinSettingFrame(wx.Frame): |
| | |
| | | self.Hide() |
| | | |
| | | |
| | | class SocketApiUtil: |
| | | |
| | | @classmethod |
| | | def __request(cls, data_json): |
| | | socket_util.encryp_client_params_sign(data_json) |
| | | client = socket.socket() # 生成socket,连接server |
| | | ip_port = (constant.SERVER_HOST, 10009) # server地址和端口号(最好是10000以后) |
| | | client.connect(ip_port) |
| | | client.send(socket_util.load_header(json.dumps(data_json).encode("utf-8"))) |
| | | result_str, header = socket_util.recv_data(client) |
| | | return result_str |
| | | |
| | | @classmethod |
| | | def get_cost_price(cls, code): |
| | | result_str = cls.__request({"type": "get_cost_price", "data": {"code": code}}) |
| | | print(result_str) |
| | | result = json.loads(result_str) |
| | | if result['code'] == 0: |
| | | return result['data']['price'] |
| | | raise Exception(result['msg']) |
| | | |
| | | |
| | | class TickFrame(wx.Frame): |
| | | def __init__(self): |
| | | '''构造函数''' |
| | |
| | | self.Size = wx.Size(win_info[2], win_info[3]) |
| | | else: |
| | | self.Center() |
| | | |
| | | # 拉取数据线程 |
| | | self.cost_price_threads = {} |
| | | |
| | | # 以下代码处理图标 |
| | | # if hasattr(sys, "frozen") and getattr(sys, "frozen") == "windows_exe": |
| | |
| | | self.timer = wx.Timer(self) # 创建定时器 |
| | | self.Bind(wx.EVT_TIMER, self.post_redraw, self.timer) # 绑定一个定时器事件 |
| | | self.last_size = (self.Size[0], self.Size[1]) |
| | | |
| | | |
| | | |
| | | # self.scroll.Layout() |
| | | # self.boxsier.Fit(self.scroll) |
| | |
| | | pannel.BackgroundColour = wx.Colour(0, 0, 0) |
| | | self.panels.append(pannel) |
| | | self.boxsier.Add(pannel) |
| | | axes = self.__create_canvas(pannel, "{}({})".format(codes_name[i][0], codes_name[i][1]), codes_name[i][1], |
| | | code = codes_name[i][0] |
| | | axes = self.__create_canvas(pannel, code, "{}({})".format(codes_name[i][0], codes_name[i][1]), |
| | | codes_name[i][1], |
| | | codes_name[i][2]) |
| | | if code not in self.cost_price_threads: |
| | | t1 = self.run_get_cost_price(codes_name[i][0]) |
| | | self.cost_price_threads[code] = t1 |
| | | axes_list.append(axes) |
| | | |
| | | self.scroll.Layout() |
| | |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | |
| | | def __create_canvas(self, pannel, title, name, price, close_callback=None): |
| | | def __create_canvas(self, pannel, code, title, name, price, close_callback=None): |
| | | def show_mouse_line(event): |
| | | # 删除之前的线 |
| | | if title in self.mark_lines: |
| | |
| | | |
| | | # axes_score.plot(t_score, s_score, 'ro', t_score, s_score, 'k') |
| | | axes.set_title(title) |
| | | axes.grid(color='firebrick', ls='-', lw=0.5) |
| | | axes.grid(False) |
| | | axes.set_xlabel(f'时间({name})') |
| | | axes.dist = 0 |
| | | |
| | |
| | | |
| | | axes2 = axes.twinx() |
| | | # axes2.grid(color='firebrick', ls='-', lw=0.5) |
| | | # axes2.grid(color='firebrick', ls='-', lw=0.5) |
| | | axes2.grid(False) |
| | | axes2.grid(color='firebrick', ls='-', lw=0.5) |
| | | # 鼠标在画布移动 |
| | | axes2.figure.canvas.mpl_connect('motion_notify_event', show_mouse_line) |
| | | # 鼠标离开画布 |
| | |
| | | limit_up_price = float(tool.get_limit_up_price(price)) |
| | | max_rate = round((limit_up_price - price) / price, 4) * 100 |
| | | print("涨停最大比例", max_rate) |
| | | yticks2 = [] |
| | | for i in range(0, 41): |
| | | if i >= 20: |
| | | yticks2.append(0 - round(max_rate * (20 - i) / 20, 4)) |
| | | else: |
| | | yticks2.append(round(max_rate * (i - 20) / 20, 4)) |
| | | yticks2_labels = [] |
| | | yticks = [] |
| | | yticks_labels = [] |
| | | for i in range(0, len(yticks2)): |
| | | if i % 2 == 0: |
| | | yticks2_labels.append("{}%".format(abs(round(yticks2[i], 2)))) |
| | | else: |
| | | yticks2_labels.append("") |
| | | price_ = round((1 + yticks2[i] / 100) * price, 2) |
| | | yticks.append(price_) |
| | | if i % 2 == 0: |
| | | yticks_labels.append("") |
| | | # yticks_labels.append(round(yticks[i], 2)) |
| | | if i == 20: |
| | | axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=2) |
| | | else: |
| | | axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=1.2) |
| | | else: |
| | | # axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=0.5) |
| | | yticks_labels.append("") |
| | | # 加粗中轴线 |
| | | # 设置纵坐标信息 |
| | | # max_rate = 2 |
| | | DrawManager.set_y_info(code, max_rate, axes, axes2, price) |
| | | |
| | | axes2.set_ylabel(u'') |
| | | # 设置纵轴的值的范围 |
| | | axes2.set_ylim(0 - max_rate * (1), max_rate * (1)) |
| | | axes2.set_yticks(yticks2) |
| | | axes2.set_yticklabels(yticks2_labels) |
| | | axes.set_yticks(yticks) |
| | | axes.set_yticklabels(yticks_labels) |
| | | # 设置纵坐标数值颜色 |
| | | for i in range(0, 19): |
| | | axes.get_yticklabels()[i].set_color("green") |
| | | axes2.get_yticklabels()[i].set_color("green") |
| | | for i in range(20, 20): |
| | | axes.get_yticklabels()[i].set_color("white") |
| | | axes2.get_yticklabels()[i].set_color("white") |
| | | for i in range(21, 41): |
| | | axes.get_yticklabels()[i].set_color("red") |
| | | axes2.get_yticklabels()[i].set_color("red") |
| | | line = axes2.plot([], [], color='white', linewidth=1) |
| | | average_line = axes2.plot([], [], color='green', linewidth=1, linestyle='-') |
| | | average_line = axes2.plot([], [], color='yellow', linewidth=1, linestyle='-') |
| | | average_line_1m = axes2.plot([], [], color='yellow', linewidth=1, linestyle='-') |
| | | # axes2.legend(loc='upper left') |
| | | cannvas = FigureCanvas(pannel, -1, figure_score) |
| | | axes2.text(1, 11.5, r'现价:0.0 涨幅:0.00% \n留格局:0%', fontsize=10, color='white') |
| | | axes2.text(-1, -11.5, r'现价:0.0 涨幅:0.00% \n留格局:0%', fontsize=10, color='white') |
| | | axes2.text(1, 11.5, r'现价:0.0 涨幅:0.00% \n留:0%', fontsize=10, color='white') |
| | | axes2.text(-1, -11.5, r'现价:0.0 涨幅:0.00% \n留:0%', fontsize=10, color='white') |
| | | |
| | | axes2.spines['top'].set_visible(False) |
| | | axes.spines['top'].set_visible(False) |
| | | axes2.spines['bottom'].set_visible(False) |
| | | axes2.spines['bottom'].set_visible(True) |
| | | axes.spines['bottom'].set_visible(False) |
| | | return (axes2, line, average_line_1m, average_line) |
| | | |
| | | # 中轴线加粗 |
| | | hline = axes2.axhline(0, linestyle='-', color='firebrick', lw=2) |
| | | |
| | | # 设置坐标轴标记点为黑色 |
| | | axes.tick_params(axis='x', colors='black') |
| | | axes.tick_params(axis='y', colors='black') |
| | | axes2.tick_params(axis='x', colors='black') |
| | | axes2.tick_params(axis='y', colors='black') |
| | | |
| | | return (axes2, line, average_line_1m, average_line, axes) |
| | | |
| | | def __show_top(self, event): |
| | | if event.Selection: |
| | |
| | | time.sleep(0.1) |
| | | self.Size = wx.Size(self.Size[0], self.Size[1] - 10) |
| | | |
| | | def run_get_cost_price(self, code): |
| | | def request(code): |
| | | while True: |
| | | try: |
| | | price = SocketApiUtil.get_cost_price(code) |
| | | pre_price = juejin_core.GPCodeManager().get_pre_prices(code) |
| | | rate = round((price - pre_price) * 100 / pre_price, 2) |
| | | DrawManager.set_cost_rate(code, rate) |
| | | # wx.CallAfter(lambda :) |
| | | except Exception as e: |
| | | DrawManager.set_cost_rate(code, None) |
| | | # wx.CallAfter(lambda: str(e)) |
| | | except: |
| | | pass |
| | | finally: |
| | | time.sleep(3) |
| | | |
| | | t1 = threading.Thread(target=lambda: request(code), daemon=True) |
| | | t1.start() |
| | | return t1 |
| | | |
| | | |
| | | # 绘图管理器 |
| | | class DrawManager: |
| | | X_RANGE_MINIUTES = 60 |
| | | X_DATA_MINIUTES = 56 |
| | | |
| | | h_lines_dict = {} |
| | | cost_mark_dict = {} |
| | | last_max_rate_dict = {} |
| | | cost_rate_dict = {} |
| | | |
| | | @classmethod |
| | | def set_cost_rate(cls, code, rate): |
| | | cls.cost_rate_dict[code] = rate |
| | | |
| | | def __load_lack_datas(self, code, time_ranges): |
| | | codeDataManager = code_data_manager.CodeDataManager() |
| | |
| | | for data in results: |
| | | datas.append(juejin_core.parse_tick(data)) |
| | | # 保存数据 |
| | | |
| | | last_time = time_range[0] |
| | | for data in datas: |
| | | # 09:25:00之前的数据不保存 |
| | | created_at = data["created_at"].strftime("%Y-%m-%d %H:%M:%S") |
| | |
| | | # 不是今天的数据不保存 |
| | | if day != created_at[:10]: |
| | | continue |
| | | # 每隔15s保存一次 |
| | | if last_time and tool.trade_time_sub(created_at[-8:], last_time) >= 15: |
| | | last_time = created_at[-8:] |
| | | codeDataManager.save_data(data) |
| | | |
| | | def init_code_datas(self): |
| | |
| | | min_time = tool.trade_time_add_second(min_time, 0 - DrawManager.X_DATA_MINIUTES * 60) |
| | | |
| | | ranges = codeDataManager.get_lack_datas_time_range(old_datas, min_time) |
| | | if len(ranges) > 0: |
| | | self.__load_lack_datas(code, ranges) |
| | | old_datas = codeDataManager.get_datas(code) |
| | | |
| | | # TODO 测试注释 |
| | | # if len(ranges) > 0: |
| | | # self.__load_lack_datas(code, ranges) |
| | | # old_datas = codeDataManager.get_datas(code) |
| | | old_datas = [] |
| | | if old_datas: |
| | | code_datas[code].extend(old_datas) |
| | | # self.update(code, code_datas[code]) |
| | | wx.CallAfter(self.update, code, code_datas[code]) |
| | | |
| | | @classmethod |
| | | def __format_max_rate(cls, max_rate): |
| | | line_count = 0 |
| | | if max_rate % 0.6 < 0.0001: |
| | | line_count = int(round(max_rate // 0.6)) |
| | | else: |
| | | line_count = int(round(max_rate // 0.6)) + 1 |
| | | return line_count * 0.6, 0.6 |
| | | |
| | | @classmethod |
| | | def set_y_info(cls, code, max_rate, axes, axes2, price): |
| | | # 设置y轴数据 |
| | | max_rate, amplitude = cls.__format_max_rate(max_rate) |
| | | line_count = int(round(max_rate / amplitude)) |
| | | print("line_count", line_count) |
| | | yticks2 = [] |
| | | for i in range(0, line_count * 2 + 1): |
| | | if i >= line_count: |
| | | yticks2.append(0 - round(max_rate * (line_count - i) / line_count, 4)) |
| | | else: |
| | | yticks2.append(round(max_rate * (i - line_count) / line_count, 4)) |
| | | yticks2_labels = [] |
| | | yticks = [] |
| | | yticks_labels = [] |
| | | if code not in cls.h_lines_dict: |
| | | cls.h_lines_dict[code] = [] |
| | | |
| | | for line in cls.h_lines_dict[code]: |
| | | line.remove() |
| | | cls.h_lines_dict[code].clear() |
| | | |
| | | for i in range(0, len(yticks2)): |
| | | # if i % 2 == 0: |
| | | yticks2_labels.append("{}%".format(abs(round(yticks2[i], 2)))) |
| | | # else: |
| | | # yticks2_labels.append("") |
| | | price_ = round((1 + yticks2[i] / 100) * price, 2) |
| | | yticks.append(price_) |
| | | if i % 2 == 0 and False: |
| | | yticks_labels.append("") |
| | | # yticks_labels.append(round(yticks[i], 2)) |
| | | if i == line_count: |
| | | hline = axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=2) |
| | | cls.h_lines_dict[code].append(hline) |
| | | else: |
| | | # hline = axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=1.2) |
| | | # cls.h_lines_dict[code].append(hline) |
| | | pass |
| | | else: |
| | | # axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=0.5) |
| | | yticks_labels.append("") |
| | | axes2.set_ylabel(u'') |
| | | # 设置纵轴的值的范围 |
| | | axes2.set_ylim(0 - max_rate * (1), max_rate * (1)) |
| | | axes.set_ylim((100 - max_rate) * price / 100, (100 + max_rate) * price / 100) |
| | | axes2.set_yticks(yticks2) |
| | | axes2.set_yticklabels(yticks2_labels) |
| | | axes.set_yticks(yticks) |
| | | axes.set_yticklabels(yticks_labels) |
| | | # axes.axhline(0, color='firebrick', linewidth=2) |
| | | |
| | | # 设置纵坐标数值颜色 |
| | | for i in range(0, line_count): |
| | | axes.get_yticklabels()[i].set_color("green") |
| | | axes2.get_yticklabels()[i].set_color("green") |
| | | for i in range(line_count, line_count): |
| | | axes.get_yticklabels()[i].set_color("white") |
| | | axes2.get_yticklabels()[i].set_color("white") |
| | | for i in range(line_count + 1, line_count * 2 + 1): |
| | | axes.get_yticklabels()[i].set_color("red") |
| | | axes2.get_yticklabels()[i].set_color("red") |
| | | |
| | | @classmethod |
| | | def mark_code_info(cls, code, max_rate, axes2, cost_rate): |
| | | ## 标记代码相关的信息 |
| | | # 设置成本线 |
| | | if code in cls.cost_mark_dict: |
| | | cls.cost_mark_dict[code].remove() |
| | | if cost_rate is None: |
| | | return |
| | | mark_x = axes2.get_xlim() |
| | | mark_y = axes2.get_ylim() |
| | | if cost_rate > max_rate: |
| | | scatter_cost = axes2.scatter((mark_x[0] + mark_x[1]) // 2, mark_y[1] - mark_y[1] / 25, c='#159EEC', |
| | | marker='^', s=50) |
| | | cls.cost_mark_dict[code] = scatter_cost |
| | | elif cost_rate < 0 and abs(cost_rate) > max_rate: |
| | | scatter_cost = axes2.scatter((mark_x[0] + mark_x[1]) // 2, 0 - mark_y[1] + mark_y[1] / 25, c='#159EEC', |
| | | marker='v', s=50) |
| | | cls.cost_mark_dict[code] = scatter_cost |
| | | else: |
| | | line1 = axes2.axhline(cost_rate, linestyle='--', color='#FF8020', lw=1) |
| | | cls.cost_mark_dict[code] = line1 |
| | | |
| | | # 更新数据 |
| | | def __update_data(self, code, axes, datas, min_rate, max_rate): |
| | | def __update_data(self, code, axes, datas, pre_price, y_max_rate=10.5, cost_rate=None): |
| | | def get_time_as_seconds(created_at): |
| | | time_ = created_at[-8:] |
| | | if tool.get_time_as_second("13:00:00") > tool.get_time_as_second(time_) > tool.get_time_as_second( |
| | |
| | | s = seconds % 60 |
| | | return "{0:0>2}:{1:0>2}:{2:0>2}".format(h, m, s) |
| | | |
| | | y_max_rate, a = self.__format_max_rate(y_max_rate) |
| | | if code not in self.last_max_rate_dict or self.last_max_rate_dict[code] < y_max_rate: |
| | | self.last_max_rate_dict[code] = y_max_rate |
| | | # 设置纵坐标的信息 |
| | | self.set_y_info(code, y_max_rate, axes[4], axes[0], pre_price) |
| | | # 标记代码相关的信息 |
| | | self.mark_code_info(code, self.last_max_rate_dict[code], axes[0], cost_rate) |
| | | |
| | | # 删除9:30以前的数据 |
| | | for i in range(0, len(datas)): |
| | | time_ = datas[i]["created_at"][-8:] |
| | |
| | | for data in datas: |
| | | xs.append(get_time_as_seconds(data["created_at"])) |
| | | ys_rate.append(data["rate"] * 100) |
| | | |
| | | ys_average_rate_1m.append(data["average_rate"] * 100 + 1.5) |
| | | ys_average_rate.append(data["average_rate"] * 100) |
| | | |
| | |
| | | axes[0].set_xticklabels(xticklabels) |
| | | |
| | | axes[1][0].set_data(xs, ys_rate) |
| | | axes[2][0].set_data(xs, ys_average_rate_1m) |
| | | # 不需要一分钟均线 |
| | | # axes[2][0].set_data(xs, ys_average_rate_1m) |
| | | if axes[3]: |
| | | axes[3][0].set_data(xs, ys_average_rate) |
| | | texts = axes[0].texts |
| | | texts[0].set_text("{}% \n留格局:0%".format(round(datas[-1]["rate"] * 100, 2))) |
| | | texts[0].set_text("{}% \n留:{}".format(round(datas[-1]["rate"] * 100, 2), '无持仓' if self.cost_rate_dict.get( |
| | | code) is None else f"{self.cost_rate_dict.get(code)}%")) |
| | | texts[1].set_text("{}".format(datas[-1]["created_at"].split(" ")[1])) |
| | | texts[0].set_x(xms[1] - 80) |
| | | texts[0].set_y(yms[1] + 0.5) |
| | |
| | | line = self.lines[code][key] |
| | | line.remove() |
| | | self.lines.pop(code) |
| | | # 绘制最大最小坐标 |
| | | line_min = axes[0].axhline(min_rate, linestyle='--', color='yellow', lw=0.5) |
| | | line_max = axes[0].axhline(max_rate, linestyle='--', color='yellow', lw=0.5) |
| | | self.lines[code] = {"min": line_min, "max": line_max} |
| | | # 暂时不需要 绘制最大最小坐标 |
| | | # line_min = axes[0].axhline(min_rate, linestyle='--', color='yellow', lw=0.5) |
| | | # line_max = axes[0].axhline(max_rate, linestyle='--', color='yellow', lw=0.5) |
| | | # self.lines[code] = {"min": line_min, "max": line_max} |
| | | axes[0].figure.canvas.draw() |
| | | axes[0].figure.canvas.flush_events() |
| | | |
| | |
| | | |
| | | def update(self, code, datas): |
| | | __start_time = time.time() |
| | | # 获取前高和前低 |
| | | max_rate = None |
| | | min_rate = None |
| | | if code in max_min_prices: |
| | | pre_price = juejin_core.GPCodeManager().get_pre_prices(code) |
| | | min_rate = round((max_min_prices[code][0] - pre_price) / pre_price, 4) |
| | | max_rate = round((max_min_prices[code][1] - pre_price) / pre_price, 4) |
| | | |
| | | for data in datas: |
| | | rate = data["rate"] * 100 |
| | | created_at = data["created_at"][-8:] |
| | | if tool.get_time_as_second("15:00:00") >= tool.get_time_as_second(created_at) >= tool.get_time_as_second( |
| | | "09:30:00"): |
| | | if max_rate is None: |
| | | max_rate = rate |
| | | if min_rate is None: |
| | | min_rate = rate |
| | | if rate > max_rate: |
| | | max_rate = rate |
| | | if rate < min_rate: |
| | | min_rate = rate |
| | | |
| | | # 获取当前的坐标范围 |
| | | max_price = pre_price |
| | | for d in datas: |
| | | if abs(d['price'] - pre_price) > abs(max_price - pre_price): |
| | | max_price = d['price'] |
| | | y_max_rate = round(abs(max_price - pre_price) * 100 / pre_price, 2) |
| | | # 展示最近的600个 |
| | | datas = datas[0 - self.X_DATA_MINIUTES * 20:] |
| | | # 修正量数据 |
| | |
| | | for i in range(0, len(self.codes_info)): |
| | | if self.codes_info[i][0] == code: |
| | | try: |
| | | self.__update_data(code, self.axes_list[i], datas, min_rate, max_rate) |
| | | self.__update_data(code, self.axes_list[i], datas, pre_price, y_max_rate, |
| | | self.cost_rate_dict.get(code)) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | print("绘图花费时间:", time.time() - __start_time) |
| | | # print("绘图花费时间:", time.time() - __start_time) |
| | | |
| | | |
| | | class mainApp(wx.App): |
| | |
| | | self.floatFrame = FloatFrame() |
| | | global_datas["tickFrame"] = self.frame |
| | | global_datas["floatFrame"] = self.floatFrame |
| | | |
| | | # # 测试 |
| | | # global_datas["floatFrame"].Show() |
| | | |
| | |
| | | while True: |
| | | data = pipe.recv() |
| | | if data: |
| | | type = data["type"] |
| | | if type == 0: |
| | | _type = data["type"] |
| | | if _type == 0: |
| | | # tick数据 |
| | | data = data["data"] |
| | | code = data["code"] |
| | | try: |
| | | if code not in code_datas: |
| | | code_datas[code] = [] |
| | | except: |
| | | continue |
| | | create_time = data['created_at'].strftime("%H:%M:%S") |
| | | last_time = None |
| | | if code_datas[code]: |
| | | if type(code_datas[code][-1]["created_at"]) == str: |
| | | last_time = code_datas[code][-1]["created_at"].split(" ")[1] |
| | | else: |
| | | last_time = code_datas[code][-1]["created_at"].strftime("%H:%M:%S") |
| | | # 如果相差15s就添加进去 |
| | | if last_time is None or tool.trade_time_sub(create_time, last_time) >= 15: |
| | | code_datas[code].append(data) |
| | | codeDataManager.save_data(data) |
| | | else: |
| | | code_datas[code][-1]['rate'] = data['rate'] |
| | | code_datas[code][-1]['price'] = data['price'] |
| | | code_datas[code][-1]['average_price'] = data['average_price'] |
| | | code_datas[code][-1]['average_rate'] = data['average_rate'] |
| | | # 更新数据 |
| | | try: |
| | | drawManager.update(code, code_datas[code]) |
| | | print("接受到的tick数据:", data) |
| | | # print("接受到的tick数据:", data) |
| | | except: |
| | | pass |
| | | |
| | |
| | | # 后台运行 |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | elif type_ == "juejin_tick_download": |
| | | wx.CallAfter(lambda: JueJinTickDataDownloadFrame().Show()) |
| | | |
| | | |
| | | elif type_ == "exit": |
| | | try: |
| | |
| | | # app = mainApp() |
| | | # app.MainLoop() |
| | | # ocr_ths_code() |
| | | print(int(1.5)) |
| | | SocketApiUtil.get_cost_price("002207") |