Example #1
0
 def step_trdmax(self):
     """
     趋势转换判定的时间超跌超涨法
     :return:
     """
     flag = False
     if self.hlp_env.klist[
             self.
             cursor].hl == 'l' and self.trdnow != 'down':  # 当前待判定的是低点,当前趋势不是下跌
         pre_h = self.hlp_env.klist[self.cursor].hpi[-1]
         if self.cursor - pre_h >= constant.TREND_REV:  # 自前高超过一定时间还未出现低点
             interval = [
                 ii.low
                 for ii in self.hlp_env.klist[pre_h:(self.cursor + 1)]
             ]
             if self.cursor == interval.index(min(interval)) + pre_h:
                 self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                 self.trdnow = 'down'
                 self.trdchg.append(self.cursor)
                 self.hlp_env.klist[self.cursor].trd = 'down'
                 flag = True
                 self.cursor += 1
                 printt(
                     f"##`step_trdmax`,确认下跌趋势开启,位置{self.cursor-1};"
                     f"之前趋势:{self.hlp_env.klist[self.cursor-1].pre_trd};"
                     f"确认条件:超过{constant.TREND_REV}未出现低点",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
     elif self.hlp_env.klist[
             self.
             cursor].hl == 'h' and self.trdnow != 'up':  # 待判定高点,当前趋势非上涨
         pre_l = self.hlp_env.klist[self.cursor].lpi[-1]
         if self.cursor - pre_l >= constant.TREND_REV:
             interval = [
                 ii.high
                 for ii in self.hlp_env.klist[pre_l:(self.cursor + 1)]
             ]
             if self.cursor == interval.index(max(interval)) + pre_l:
                 self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                 self.trdnow = 'up'
                 self.trdchg.append(self.cursor)
                 self.hlp_env.klist[self.cursor].trd = 'up'
                 flag = True
                 self.cursor += 1
                 printt(
                     f"##`step_trdmax`,确认上涨趋势开启,位置{self.cursor-1};"
                     f"之前趋势:{self.hlp_env.klist[self.cursor-1].pre_trd};"
                     f"确认条件:超过{constant.TREND_REV}未出现高点",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
     return flag
Example #2
0
    def init_trd(self):
        if len(self.hlp_env.hpi) + len(self.hlp_env.lpi) < 4:
            raise TrendError(
                f"TrendError:{self.hlp_env.code}高低点个数不足,无法继续策略已被忽略")
        else:
            if self.hlp_env.hpi[0] > self.hlp_env.lpi[0]:  # 低点先出现
                if self.hlp_env.klist[self.hlp_env.lpi[
                        1]].low > self.hlp_env.klist[self.hlp_env.lpi[0]].low:
                    # 低点升高,推断为上升趋势,趋势开始时间为第二个低点被确认
                    self.cursor = self.hlp_env.klist[
                        self.hlp_env.lpi[1]].hl_confirmed
                    self.hlp_env.klist[self.cursor].trd = 'up'
                    self.trdchg.append(self.cursor)
                    self.trdnow = 'up'
                    printt(f"##`init_trd`,从l1-h1-l2(l2>l1)推断为上涨趋势",
                           msg_mode=constant.RunMode.REPORT,
                           global_mode=constant.RUN_MODE)
                else:
                    self.cursor = self.hlp_env.klist[
                        self.hlp_env.lpi[1]].hl_confirmed
                    self.hlp_env.klist[self.cursor].trd = 'consd'
                    self.trdchg.append(self.cursor)
                    self.trdnow = 'consd'
                    printt(f"##`init_trd`,从l1-h1-l2(l2<l1)推断为盘整趋势",
                           msg_mode=constant.RunMode.REPORT,
                           global_mode=constant.RUN_MODE)

            else:  # 高点先出现
                if self.hlp_env.klist[
                        self.hlp_env.hpi[1]].high < self.hlp_env.klist[
                            self.hlp_env.hpi[0]].high:  # 高点降低
                    self.cursor = self.hlp_env.klist[
                        self.hlp_env.hpi[1]].hl_confirmed
                    self.hlp_env.klist[self.cursor].trd = 'down'
                    self.trdchg.append(self.cursor)
                    self.trdnow = 'down'
                    printt(f"##`init_trd`,从h1-l1-h2(h2<h1)推断为下跌趋势",
                           msg_mode=constant.RunMode.REPORT,
                           global_mode=constant.RUN_MODE)
                else:  # 高点抬高
                    self.cursor = self.hlp_env.klist[
                        self.hlp_env.hpi[1]].hl_confirmed
                    self.hlp_env.klist[
                        self.cursor].trd = 'consd'  # 高-低-高(抬高)-->盘整
                    self.trdchg.append(self.cursor)  # 记录趋势改变(或首次出现能被判定的趋势类型时)
                    self.trdnow = 'consd'
                    printt(f"##`init_trd`,从h1-l1-h2(h2>h1)推断为盘整趋势",
                           msg_mode=constant.RunMode.REPORT,
                           global_mode=constant.RUN_MODE)
            self.cursor += 1
Example #3
0
 def buy_in_day(self, l_p, typ):
     """
     在日线级别上的买入操作需要满足以下条件
     / 1.30min级别买入失败
     / 2.日线低点被确认当日K收盘
     / 3.确认当日K的最高价距离被确认的低点上涨幅度低于阈值
     :param l_p: 最近被确认日线低点索引
     :param typ: 卖点类型
     :return: 是否发生日线买入操作
     """
     flag = False  # 是否发生买入操作
     l_pp = self.klist[l_p].low
     l_confirmed = self.klist[l_p].hl_confirmed
     p = self.klist[l_confirmed].high
     if p <= l_pp * (1 + constant.MAX_UPFLOAT):
         buy_p = Trade.Buy(self.klist[l_confirmed].t,
                           self.klist[l_confirmed].i, typ,
                           self.klist[l_confirmed].close, self.account,
                           l_pp)
         printt(
             f"##`buy_in_day`,发现日线级别买点,位置{l_confirmed},买点类型{typ};"
             f"买入价格{self.klist[l_confirmed].close};"
             f"买入理由:日线级别低点被确认时上涨幅度未超过阈值;"
             f"止损价格{l_pp}-->被确认日线低点",
             msg_mode=constant.RunMode.REPORT,
             global_mode=constant.RUN_MODE)
         flag = True
         buy_p.register()
         self.order_l.append((buy_p, len(self.bs_list)))
         self.bs_list.append(buy_p)
         self.klist[l_confirmed].trade_info(
             len(self.bs_list) - 1, buy_p.typ, buy_p.price, buy_p.volume,
             buy_p.stop_p)
     else:
         printt(f"##`buy_in_day`,未发现日线级别买点;"
                f"失败理由:日线级别低点被确认时上涨幅度超过阈值",
                msg_mode=constant.RunMode.REPORT,
                global_mode=constant.RUN_MODE)
     return flag
Example #4
0
 def init_hl(self):
     flag = True  # 是否找到顶分型或底分型
     jj = 0
     while flag:
         if self.klist[jj + 1].high >= self.klist[jj].high and \
             self.klist[jj + 1].high > self.klist[jj + 2].high:
             self.temp_h = jj
             self.hl = "h"
             self.temp_min = jj
             self.klist[jj].temp_h = jj
             self.klist[jj].hl = "h"
             self.klist[jj].temp_min = jj
             self.cursor = jj + 1
             flag = False
             printt(
                 f"##`init_hl`,找到顶分型,位置{jj};"
                 f"当前寻找高点,待判定高点位置{jj},高点价位{self.klist[jj].high}",
                 msg_mode=constant.RunMode.DEBUG,
                 global_mode=constant.RUN_MODE)
         elif self.klist[jj + 1].low <= self.klist[jj].low and \
             self.klist[jj + 1].low < self.klist[jj + 2].low:
             self.temp_l = jj
             self.hl = "l"
             self.temp_max = jj
             self.klist[jj].temp_l = jj
             self.klist[jj].hl = "l"
             self.klist[jj].temp_max = jj
             self.cursor = jj + 1
             flag = False
             printt(
                 f"##`init_hl`,找到底分型,位置{jj};"
                 f"当前寻找低点,待判定低点位置{jj},低点价位{self.klist[jj].low}",
                 msg_mode=constant.RunMode.DEBUG,
                 global_mode=constant.RUN_MODE)
         else:
             jj += 1
Example #5
0
 def roll_forward(self, lev_higher):
     while self.hlp_env.cursor < len(self.klist) and \
             self.klist[self.hlp_env.cursor].i <= lev_higher.i:
         self.hlp_env.step_hl(
             wait_thresh=constant.WAIT_30TO5)  # step_hl操作会使cursor向后推
         # 如果有同时在进行的低级别过程
         if self.lev_chg_lower:
             self.lev_chg_lower.roll_forward(
                 self.klist[self.hlp_env.cursor - 1])
             if self.lev_chg_lower.end_up_trd:
                 self.end_up_trd = True
                 printt(
                     f"###`roll_forward`,30min->5min级别下上涨趋势结束,"
                     f"位置{lev_higher.i.kti}",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
                 self.sell_k = self.lev_chg_lower.sell_k
                 self.hp5 = [
                     self.lev_chg_lower.hlp_env.klist[cur]
                     for cur in self.lev_chg_lower.hlp_env.hpi
                 ]
                 self.lp5 = [
                     self.lev_chg_lower.hlp_env.klist[cur]
                     for cur in self.lev_chg_lower.hlp_env.lpi
                 ]
                 break
         # 没有更低级别的进程
         else:
             # 是否满足本级别终止条件
             # 如果当前级别至少有一个低点
             # 由于默认应当已经在上涨趋势,一旦跌破前低就认为是结束本级别上涨趋势
             if self.hlp_env.lpi:
                 if self.klist[self.hlp_env.cursor-1].low < \
                         self.klist[self.hlp_env.lpi[-1]].low:
                     self.end_up_trd = True
                     self.sell_k = self.klist[self.hlp_env.cursor - 1]
                     printt(
                         f"###`roll_forward`,"
                         f"{['30min', '5min'][self.lev-2]}级别下上涨趋势结束,"
                         f"位置{lev_higher.i.kti},发出卖点信号",
                         msg_mode=constant.RunMode.REPORT,
                         global_mode=constant.RUN_MODE)
                     break
             # 不满足本级别终止条件,是否需要进入低接别
             if self.lev == 2 and self.klist[self.hlp_env.cursor -
                                             1].lev_chg_signal:
                 self.lev_chg_lower = Trade.LevChg(
                     code=self.code,
                     lev=3,
                     start=self.klist[self.hlp_env.cursor],
                     ref_t=self.ref_t)
                 printt(
                     f"###`roll_forward`,"
                     f"由30min操作级别转入5min操作级别寻找卖点,"
                     f"位置{lev_higher.i.kti}",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
     # 完成本轮循环,说明本级别过程仍然继续,需要考虑扩充本级别序列的数据
     if len(self.klist) - self.hlp_env.cursor <= [
             constant.LEN_K5 * 0.25, constant.LEN_K30 * 0.25
     ][self.lev == 2]:
         self.hlp_env.extend_klist(self.ref_t)
Example #6
0
 def seek_to_sell(self):
     '''
     此函数用于寻找卖点
     :return:
     '''
     flag = False  # 是否发生卖出操作
     # 如果没有多头仓位,不操作
     if not self.order_l:
         pass
     else:
         # 先以日线卖出标准将能够卖出的都卖出
         for b in self.order_l:
             bb = b[0]  # b =(buy object, index in order_l)
             # 符合日线上止损点或止盈点卖出条件, 注意不能在同一天交易
             if self.klist[self.cursor].low < bb.stop_p and self.klist[self.cursor].i.kti[0] > \
                     bb.index_k.kti[0]:
                 # 如果是浮盈后离场
                 if bb.max_profit > constant.THRESH_PROFIT:
                     typ = "S3"
                 # 其他止损点离场
                 else:
                     typ = "S2"
                 # 创建卖点对象
                 sell_p = Trade.Sell(self.klist[self.cursor].t,
                                     self.klist[self.cursor].i, typ,
                                     bb.volume,
                                     self.klist[self.cursor].close,
                                     self.account, bb)
                 printt(
                     f"##`seek_to_sell`,发现卖点,位置{self.cursor};"
                     f"卖点类型{typ},卖出价格{self.klist[self.cursor].close};"
                     f"卖出理由:{constant.BUYSELL_TYPE[typ][2]}",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
                 flag = True
                 # 在Account中注册卖点信息
                 sell_p.register()
                 self.bs_list.append(sell_p)
                 self.order_l.remove(b)
                 self.order_s.append((sell_p, len(self.bs_list) - 1))
                 self.klist[self.cursor].trade_info(
                     len(self.bs_list) - 1, typ, sell_p.price,
                     sell_p.volume, None)
             elif self.klist[self.cursor].low < self.klist[self.klist[
                     self.cursor].lpi[-1]].low and self.klist[
                         self.cursor].i.kti[0] > bb.index_k.kti[0]:
                 # 不符合上述条件,但是直接跌破前日线低点;一般适用于在日线级别买入后马上跌破
                 # 或30min低点恰好是日线低点马上跌破的30min买点
                 typ = "S1"
                 sell_p = Trade.Sell(self.klist[self.cursor].t,
                                     self.klist[self.cursor].i, typ,
                                     bb.volume,
                                     self.klist[self.cursor].close,
                                     self.account, bb)
                 printt(
                     f"##`seek_to_sell`,发现卖点,位置{self.cursor};"
                     f"卖点类型S1,卖出价格{self.klist[self.cursor].close};"
                     f"卖出理由:{constant.BUYSELL_TYPE['S1'][2]}",
                     msg_mode=constant.RunMode.REPORT,
                     global_mode=constant.RUN_MODE)
                 flag = True
                 sell_p.register()
                 self.bs_list.append(sell_p)
                 self.order_l.remove(b)
                 self.order_s.append((sell_p, len(self.bs_list) - 1))
                 self.klist[self.cursor].trade_info(
                     len(self.bs_list) - 1, typ, sell_p.price,
                     sell_p.volume, None)
         # 当日不能以日线卖出的买点,考虑是否需要进行降级别处理
         # 降级别计算较复杂,主要功能采用一个特别类对象来处理
         if len(self.order_l):
             if self.klist[self.cursor].trd == "up" and \
                     self.klist[self.cursor].lev_chg_signal:
                 for b in self.order_l:
                     bb = b[0]
                     # 当前时间买点已经发生
                     if self.klist[self.cursor].i.kti > bb.index_k.kti:
                         if not bb.lev_chg:
                             bb.lev_chg = Trade.LevChg(
                                 code=self.code,
                                 lev=2,
                                 start=self.klist[self.cursor + 1],
                                 ref_t=[k.t for k in self.klist])
                             printt(
                                 f"##`sek_to_sell`,发起30min级别卖点寻找,"
                                 f"开始位置{self.cursor}",
                                 msg_mode=constant.RunMode.REPORT,
                                 global_mode=constant.RUN_MODE)
                         else:
                             bb.lev_chg.roll_forward(
                                 self.klist[self.cursor])
                             if bb.lev_chg.end_up_trd:
                                 sell_k = bb.lev_chg.sell_k
                                 typ = ["S4", "S5"][sell_k.lev == 3]
                                 self.hp30 += \
                                     [bb.lev_chg.klist[cur] for cur in bb.lev_chg.hlp_env.hpi]
                                 self.lp30 += \
                                     [bb.lev_chg.klist[cur] for cur in bb.lev_chg.hlp_env.lpi]
                                 if typ == "S5":
                                     self.hp5 += bb.lev_chg.hp5
                                     self.lp5 += bb.lev_chg.lp5
                                 sell_p = Trade.Sell(
                                     sell_k.t, sell_k.i, typ, bb.volume,
                                     sell_k.close, self.account, bb)
                                 printt(
                                     f"##`seek_to_sell`,发现卖点,位置{self.cursor};"
                                     f"卖点类型{typ},卖出价格{sell_k.close};"
                                     f"卖出理由:{constant.BUYSELL_TYPE['S1'][2]}",
                                     msg_mode=constant.RunMode.REPORT,
                                     global_mode=constant.RUN_MODE)
                                 flag = True
                                 sell_p.register()
                                 self.bs_list.append(sell_p)
                                 self.order_l.remove(b)
                                 self.order_s.append(
                                     (sell_p, len(self.bs_list) - 1))
                                 self.klist[self.cursor].trade_info(
                                     len(self.bs_list) - 1, typ,
                                     sell_p.price, sell_p.volume, None)
                     else:
                         continue
     return flag
Example #7
0
    def buy_in_min30(self, start, end, pre_low, typ):
        flag1 = False  # 是否跌破前日线低点,跌破日线前低点,终止买点搜索
        flag2 = False  # 是否找到买点机会
        begin_time = self.klist[start + 1].t + constant.MIN30_STR[0]
        end_time = self.klist[end].t + constant.MIN30_STR[-1]
        klist30 = loadData_min(begin_time, self.code, end_time, 30, start + 1)
        hlp30_env = HLPointMin(klist30, self.code, constant.THRESH_30, 2, "l")
        for cursor in range(hlp30_env.cursor, len(hlp30_env.klist)):
            ref_low30 = -np.inf  # 如果要以30min低点作参考, 暂时不需要
            # # 如果已经有30min级别低点,不能跌破前低
            # if len(hlp30_env.klist[cursor].lpi):
            #     ref_low30 = hlp30_env.klist[hlp30_env.klist[cursor].lpi[-1]].low

            if hlp30_env.klist[cursor].low < max(self.klist[pre_low].low,
                                                 ref_low30):
                flag1 = True  # 买点寻找过程中是否跌破前日线低点或更保守的以30min前低点作为参照
                printt(
                    f"###`buy_in_min30`,未发现30min买点;"
                    f"失败理由:30min下跌趋势中跌破前日线(或前30min)低点",
                    msg_mode=constant.RunMode.REPORT,
                    global_mode=constant.RUN_MODE)
                break
            else:
                hlp30_env.step_hl(wait_thresh=constant.WAIT_30TO5
                                  )  # step_hl使得cursor增加1,注意减回来
                if len(hlp30_env.hpi) + len(hlp30_env.lpi) < 3:
                    # printt(f"###`buy_in_min30`,未发现30min买点;"
                    #        f"失败理由:30min未构成完整趋势",
                    #        msg_mode=constant.RunMode.REPORT,
                    #        global_mode=constant.RUN_MODE)
                    pass
                else:
                    if len(hlp30_env.klist[cursor].hpi
                           ) >= 1:  # NOTE:放宽要求,l1-h1-l2-cursor(
                        # c>h2, l2>l1)模式也承认
                        if hlp30_env.klist[cursor].high > \
                                hlp30_env.klist[hlp30_env.klist[cursor].hpi[-1]].high and \
                                (hlp30_env.klist[hlp30_env.klist[cursor].lpi[-1]].low >
                                 hlp30_env.klist[hlp30_env.klist[cursor].lpi[-2]].low):
                            flag2 = True  # 是否找到符合条件的30min级别买点
                            # 记录有效(有交易发生)30min高点K对象
                            self.hp30 += \
                                [hlp30_env.klist[cur] for cur in hlp30_env.hpi]
                            # 记录有效(有交易发生)30min低点K对象
                            self.lp30 += \
                                [hlp30_env.klist[cur] for cur in hlp30_env.lpi]
                            stop_p = hlp30_env.klist[
                                hlp30_env.klist[cursor].temp_l].low
                            stop_p *= (1 + constant.STOP_P_BUFFER_30)
                            buy_p = Trade.Buy(hlp30_env.klist[cursor].t,
                                              hlp30_env.klist[cursor].i,
                                              typ,
                                              hlp30_env.klist[cursor].close,
                                              self.account,
                                              stop_p=stop_p)
                            printt(
                                f"###`buy_in_min30`,发现30min买点,买点类型:{typ};"
                                f"买入理由:30min下跌趋势中突破前30min高点;"
                                f"止损价格{stop_p}->30min最近低点",
                                msg_mode=constant.RunMode.REPORT,
                                global_mode=constant.RUN_MODE)
                            buy_p.register()
                            self.order_l.append((buy_p, len(self.bs_list)))
                            self.bs_list.append(buy_p)
                            self.klist[
                                hlp30_env.klist[cursor].i.kti[0]].trade_info(
                                    len(self.bs_list) - 1, typ,
                                    hlp30_env.klist[cursor].close,
                                    buy_p.volume, buy_p.stop_p)
                            break
        return flag1, flag2
Example #8
0
    def seek_to_buy(self):
        """
        处理买入操作
        :return: 是否发生买入操作
        """
        flag = False  # 是否发生买入操作
        h_confirmed = [self.klist[hh].hl_confirmed
                       for hh in self.hpi]  # 回测期间内所有高点被确认时的K线序号
        if (self.cursor in h_confirmed) and len(
                self.klist[self.cursor].lpi):  #
            # 如果本K线当日确认了高点,且非第一个高低点
            last_opt = "NA" if not self.bs_list else self.bs_list[-1].typ
            pre_low = self.klist[self.cursor].lpi[-1]  # 前低点序列号
            pre_low_i = self.lpi.index(pre_low)  # 前低点在低点序列内的序列号
            # 如果前低点不是回测区间内最后一个低点,那么30min数据提取范围从本K线到后一低点被确认当日结束;否则从本K线到回测期最后一日
            # 此处不涉及未来函数,因为在逐日监控中,30min买点寻找在低点被确认当日自然停止
            l_confirmed = len(self.klist) - 1 if pre_low == self.lpi[-1] else \
                self.klist[self.lpi[pre_low_i+1]].hl_confirmed
            # 左侧买点,下跌过程中,高点确认时尚未跌破前低(存在下一低点比前低点抬高的可能)
            if self.klist[self.cursor].trd == 'down' and \
                self.klist[self.cursor].low > self.klist[pre_low].low:
                self.operate_lev_buy = 2  # 转换买入操作级别为30min级别
                printt(
                    f"##`seek_to_buy`,尝试寻找第一买点,位置{self.cursor};"
                    f"确认高点处于下跌趋势中,目前未跌破前低点;"
                    f"30min搜索范围{self.cursor}~{l_confirmed}",
                    msg_mode=constant.RunMode.DEBUG,
                    global_mode=constant.RUN_MODE)
                res = self.buy_in_min30(self.cursor, l_confirmed, pre_low,
                                        "B1-0")
                if res[0]:
                    self.operate_lev_buy = 1

                elif res[1]:
                    self.operate_lev_buy = 1
                    flag = True
                else:
                    if pre_low_i < len(self.lpi) - 1:
                        printt(f"##`seek_to_buy`,转而尝试寻找日线第一买点,位置{self.cursor}",
                               msg_mode=constant.RunMode.DEBUG,
                               global_mode=constant.RUN_MODE)
                        # NOTE: 不需要额外增加判定日线低点抬高的条件,因为如果中间跌破前低,res[0]为True
                        flag = self.buy_in_day(self.lpi[pre_low_i + 1], "B1-1")
                        # self.operate_lev_buy = [2, 1][flag]
                        self.operate_lev_buy = 1
            elif self.klist[self.cursor].trd == "consd" and \
                    self.klist[self.cursor].pre_trd == "down" and \
                    self.klist[self.cursor].low > self.klist[pre_low].low:
                # 由下跌转为盘整趋势中(说明被确认的高点高于前高,而前两个低点降低),目前尚未跌破前低
                self.operate_lev_buy = 2
                printt(
                    f"##`seek_to_buy`,尝试寻找第二买点,位置{self.cursor};"
                    f"确认高点处于下跌趋势转为盘整,目前未跌破前低点;"
                    f"30min搜索范围{self.cursor}~{l_confirmed}",
                    msg_mode=constant.RunMode.DEBUG,
                    global_mode=constant.RUN_MODE)
                res = self.buy_in_min30(self.cursor, l_confirmed, pre_low,
                                        "B2-0")
                if res[0]:
                    self.operate_lev_buy = 1

                elif res[1]:
                    self.operate_lev_buy = 1
                    flag = True
                else:
                    if pre_low_i < len(self.lpi) - 1:
                        flag = self.buy_in_day(self.lpi[pre_low_i + 1], "B2-1")
                        # self.operate_lev_buy = [2, 1][flag]
                        self.operate_lev_buy = 1
            elif self.klist[self.cursor].trd == "up" and \
                    self.klist[self.cursor].low > self.klist[pre_low].low and last_opt[:2] not in \
                    ("B2", "B3"):
                # 当前处于上涨趋势中,且上一操作不是第二买点或第三买点
                self.operate_lev_buy = 2
                printt(
                    f"##`seek_to_buy`,尝试寻找第二(三)买点,位置{self.cursor};"
                    f"确认高点处于上涨趋势中,目前未跌破前低点;"
                    f"30min搜索范围{self.cursor}~{l_confirmed}",
                    msg_mode=constant.RunMode.DEBUG,
                    global_mode=constant.RUN_MODE)
                res = self.buy_in_min30(self.cursor, l_confirmed, pre_low,
                                        ["B2-0", "B3-0"
                                         ][int(last_opt in ("S4", "S5"))])
                if res[0]:
                    self.operate_lev_buy = 1

                elif res[1]:
                    self.operate_lev_buy = 1
                    flag = True
                else:
                    if pre_low_i < len(self.lpi) - 1:
                        flag = self.buy_in_day(self.lpi[pre_low_i + 1],
                                               ["B2-1", "B3-1"
                                                ][int(last_opt in ("S4",
                                                                   "S5"))])
                        # self.operate_lev_buy = [2, 1][flag]
                        self.operate_lev_buy = 1
            elif self.klist[self.cursor].trd == "consd" and \
                self.klist[self.cursor].pre_trd == "up" and \
                self.klist[self.cursor].low > self.klist[pre_low].low and \
                "B1" not in last_opt:
                # 由上涨转入盘整趋势中,高点低点区间连续放宽
                self.operate_lev_buy = 2
                printt(
                    f"##`seek_to_buy`,尝试寻找第买点一,位置{self.cursor};"
                    f"上涨趋势转为盘整,目前未跌破前低点;"
                    f"30min搜索范围{self.cursor}~{l_confirmed}",
                    msg_mode=constant.RunMode.DEBUG,
                    global_mode=constant.RUN_MODE)
                res = self.buy_in_min30(self.cursor, l_confirmed, pre_low,
                                        "B1-0")
                if res[0]:
                    self.operate_lev_buy = 1

                elif res[1]:
                    self.operate_lev_buy = 1
                    flag = True
                else:
                    if pre_low_i < len(self.lpi) - 1:
                        flag = self.buy_in_day(self.lpi[pre_low_i + 1], "B1-1")
                        # self.operate_lev_buy = [2, 1][flag]
                        self.operate_lev_buy = 1
        return flag
Example #9
0
    def step_hl(self, wait_thresh=constant.WAIT_DTO30):
        """
        完成导入回测期全部K线数据并创建K对象实例list后,在第二次从头遍历K对象实例时的每步迭代函数
        需要完成以下任务:
        / 1.将当前高低点对象实例维护的全局状态域赋值给当前遍历的K对象实例的自有对应域
        :param wait_thresh:
        :return:
        """
        if self.cursor < len(self.klist):
            self.klist[self.cursor].hpi = copy(self.hpi)
            self.klist[self.cursor].lpi = copy(self.lpi)
            self.klist[self.cursor].hl = self.hl
            self.klist[self.cursor].temp_l = self.temp_l
            self.klist[self.cursor].temp_h = self.temp_h
            self.klist[self.cursor].temp_min = self.temp_min
            self.klist[self.cursor].temp_max = self.temp_max
            if self.hl == "h":
                # 在找高点过程中出现新高,则转换当前高点为待判定高点,自新高(当前K)回调最低点为当前K
                if self.klist[self.cursor].high > self.klist[self.temp_h].high:
                    self.temp_h = self.cursor
                    self.temp_min = self.cursor
                    self.klist[self.cursor].temp_h = self.temp_h
                    self.klist[self.cursor].temp_min = self.temp_min
                    printt(
                        f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                        f"寻高点过程出现新高,新待判定高点位置{self.temp_h},"
                        f"新高点价位{self.klist[self.cursor].high}",
                        msg_mode=constant.RunMode.INFO,
                        global_mode=constant.RUN_MODE)

                else:
                    # 如果找高点过程中未出现新高
                    self.klist[self.cursor].use_space = self.use_space
                    # 如果自待判定高点回调以来出现新低
                    if self.klist[self.cursor].low < self.klist[
                            self.temp_min].low:
                        # 则当前K为回调新低
                        self.temp_min = self.cursor
                        self.klist[self.cursor].temp_min = self.temp_min
                        printt(
                            f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                            f"寻高点过程出现自待判定高点以来回调新低,"
                            f"新低位置{self.cursor},点位{self.klist[self.cursor].low}",
                            msg_mode=constant.RunMode.INFO,
                            global_mode=constant.RUN_MODE)
                        # 判断是否满足以”空间回撤“大小提前(相对于回调时间长度条件)判定高点的条件
                        if self.space_h and \
                                round((self.klist[self.temp_min].low -
                                       self.klist[self.temp_h].high) / self.klist[self.temp_h].high, 2) \
                                < -self.space_h * constant.AVG_BUFFER:
                            self.use_space = True
                            self.klist[self.cursor].use_space = self.use_space
                            printt(
                                f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                                f"寻高点过程满足空间判定条件,可确认高点",
                                msg_mode=constant.RunMode.INFO,
                                global_mode=constant.RUN_MODE)
                    if (self.use_space or (self.temp_min - self.temp_h) >= self.thresh or
                            len(self.lpi) and self.klist[self.temp_min].low < self.klist[self.lpi[-1]].low) and\
                            self.temp_min == self.cursor:
                        # 判定高点的3个条件:
                        # / 0.当前K为自待判定高点以来回调最低点
                        #  以下条件三选一:
                        # / 1.当前K距离带判定高点(时间,指有效日K线数)距离超过阈值-->时间判定
                        # / 2.当前K的最低价距离待判定高点最高价回调幅度超过阈值-->空间判定
                        # / 3.当前K的最低价已经跌破前被确认低点的最低价-->跌破前低判定
                        printt(
                            f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                            f"确认高点,高点位置{self.temp_h},高点价位"
                            f"{self.klist[self.temp_h].high};当前位置{self.cursor},转为寻低点"
                            f"过程,待判定低点价位{self.klist[self.cursor].low}",
                            msg_mode=constant.RunMode.DEBUG,
                            global_mode=constant.RUN_MODE)
                        self.hpi.append(self.temp_h)
                        self.klist[self.temp_h].hl_confirmed = self.cursor
                        self.klist[self.cursor].confirm_hl = self.temp_h
                        self.confirm_p.append(self.cursor)
                        # 将全局状态转变为寻找低点相关
                        self.hl = "l"
                        self.klist[self.cursor].hl = 'l'
                        self.temp_l = self.temp_min
                        self.klist[self.cursor].temp_l = self.temp_l
                        self.temp_max = self.cursor
                        self.klist[self.cursor].temp_max = self.temp_max
                        self.use_space = False
                        self.klist[self.cursor].hpi = copy(self.hpi)
                        # 计算从低点到高点的上涨平均空间水平,是为下一次确认低点的条件2做准备
                        l2h = self.l2h()
                        if len(l2h) >= constant.AVG_N:
                            self.space_l = round(
                                np.mean(
                                    list(
                                        map(
                                            lambda x, y:
                                            (self.klist[x].high - self.klist[y]
                                             .low) / self.klist[y].low, [
                                                 k[1]
                                                 for k in l2h[-constant.AVG_N:]
                                             ], [
                                                 k[0]
                                                 for k in l2h[-constant.AVG_N:]
                                             ]))).item(), 3)
                            if self.space_l == np.nan:
                                self.space_l = 0.0
                            else:
                                printt(
                                    f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                                    f"存在低点确认可参考空间涨幅{self.space_l}",
                                    msg_mode=constant.RunMode.INFO,
                                    global_mode=constant.RUN_MODE)

            else:
                # 在找低点过程中
                if self.klist[self.cursor].low < self.klist[self.temp_l].low:
                    # 当前出现跌破待判定低点的前低,更新当前K为待判定低点
                    self.temp_l = self.cursor
                    self.temp_max = self.cursor
                    self.klist[self.cursor].temp_l = self.temp_l
                    self.klist[self.cursor].temp_max = self.temp_max
                    printt(
                        f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                        f"寻低点过程出现新低,新待判定低点位置{self.temp_l},"
                        f"新低点价位{self.klist[self.cursor].low}",
                        msg_mode=constant.RunMode.INFO,
                        global_mode=constant.RUN_MODE)
                else:
                    self.klist[self.cursor].use_space = self.use_space
                    if self.klist[self.cursor].high > self.klist[
                            self.temp_max].high:
                        # 当前出现自待判定低点上涨以来新高,更新当前K为上涨新高
                        self.temp_max = self.cursor
                        self.klist[self.cursor].temp_max = self.temp_max
                        printt(
                            f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                            f"寻低点过程出现自待判定低点以来上涨新高,"
                            f"新高位置{self.cursor},点位{self.klist[self.cursor].high}",
                            msg_mode=constant.RunMode.INFO,
                            global_mode=constant.RUN_MODE)
                        if self.space_l and \
                                (self.klist[self.temp_max].high -
                                 self.klist[self.temp_l].low) / self.klist[self.temp_l].low > \
                                self.space_l*constant.AVG_BUFFER:
                            self.use_space = True
                            self.klist[self.cursor].use_space = self.use_space
                            printt(
                                f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                                f"寻低点过程满足空间判定条件,可确认低点",
                                msg_mode=constant.RunMode.INFO,
                                global_mode=constant.RUN_MODE)
                    if (self.use_space or (self.temp_max - self.temp_l) >= self.thresh or
                        len(self.hpi) and self.klist[self.temp_max].high > self.klist[self.hpi[-1]].high) and\
                            self.temp_max == self.cursor:
                        # 确认低点的前提条件(条件0)和其他三个任选条件与确认高点是镜像问题
                        printt(
                            f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                            f"确认低点,低点位置{self.temp_l},低点价位"
                            f"{self.klist[self.temp_l].low};当前位置{self.cursor},转为寻高点"
                            f"过程,待判定高点价位{self.klist[self.cursor].high}",
                            msg_mode=constant.RunMode.DEBUG,
                            global_mode=constant.RUN_MODE)
                        self.lpi.append(self.temp_l)
                        self.klist[self.temp_l].hl_confirmed = self.cursor
                        self.klist[self.cursor].confirm_hl = self.temp_l
                        self.confirm_p.append(self.cursor)
                        # 将全局状态转换为找高点
                        self.hl = "h"
                        self.klist[self.cursor].hl = 'h'
                        self.temp_h = self.temp_max
                        self.klist[self.cursor].temp_h = self.temp_h
                        self.temp_min = self.cursor
                        self.klist[self.cursor].temp_min = self.temp_min
                        self.use_space = False
                        self.klist[self.cursor].lpi = copy(self.lpi)
                        h2l = self.h2l()
                        if len(h2l) >= constant.AVG_N:
                            self.space_h = round(
                                np.mean(
                                    list(
                                        map(
                                            lambda x, y:
                                            (self.klist[x].high - self.klist[y]
                                             .low) / self.klist[x].high, [
                                                 k[0]
                                                 for k in h2l[-constant.AVG_N:]
                                             ], [
                                                 k[1]
                                                 for k in h2l[-constant.AVG_N:]
                                             ]))).item(), 3)
                            if self.space_h == np.nan:
                                self.space_h = 0.0
                            else:
                                printt(
                                    f"##`step_hl-{constant.K_LEV_DICT[self.k_lev]}`,"
                                    f"存在高点确认可参考空间涨幅{self.space_h}",
                                    msg_mode=constant.RunMode.INFO,
                                    global_mode=constant.RUN_MODE)

            if self.hl == "h":
                # 对于找高点的升频条件判定,如果超过等待时间还不能确认高点,发出级别降低提示
                if self.klist[self.cursor].lpi:
                    self.klist[self.cursor].lev_chg_signal = \
                        (self.cursor - self.klist[self.cursor].lpi[-1]) >= wait_thresh
                else:
                    self.klist[
                        self.
                        cursor].lev_chg_signal = self.cursor >= wait_thresh
            self.cursor += 1
Example #10
0
    def step_trd(self):
        """
        趋势判定主函数,在高低点标定之后进行
        :return:
        """
        if self.trdnow == 'up' and self.hlp_env.klist[self.cursor].hl == 'h':
            # 当前上涨趋势+待判定高点
            if self.hlp_env.klist[self.cursor].low < self.hlp_env.klist[
                    self.hlp_env.klist[self.cursor].lpi[-1]].low:
                # NOTE:该种情况可能不会发生,因为一旦跌破前低点,满足确认高点条件,当即确认高点,hl转变为”l“
                self.trdchg.append(self.cursor)  # 上升趋势中,待判定高点未确认,若期间跌破前低,转为盘整
                self.hlp_env.klist[self.cursor].trd = 'consd'
                self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                self.trdnow = 'consd'
                printt(
                    f"##`step_trd`,确认盘整趋势开启,位置{self.cursor};"
                    f"之前趋势:up;确认条件:上涨趋势中高点未确认,跌破前低点",
                    msg_mode=constant.RunMode.REPORT,
                    global_mode=constant.RUN_MODE)
            else:
                self.hlp_env.klist[self.cursor].trd = self.trdnow  # 延续上升趋势
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd
        elif self.trdnow == 'up' and self.hlp_env.klist[
                self.cursor].hl == 'l':  # 当前上涨趋势+待判定低点
            if self.hlp_env.klist[self.cursor].low < self.hlp_env.klist[
                    self.hlp_env.klist[self.cursor].lpi[-1]].low:
                # 当前跌破前低点,上涨趋势终止
                if self.hlp_env.klist[self.hlp_env.klist[self.cursor].hpi[-1]].high < \
                    self.hlp_env.klist[self.hlp_env.klist[self.cursor].hpi[-2]].high:
                    # 高点已连续降低,可追认下跌趋势
                    self.hlp_env.klist[
                        self.cursor].trd = 'down'  # 上升趋势,待判定低点,期间跌破前低,且高点已连续降低
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    # 上升趋势转为下跌-->跌破前低表明上升结束,追认高点降低为下跌条件
                    self.trdchg.append(self.cursor)
                    self.trdnow = 'down'
                    printt(
                        f"##`step_trd`,确认下跌趋势开启,位置{self.cursor};"
                        f"之前趋势:up;确认条件:上涨趋势中待判定低点,期间跌破前低点,高点已确认并连续降低,追认下跌趋势",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
                else:
                    self.hlp_env.klist[
                        self.cursor].trd = 'consd'  # 上升趋势,待判定低点,期间跌破前低,表明上升结束
                    self.trdchg.append(self.cursor)  # 但高点未连续降低,尚不满足下跌条件,转为盘整
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    self.trdnow = 'consd'
                    printt(
                        f"##`step_trd`,确认盘整趋势开启,位置{self.cursor};"
                        f"之前趋势:up;确认条件:上涨趋势中待判定低点,期间跌破前低点,高点已确认但未连续降低",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
            else:
                self.hlp_env.klist[
                    self.cursor].trd = self.trdnow  # 上升趋势未跌破前低,趋势延续
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd
        elif self.trdnow == 'down' and self.hlp_env.klist[
                self.cursor].hl == 'l':
            if self.hlp_env.klist[self.cursor].high > self.hlp_env.klist[
                    self.hlp_env.klist[self.cursor].hpi[-1]].high:
                # 同其镜像问题,该种情况也不会出现,一点突破前高点,当即确认低点,hl转为h
                self.trdchg.append(self.cursor)  # 下跌趋势,待判定低点,若期间突破前高,转为盘整
                self.hlp_env.klist[self.cursor].trd = 'consd'
                self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                self.trdnow = 'consd'
                printt(
                    f"##`step_trd`,确认盘整趋势开启,位置{self.cursor};"
                    f"之前趋势:down;确认条件:下跌趋势中低点未确认,突破前高点",
                    msg_mode=constant.RunMode.REPORT,
                    global_mode=constant.RUN_MODE)
            else:
                self.hlp_env.klist[
                    self.cursor].trd = self.trdnow  # 下跌趋势,待判定低点,不突破前高,趋势保持
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd
        elif self.trdnow == 'down' and self.hlp_env.klist[
                self.cursor].hl == 'h':
            if self.hlp_env.klist[self.cursor].high > self.hlp_env.klist[
                    self.hlp_env.klist[self.cursor].hpi[-1]].high:
                if self.hlp_env.klist[self.hlp_env.klist[self.cursor].lpi[-1]].low > \
                    self.hlp_env.klist[self.hlp_env.klist[self.cursor].lpi[-2]].low:
                    self.hlp_env.klist[
                        self.
                        cursor].trd = 'up'  # 下跌趋势,待判定高点,若期间突破前高,且低点已连续抬高,满足上涨条件
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    self.trdnow = 'up'
                    self.trdchg.append(self.cursor)
                    printt(
                        f"##`step_trd`,确认上涨趋势开启,位置{self.cursor};"
                        f"之前趋势:down;确认条件:下跌趋势中待判定高点,期间突破前高点,低点已确认并连续抬高,追认上涨趋势",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
                else:
                    self.hlp_env.klist[self.cursor].trd = 'consd'  #
                    # 下跌趋势,待判定高点,期间高点突破,下跌结束,但低点未连续抬高,不满足上涨条件,转为盘整
                    self.trdchg.append(self.cursor)
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    self.trdnow = 'consd'
                    printt(
                        f"##`step_trd`,确认盘整趋势开启,位置{self.cursor};"
                        f"之前趋势:down;确认条件:下跌趋势中待判定高点,期间突破前高点,低点已确认但未连续抬高",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
            else:
                self.hlp_env.klist[self.cursor].trd = self.trdnow
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd
        elif self.trdnow == 'consd' and self.hlp_env.klist[
                self.cursor].hl == 'h':
            # 当前盘整趋势+待判定高点
            # NOTE:规范的盘整一般最终都可划归为两种形态
            # / 1.h1-l1-h2(h2>h1)-cursor(c<l1,跌破前低),由上涨趋势转化而来
            # / 2.l1-h1-l2(l2<l1)-cursor(c>h1,突破前高),由下跌趋势转化而来
            # 脱离盘整的判定有2种:
            # / 1.在step_trdmax中通过时间超跌超涨非结构性的转入上涨或下跌
            # / 2.在高点或低点被确认的K线上可能出现新状态

            if self.hlp_env.klist[self.hlp_env.klist[
                    self.cursor].lpi[-1]].hl_confirmed == self.cursor:
                # 在当前K上确认最近低点,转入h
                if ((self.hlp_env.klist[self.hlp_env.klist[
                        self.cursor].hpi[-1]].high > self.hlp_env.klist[
                            self.hlp_env.klist[self.cursor].hpi[-2]].high)
                        and (self.hlp_env.klist[self.hlp_env.klist[
                            self.cursor].lpi[-1]].low > self.hlp_env.klist[
                                self.hlp_env.klist[self.cursor].lpi[-2]].low)):
                    # 通过确认低点后可以马上结束盘整的模式-->h1-l1-h2(h2>h1)-l2(确认,l2>l1)
                    self.hlp_env.klist[self.cursor].trd = 'up'
                    self.trdchg.append(self.cursor)
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    self.trdnow = 'up'
                    printt(
                        f"##`step_trd`,确认上涨趋势开启,位置{self.cursor};"
                        f"之前趋势:{self.hlp_env.klist[self.cursor].pre_trd};"
                        f"确认条件:低点被确认后立即符合上涨形态",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
                else:
                    self.hlp_env.klist[self.cursor].trd = self.trdnow
                    self.hlp_env.klist[
                        self.cursor].pre_trd = self.hlp_env.klist[self.cursor -
                                                                  1].pre_trd
            else:
                self.hlp_env.klist[self.cursor].trd = self.trdnow
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd

        elif self.trdnow == 'consd' and self.hlp_env.klist[
                self.cursor].hl == 'l':
            if self.hlp_env.klist[self.hlp_env.klist[
                    self.cursor].hpi[-1]].hl_confirmed == self.cursor:
                # 当前K上确认最近高点
                if ((self.hlp_env.klist[self.hlp_env.klist[
                        self.cursor].hpi[-1]].high < self.hlp_env.klist[
                            self.hlp_env.klist[self.cursor].hpi[-2]].high)
                        and (self.hlp_env.klist[self.hlp_env.klist[
                            self.cursor].lpi[-1]].low < self.hlp_env.klist[
                                self.hlp_env.klist[self.cursor].lpi[-2]].low)):
                    # 通过确认低点后可以马上结束盘整的模式-->l1-h1-l2(l2<l1)-h2(确认,h2<h1)
                    self.hlp_env.klist[self.cursor].trd = 'down'
                    self.trdchg.append(self.cursor)
                    self.hlp_env.klist[self.cursor].pre_trd = self.trdnow
                    self.trdnow = 'down'
                    printt(
                        f"##`step_trd`,确认下跌趋势开启,位置{self.cursor};"
                        f"之前趋势:{self.hlp_env.klist[self.cursor].pre_trd};"
                        f"确认条件:高点被确认后立即符合下跌形态",
                        msg_mode=constant.RunMode.REPORT,
                        global_mode=constant.RUN_MODE)
                else:
                    self.hlp_env.klist[self.cursor].trd = self.trdnow
                    self.hlp_env.klist[
                        self.cursor].pre_trd = self.hlp_env.klist[self.cursor -
                                                                  1].pre_trd
            else:
                self.hlp_env.klist[self.cursor].trd = self.trdnow
                self.hlp_env.klist[self.cursor].pre_trd = self.hlp_env.klist[
                    self.cursor - 1].pre_trd
        self.cursor += 1