예제 #1
0
class Fut_YuePortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'yue'

        assert len(symbol_list) == 2
        self.symbol_a = symbol_list[0]
        self.symbol_b = symbol_list[1]
        self.dual_name = self.symbol_a + '_' + self.symbol_b
        symbol_list.append(self.dual_name)
        self.got_dict = {}
        self.got_dict[self.symbol_a] = False
        self.got_dict[self.symbol_b] = False

        df = self.load_param()
        if df is not None:
            for i, row in df.iterrows():
                if row.symbol_a in symbol_list and row.symbol_b in symbol_list:
                    pass

        Portfolio.__init__(self, Fut_YueSignal, engine, symbol_list,
                           signal_param)

        self.name_second = 'yue_' + self.dual_name

        # print(symbol_list, self.dual_name)

    #----------------------------------------------------------------------
    def load_param(self):
        fn = get_dss() + 'fut/engine/yue/portfolio_yue_param.csv'
        df = None
        if os.path.exists(fn):
            df = pd.read_csv(fn)

        return df

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min5':  # 本策略为min5
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """

        if self.got_dict[self.symbol_a] == True and self.got_dict[
                self.symbol_b] == True:
            for signal in self.signalDict[self.dual_name]:
                for s_a in self.signalDict[self.symbol_a]:
                    ask_price_a = float(s_a.bar.AskPrice)  # 挂卖价
                    bid_price_a = float(s_a.bar.BidPrice)  # 挂买价
                for s_b in self.signalDict[self.symbol_b]:
                    ask_price_b = float(s_b.bar.AskPrice)  # 挂卖价
                    bid_price_b = float(s_b.bar.BidPrice)  # 挂买价

                long_price = ask_price_a - bid_price_b
                short_price = bid_price_a - ask_price_b
                bar_dual = VtBarData()
                bar_dual.vtSymbol = self.dual_name
                bar_dual.high = short_price
                bar_dual.low = long_price
                bar_dual.date = bar.date
                bar_dual.time = bar.time
                bar_dual.datetime = bar.date + ' ' + bar.time

                # 将bar推送给signal
                signal.onBar(bar_dual, minx)
                self.result.updateBar(bar_dual)

                # print(bar_dual.vtSymbol, bar_dual.datetime )

            self.got_dict[self.symbol_a] = False
            self.got_dict[self.symbol_b] = False

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def _bc_dual_signal(self, direction, offset, volume):
        for signal in self.signalDict[self.symbol_a]:
            signal_a = signal
        for signal in self.signalDict[self.symbol_b]:
            signal_b = signal

        # 此处应使用挂买、挂卖价
        if direction == DIRECTION_LONG and offset == OFFSET_OPEN:
            signal_a.buy(float(signal_a.bar.AskPrice), volume)
            signal_b.short(float(signal_b.bar.BidPrice), volume)
        if direction == DIRECTION_SHORT and offset == OFFSET_OPEN:
            signal_a.short(float(signal_a.bar.BidPrice), volume)
            signal_b.buy(float(signal_b.bar.AskPrice), volume)
        if direction == DIRECTION_LONG and offset == OFFSET_CLOSE:
            signal_a.cover(float(signal_a.bar.AskPrice), volume)
            signal_b.sell(float(signal_b.bar.BidPrice), volume)
        if direction == DIRECTION_SHORT and offset == OFFSET_CLOSE:
            signal_a.sell(float(signal_a.bar.BidPrice), volume)
            signal_b.cover(float(signal_b.bar.AskPrice), volume)
예제 #2
0
class Fut_Skew_StrdPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'skew_strd'
        self.tm = '00:00:00'
        self.got_dict = {}
        for symbol in symbol_list:
            self.got_dict[symbol] = False

        # self.d_base_dict = {}

        Portfolio.__init__(self, Fut_Skew_StrdSignal, engine, symbol_list,
                           signal_param)

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.tm != bar.time:
            self.tm = bar.time
            for symbol in self.vtSymbolList:
                self.got_dict[symbol] = False

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        # print('here')
        self.control_in_p(bar)
        # print('here3')

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def control_in_p(self, bar):
        if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0

            # cols = ['tm','basic_m0','basic_m1','strike_m0','strike_m1','fixed_size','profit','state','source','hold_m0','hold_m1','skew_low_open','skew_high_open','price_c_m0','price_p_m0','price_c_m1','price_p_m1','skew_max','dida_max','skew_min','dida_min','profit_m0','profit_m1','profit_o','date']
            fn = get_dss(
            ) + 'fut/engine/skew_strd/portfolio_skew_strd_param.csv'

            cols_straddle = [
                'tm', 'basic_c', 'strike_c', 'basic_p', 'strike_p', 'num_c',
                'num_p', 'direction', 'hold_c', 'hold_p', 'profit', 'state',
                'source', 'price_c', 'price_p', 'profit_c', 'profit_p',
                'profit_o', 'date'
            ]
            fn_straddle = get_dss(
            ) + 'fut/engine/straddle/portfolio_straddle_param.csv'

            df = pd.read_csv(fn)
            df_straddle = pd.read_csv(fn_straddle)
            symbol_got_list = []

            for i, row in df.iterrows():
                try:
                    r = []
                    if row.state == 'stop':
                        continue

                    if row.basic_m0[:2] == 'IO':
                        symbol_obj = 'IF' + row.basic_m0[2:]
                    else:
                        symbol_obj = row.basic_m0

                    exchangeID = str(get_contract(row.basic_m0).exchangeID)
                    if exchangeID in ['CFFEX', 'DCE']:
                        symbol_c_m0 = row.basic_m0 + '-C-' + str(row.strike_m0)
                        symbol_p_m0 = row.basic_m0 + '-P-' + str(row.strike_m0)
                        symbol_c_m1 = row.basic_m1 + '-C-' + str(row.strike_m1)
                        symbol_p_m1 = row.basic_m1 + '-P-' + str(row.strike_m1)
                    else:
                        symbol_c_m0 = row.basic_m0 + 'C' + str(row.strike_m0)
                        symbol_p_m0 = row.basic_m0 + 'P' + str(row.strike_m0)
                        symbol_c_m1 = row.basic_m1 + 'C' + str(row.strike_m1)
                        symbol_p_m1 = row.basic_m1 + 'P' + str(row.strike_m1)

                    if symbol_obj not in self.got_dict or symbol_c_m0 not in self.got_dict or symbol_p_m0 not in self.got_dict or symbol_c_m1 not in self.got_dict or symbol_p_m1 not in self.got_dict:
                        continue

                    if self.got_dict[symbol_obj] == False or self.got_dict[
                            symbol_c_m0] == False or self.got_dict[
                                symbol_p_m0] == False or self.got_dict[
                                    symbol_c_m1] == False or self.got_dict[
                                        symbol_p_m1] == False:
                        continue
                    else:
                        symbol_got_list.append(symbol_obj)
                        symbol_got_list.append(symbol_c_m0)
                        symbol_got_list.append(symbol_p_m0)
                        symbol_got_list.append(symbol_c_m1)
                        symbol_got_list.append(symbol_p_m1)

                        s_obj = self.signalDict[symbol_obj][0]
                        s_c_m0 = self.signalDict[symbol_c_m0][0]
                        s_p_m0 = self.signalDict[symbol_p_m0][0]
                        s_c_m1 = self.signalDict[symbol_c_m1][0]
                        s_p_m1 = self.signalDict[symbol_p_m1][0]

                        df.at[i, 'tm'] = bar.time

                        # 开仓
                        if row.hold_m0 == 0 and row.hold_m1 == 0:
                            iv_right_c = self.calc_iv(row.basic_m1, 'C',
                                                      s_obj.bar.close,
                                                      row.strike_m1,
                                                      s_c_m1.bar.close)
                            iv_right_p = self.calc_iv(row.basic_m1, 'P',
                                                      s_obj.bar.close,
                                                      row.strike_m1,
                                                      s_p_m1.bar.close)
                            iv_left_c = self.calc_iv(row.basic_m0, 'C',
                                                     s_obj.bar.close,
                                                     row.strike_m0,
                                                     s_c_m0.bar.close)
                            iv_left_p = self.calc_iv(row.basic_m0, 'P',
                                                     s_obj.bar.close,
                                                     row.strike_m0,
                                                     s_p_m0.bar.close)
                            skew = round(
                                100 * (iv_right_c + iv_right_p - iv_left_c -
                                       iv_left_p) / (iv_left_c + iv_left_p), 2)
                            # print(skew)

                            if skew > row.skew_max:
                                df.at[i, 'skew_max'] = skew
                                df.at[i, 'dida_max'] = 0
                            else:
                                df.at[i, 'dida_max'] = row.dida_max + 1
                                # print(df.at[i, 'dida_max'], row.dida_max)

                            if skew < row.skew_min:
                                df.at[i, 'skew_min'] = skew
                                df.at[i, 'dida_min'] = 0
                            else:
                                df.at[i, 'dida_min'] = row.dida_min + 1

                            # 做空m0,做多m1
                            if df.at[
                                    i,
                                    'skew_min'] < row.skew_low_open and skew >= row.skew_low_open and df.at[
                                        i, 'dida_min'] > 0:
                                r.append([
                                    '00:00:00', row.basic_m0, row.strike_m0,
                                    row.basic_m0, row.strike_m0,
                                    row.fixed_size, row.fixed_size, 'kong', 0,
                                    0, 1000, 'run', 'skew_strd', '', '', '',
                                    '', '', bar.date
                                ])
                                r.append([
                                    '00:00:00', row.basic_m1, row.strike_m1,
                                    row.basic_m1, row.strike_m1,
                                    row.fixed_size, row.fixed_size, 'duo', 0,
                                    0, 1000, 'run', 'skew_strd', '', '', '',
                                    '', '', bar.date
                                ])
                                df.at[i, 'hold_m0'] = -1
                                df.at[i, 'hold_m1'] = 1
                                if self.engine.type == 'backtest':
                                    df.at[i, 'price_c_m0'] = s_c_m0.bar.close
                                    df.at[i, 'price_p_m0'] = s_p_m0.bar.close
                                    df.at[i, 'price_c_m1'] = s_c_m1.bar.close
                                    df.at[i, 'price_p_m1'] = s_p_m1.bar.close
                                else:
                                    df.at[i,
                                          'price_c_m0'] = s_c_m0.bar.BidPrice
                                    df.at[i,
                                          'price_p_m0'] = s_p_m0.bar.BidPrice
                                    df.at[i,
                                          'price_c_m1'] = s_c_m1.bar.AskPrice
                                    df.at[i,
                                          'price_p_m1'] = s_p_m1.bar.AskPrice

                            # 做多m0,做空m1
                            if df.at[
                                    i,
                                    'skew_max'] > row.skew_high_open and skew <= row.skew_high_open and df.at[
                                        i, 'dida_max'] > 0:
                                r.append([
                                    '00:00:00', row.basic_m0, row.strike_m0,
                                    row.basic_m0, row.strike_m0,
                                    row.fixed_size, row.fixed_size, 'duo', 0,
                                    0, 1000, 'run', 'skew_strd', '', '', '',
                                    '', '', bar.date
                                ])
                                r.append([
                                    '00:00:00', row.basic_m1, row.strike_m1,
                                    row.basic_m1, row.strike_m1,
                                    row.fixed_size, row.fixed_size, 'kong', 0,
                                    0, 1000, 'run', 'skew_strd', '', '', '',
                                    '', '', bar.date
                                ])
                                df.at[i, 'hold_m0'] = 1
                                df.at[i, 'hold_m1'] = -1
                                if self.engine.type == 'backtest':
                                    df.at[i, 'price_c_m0'] = s_c_m0.bar.close
                                    df.at[i, 'price_p_m0'] = s_p_m0.bar.close
                                    df.at[i, 'price_c_m1'] = s_c_m1.bar.close
                                    df.at[i, 'price_p_m1'] = s_p_m1.bar.close
                                else:
                                    df.at[i,
                                          'price_c_m0'] = s_c_m0.bar.AskPrice
                                    df.at[i,
                                          'price_p_m0'] = s_p_m0.bar.AskPrice
                                    df.at[i,
                                          'price_c_m1'] = s_c_m1.bar.BidPrice
                                    df.at[i,
                                          'price_p_m1'] = s_p_m1.bar.BidPrice

                            df2_straddle = pd.DataFrame(r,
                                                        columns=cols_straddle)
                            df_straddle = pd.concat(
                                [df_straddle, df2_straddle], sort=False)

                        # 获利平仓
                        elif row.hold_m0 == -1 and row.hold_m1 == 1:
                            if self.engine.type == 'backtest':
                                df.at[i, 'profit_m0'] = round(
                                    (row.price_c_m0 + row.price_p_m0) -
                                    (s_c_m0.bar.close + s_p_m0.bar.close), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (s_c_m1.bar.close + s_p_m1.bar.close) -
                                    (row.price_c_m1 + row.price_p_m1), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)
                            else:
                                df.at[i, 'profit_m0'] = round(
                                    (row.price_c_m0 + row.price_p_m0) -
                                    (s_c_m0.bar.AskPrice +
                                     s_p_m0.bar.AskPrice), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (s_c_m1.bar.BidPrice + s_p_m1.bar.BidPrice)
                                    - (row.price_c_m1 + row.price_p_m1), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)
                            # print(df.at[i, 'profit_o'])

                            if df.at[i, 'profit_o'] >= row.profit:
                                df.at[i, 'hold_m0'] = 0
                                df.at[i, 'hold_m1'] = 0
                                df.at[i, 'state'] = 'stop'
                                for j, jow in df_straddle.iterrows():
                                    if jow.basic == row.basic_m0 and jow.strike == row.strike_m0 and jow.direction == 'kong' and jow.source == 'skew_strd':
                                        df_straddle.at[j, 'profit'] = -1000
                                    if jow.basic == row.basic_m1 and jow.strike == row.strike_m1 and jow.direction == 'duo' and jow.source == 'skew_strd':
                                        df_straddle.at[j, 'profit'] = -1000

                        # 获利平仓
                        elif row.hold_m0 == 1 and row.hold_m1 == -1:
                            if self.engine.type == 'backtest':
                                df.at[i, 'profit_m0'] = round(
                                    (s_c_m0.bar.close + s_p_m0.bar.close) -
                                    (row.price_c_m0 + row.price_p_m0), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (row.price_c_m1 + row.price_p_m1) -
                                    (s_c_m1.bar.close + s_p_m1.bar.close), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)
                            else:
                                df.at[i, 'profit_m0'] = round(
                                    (s_c_m0.bar.BidPrice + s_p_m0.bar.BidPrice)
                                    - (row.price_c_m0 + row.price_p_m0), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (row.price_c_m1 + row.price_p_m1) -
                                    (s_c_m1.bar.AskPrice +
                                     s_p_m1.bar.AskPrice), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)
                            # print(df.at[i, 'profit_o'])

                            if df.at[i, 'profit_o'] >= row.profit:
                                df.at[i, 'hold_m0'] = 0
                                df.at[i, 'hold_m1'] = 0
                                df.at[i, 'state'] = 'stop'
                                for j, jow in df_straddle.iterrows():
                                    if jow.basic == row.basic_m0 and jow.strike == row.strike_m0 and jow.direction == 'duo' and jow.source == 'skew_strd':
                                        df_straddle.at[j, 'profit'] = -1000
                                    if jow.basic == row.basic_m1 and jow.strike == row.strike_m1 and jow.direction == 'kong' and jow.source == 'skew_strd':
                                        df_straddle.at[j, 'profit'] = -1000

                except Exception as e:
                    s = traceback.format_exc()
                    to_log(s)

            df_straddle.to_csv(fn_straddle, index=False)
            df.to_csv(fn, index=False)

            for symbol in symbol_got_list:
                self.got_dict[symbol] = False

    #----------------------------------------------------------------------
    def calc_iv(self, basic, flag, S0, K, C0):
        r = 0.03
        fn = get_dss() + 'fut/cfg/opt_mature.csv'
        df2 = pd.read_csv(fn)
        df2 = df2[df2.pz == df2.pz]  # 筛选出不为空的记录
        df2 = df2.set_index('symbol')
        mature_dict = dict(df2.mature)
        date_mature = mature_dict[basic]
        date_mature = datetime.strptime(date_mature, '%Y-%m-%d')
        td = datetime.now()
        T = float((date_mature - td).days) / 365  # 剩余期限

        skew = 0
        if flag == 'C':
            skew = bsm_call_imp_vol(S0, K, T, r, C0)
        if flag == 'P':
            skew = bsm_put_imp_vol(S0, K, T, r, C0)

        return skew

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)
예제 #3
0
class Fut_FollowPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'follow'

        self.symbol_o = ''
        self.symbol_c = ''
        self.symbol_p = ''

        for symbol in symbol_list:
            if symbol[:2] == 'IF':
                self.symbol_o = symbol
                break

        self.got_dict = {}
        self.strike_high = 0
        self.strike_low = 0

        self.price_o = 0
        self.price_o_high = 0
        self.price_o_low = 0

        self.price_c = 0
        self.price_p = 0

        self.hold_o = 0
        self.hold_c = 0
        self.hold_p = 0

        self.profit_o = 0
        self.profit_c = 0
        self.profit_p = 0

        self.switch_state = 'off'
        fn = get_dss() + 'fut/engine/follow/follow_switch.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            if len(df) > 0:
                rec = df.iloc[-1, :]
                if rec.state == 'on':
                    self.switch_state = 'on'

        Portfolio.__init__(self, Fut_FollowSignal, engine, symbol_list,
                           signal_param)

#----------------------------------------------------------------------

    def rec_profit(self, dt, tm, price_o, price_c, price_p, note):
        r = [[
            dt, tm, price_o, price_c, self.hold_c, self.price_c, self.profit_c,
            price_p, self.hold_p, self.price_p, self.profit_p, note, 60,
            self.profit_c + self.profit_p
        ]]
        df = pd.DataFrame(r,
                          columns=[
                              'date', 'time', 'price_o', 'price_c', 'hold_c',
                              'cost_c', 'profit_c', 'price_p', 'hold_p',
                              'cost_p', 'profit_p', 'note', 'commission',
                              'profit'
                          ])
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() + 'fut/engine/follow/portfolio_profit_' + pz + '.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)

#----------------------------------------------------------------------

    def get_open_signal(self):
        return True

#----------------------------------------------------------------------

    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        if bar.time > '09:35:00':  # 因第一根K线的价格为0
            if self.switch_state == 'on' and self.get_open_signal() == True:
                s_o = self.signalDict[self.symbol_o][0]
                self.price_o = s_o.bar.close
                self.price_o_high = 1.04 * self.price_o
                self.price_o_low = 0.96 * self.price_o

                strike_mid = int(round(self.price_o / 100, 0) * 100)
                self.strike_high = strike_mid + 300
                self.strike_low = strike_mid - 300

                self.symbol_c = 'IO' + self.symbol_o[2:6] + '-C-' + str(
                    self.strike_high)
                self.symbol_p = 'IO' + self.symbol_o[2:6] + '-P-' + str(
                    self.strike_low)

                s_c = self.signalDict[self.symbol_c][0]
                s_p = self.signalDict[self.symbol_p][0]

                if self.engine.type == 'backtest':
                    s_c.short(s_c.bar.close, 1)
                    s_p.short(s_p.bar.close, 1)
                else:
                    s_c.short(s_c.bar.BidPrice, 1)  # 挂买价
                    s_p.short(s_p.bar.BidPrice, 1)  # 挂买价

                self.got_dict[self.symbol_o] = False
                self.got_dict[self.symbol_c] = False
                self.got_dict[self.symbol_p] = False

                if self.engine.type == 'backtest':
                    self.price_c = s_c.bar.close
                    self.price_p = s_p.bar.close
                else:
                    self.price_c = s_c.bar.BidPrice
                    self.price_p = s_p.bar.BidPrice

                self.hold_c = -1
                self.hold_p = -1

                self.profit_o = self.price_c + self.price_p  # 止盈止损点
                self.switch_state = 'off'  # 不再开仓

                df2 = pd.DataFrame([{'state': 'off'}])
                fn = get_dss() + 'fut/engine/follow/follow_switch.csv'
                df2.to_csv(fn, index=False)  # 回写文件

                self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                s_c.bar.close, s_p.bar.close, '开仓')

            if self.hold_c == -1 and self.hold_p == -1:
                if self.got_dict[self.symbol_o] == True and self.got_dict[
                        self.symbol_c] == True and self.got_dict[
                            self.symbol_p] == True:
                    self.got_dict[self.symbol_o] = False
                    self.got_dict[self.symbol_c] = False
                    self.got_dict[self.symbol_p] = False

                    s_o = self.signalDict[self.symbol_o][0]
                    s_c = self.signalDict[self.symbol_c][0]
                    s_p = self.signalDict[self.symbol_p][0]

                    # 盈亏离场 或 无剩余价值离场
                    if self.profit_c + self.profit_p > 0.5 * self.profit_o or self.profit_c + self.profit_p < -0.3 * self.profit_o or abs(
                            self.hold_c * s_c.bar.close +
                            self.hold_p * s_p.bar.close) <= 3:
                        if self.engine.type == 'backtest':
                            s_c.cover(s_c.bar.close, 1)
                            s_p.cover(s_p.bar.close, 1)
                        else:
                            s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                            s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价

                        self.hold_c = 0
                        self.hold_p = 0

                        self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                        s_c.bar.close, s_p.bar.close, '清仓')

                    # 已持仓
                    elif self.hold_c == -1 or self.hold_p == -1:
                        # 上涨2% 或 离行权价小于50点时
                        if s_o.bar.close > self.price_o_high or self.strike_high - s_o.bar.close < 50:
                            if self.engine.type == 'backtest':
                                s_c.cover(s_c.bar.close, 1)
                                s_p.cover(s_p.bar.close, 1)
                            else:
                                s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                                s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价

                            if self.engine.type == 'backtest':
                                self.price_c = self.price_c - s_c.bar.close
                                self.price_p = self.price_p - s_p.bar.close
                            else:
                                self.price_c = self.price_c - s_c.bar.AskPrice
                                self.price_p = self.price_p - s_p.bar.AskPrice

                            self.hold_c = 0
                            self.hold_p = 0
                            self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                            s_c.bar.close, s_p.bar.close, '移仓')

                            self.price_o = s_o.bar.close
                            self.price_o_high = 1.04 * self.price_o
                            self.price_o_low = 0.96 * self.price_o

                            self.strike_high += 100
                            self.strike_low += 100

                            self.symbol_c = 'IO' + self.symbol_o[
                                2:6] + '-C-' + str(self.strike_high)
                            self.symbol_p = 'IO' + self.symbol_o[
                                2:6] + '-P-' + str(self.strike_low)

                            s_c = self.signalDict[self.symbol_c][0]
                            s_p = self.signalDict[self.symbol_p][0]

                            if self.engine.type == 'backtest':
                                s_c.short(s_c.bar.close, 1)
                                s_p.short(s_p.bar.close, 1)
                            else:
                                s_c.short(s_c.bar.BidPrice, 1)  # 挂买价
                                s_p.short(s_p.bar.BidPrice, 1)  # 挂买价

                            self.got_dict[self.symbol_o] = False
                            self.got_dict[self.symbol_c] = False
                            self.got_dict[self.symbol_p] = False

                            if self.engine.type == 'backtest':
                                self.price_c += s_c.bar.close
                                self.price_p += s_p.bar.close
                            else:
                                self.price_c += s_c.bar.BidPrice
                                self.price_p += s_p.bar.BidPrice

                            self.hold_c = -1
                            self.hold_p = -1
                            self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                            s_c.bar.close, s_p.bar.close, '移仓')

                        # 下跌2% 或 离行权价小于50点时
                        if s_o.bar.close < self.price_o_low or s_o.bar.close - self.strike_low < 50:
                            if self.engine.type == 'backtest':
                                s_c.cover(s_c.bar.close, 1)
                                s_p.cover(s_p.bar.close, 1)
                            else:
                                s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                                s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价

                            if self.engine.type == 'backtest':
                                self.price_c = self.price_c - s_c.bar.close
                                self.price_p = self.price_p - s_p.bar.close
                            else:
                                self.price_c = self.price_c - s_c.bar.AskPrice
                                self.price_p = self.price_p - s_p.bar.AskPrice

                            self.hold_c = 0
                            self.hold_p = 0
                            self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                            s_c.bar.close, s_p.bar.close, '移仓')

                            self.price_o = s_o.bar.close
                            self.price_o_high = 1.04 * self.price_o
                            self.price_o_low = 0.96 * self.price_o

                            self.strike_high -= 100
                            self.strike_low -= 100

                            self.symbol_c = 'IO' + self.symbol_o[
                                2:6] + '-C-' + str(self.strike_high)
                            self.symbol_p = 'IO' + self.symbol_o[
                                2:6] + '-P-' + str(self.strike_low)

                            s_c = self.signalDict[self.symbol_c][0]
                            s_p = self.signalDict[self.symbol_p][0]
                            if self.engine.type == 'backtest':
                                s_c.short(s_c.bar.close, 1)
                                s_p.short(s_p.bar.close, 1)
                            else:
                                s_c.short(s_c.bar.BidPrice, 1)  # 挂买价
                                s_p.short(s_p.bar.BidPrice, 1)  # 挂买价

                            self.got_dict[self.symbol_o] = False
                            self.got_dict[self.symbol_c] = False
                            self.got_dict[self.symbol_p] = False

                            if self.engine.type == 'backtest':
                                self.price_c += s_c.bar.close
                                self.price_p += s_p.bar.close
                            else:
                                self.price_c += s_c.bar.BidPrice
                                self.price_p += s_p.bar.BidPrice

                            self.hold_c = -1
                            self.hold_p = -1
                            self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                            s_c.bar.close, s_p.bar.close, '移仓')

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

        fn = get_dss() + 'fut/engine/follow/portfolio_follow_param.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            if len(df) > 0:
                rec = df.iloc[-1, :]  # 取最近日期的记录

                self.symbol_c = rec.symbol_c
                self.symbol_p = rec.symbol_p

                self.strike_high = rec.strike_high
                self.strike_low = rec.strike_low

                self.profit_o = rec.profit_o
                self.price_o = rec.price_o
                self.price_o_high = 1.04 * self.price_o
                self.price_o_low = 0.96 * self.price_o

                self.price_c = rec.price_c
                self.price_p = rec.price_p

                self.hold_c = rec.hold_c
                self.hold_p = rec.hold_p

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        r = [ [self.result.date, self.symbol_c, self.symbol_p, self.strike_high, self.strike_low, \
               self.profit_o, self.price_o, self.price_c, self.price_p, self.hold_c, self.hold_p] ]

        df = pd.DataFrame(r,
                          columns=[
                              'datetime', 'symbol_c', 'symbol_p',
                              'strike_high', 'strike_low', 'profit_o',
                              'price_o', 'price_c', 'price_p', 'hold_c',
                              'hold_p'
                          ])
        fn = get_dss() + 'fut/engine/follow/portfolio_follow_param.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)
예제 #4
0
class Fut_FollowPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'follow'

        assert len(symbol_list) == 3
        self.symbol_o = symbol_list[0]
        self.symbol_c = symbol_list[1]
        self.symbol_p = symbol_list[2]

        if self.symbol_o[:2] == 'IF':
            self.symbol_future = 'IO' + self.symbol_o[2:]
        else:
            self.symbol_future = self.symbol_o
        self.dual_name = self.symbol_future

        self.got_dict = {}
        self.got_dict[self.symbol_o] = False
        self.got_dict[self.symbol_c] = False
        self.got_dict[self.symbol_p] = False

        self.price_o = 0
        self.price_o_high = 0
        self.price_o_low  = 0

        self.price_c = 0
        self.price_p = 0

        self.hold_o = 0
        self.hold_c = 0
        self.hold_p = 0

        self.profit_o = 0
        self.profit_c = 0
        self.profit_p = 0

        self.flag_c, self.flag_p, self.strike_high, self.strike_low, self.fixed_size, self.switch_state, self.percent, self.gap = self.load_param(self.symbol_c, self.symbol_p)

        Portfolio.__init__(self, Fut_FollowSignal, engine, symbol_list, signal_param)

        self.name_second = 'follow_' + self.dual_name

    #----------------------------------------------------------------------
    def load_param(self, s_c, s_p):
        fn = get_dss() +  'fut/engine/follow/portfolio_follow_param.csv'
        df = pd.read_csv(fn)
        df = df[(df.symbol_c == s_c) & (df.symbol_p == s_p)]
        row = df.iloc[-1,:]

        return row.flag_c, row.flag_p, int(row.strike_high), int(row.strike_low), int(row.fixed_size), row.switch_state, float(row.percent), int(row.gap)

    #----------------------------------------------------------------------
    def set_param(self, rec):
        fn = get_dss() +  'fut/engine/follow/portfolio_follow_param.csv'
        df = pd.read_csv(fn)
        df = df[(df.symbol_c != rec[1]) & (df.symbol_p != rec[2])]
        df.to_csv(fn, index=False)

        df = pd.DataFrame([rec], columns=['symbol_o','symbol_c','symbol_p','flag_c','flag_p','strike_high','strike_low','fixed_size','switch_state','percent','gap'])
        df.to_csv(fn, index=False, mode='a', header=False)

    #----------------------------------------------------------------------
    def rec_profit(self, dt, tm, price_o, price_c, price_p, note):
        r = [[dt, tm, price_o, price_c, self.hold_c, self.price_c, self.profit_c, price_p, self.hold_p, self.price_p, self.profit_p, note, 60, self.profit_c + self.profit_p]]
        df = pd.DataFrame(r, columns=['date','time','price_o','price_c','hold_c','cost_c','profit_c','price_p','hold_p','cost_p','profit_p','note','commission','profit'])
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() +  'fut/engine/follow/portfolio_' + self.name_second + '_profit.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)


    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':               # 本策略为min1
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)

        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        if (bar.time > '09:35:00' and bar.time < '11:25:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:05:00' and bar.time < '14:55:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '09:05:00' and bar.time < '11:25:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:35:00' and bar.time < '14:55:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:05:00' and bar.time < '22:55:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0
            # 开仓
            if self.switch_state == 'on' and self.hold_c == 0 and self.hold_p == 0:
                if self.got_dict[self.symbol_o] == True and self.got_dict[self.symbol_c] == True and self.got_dict[self.symbol_p] == True:
                    self.got_dict[self.symbol_o] = False
                    self.got_dict[self.symbol_c] = False
                    self.got_dict[self.symbol_p] = False

                    s_o = self.signalDict[self.symbol_o][0]
                    s_c = self.signalDict[self.symbol_c][0]
                    s_p = self.signalDict[self.symbol_p][0]

                    self.price_o = s_o.bar.close
                    self.price_o_high = (1+self.percent) * self.price_o
                    self.price_o_low  = (1-self.percent) * self.price_o

                    if self.engine.type == 'backtest':
                        s_c.short(s_c.bar.close, self.fixed_size)
                        s_p.short(s_p.bar.close, self.fixed_size)
                    else:
                        s_c.short(s_c.bar.BidPrice, self.fixed_size)                     # 挂买价
                        s_p.short(s_p.bar.BidPrice, self.fixed_size)                     # 挂买价

                    if self.engine.type == 'backtest':
                        self.price_c = s_c.bar.close
                        self.price_p = s_p.bar.close
                    else:
                        self.price_c = s_c.bar.BidPrice
                        self.price_p = s_p.bar.BidPrice

                    self.hold_c = -1
                    self.hold_p = -1

                    self.profit_o = self.price_c + self.price_p          # 止盈止损点
                    self.switch_state = 'off'                            # 不再开仓
                    self.set_param([self.symbol_o,self.symbol_c,self.symbol_p,self.flag_c,self.flag_p,self.strike_high,self.strike_low,self.fixed_size,self.switch_state,self.percent,self.gap])

                    self.rec_profit(bar.date, bar.time, s_o.bar.close, s_c.bar.close, s_p.bar.close, '开仓')

            if self.hold_c == -1 and self.hold_p == -1 :
                if self.got_dict[self.symbol_o] == True and self.got_dict[self.symbol_c] == True and self.got_dict[self.symbol_p] == True:
                    s_o = self.signalDict[self.symbol_o][0]
                    s_c = self.signalDict[self.symbol_c][0]
                    s_p = self.signalDict[self.symbol_p][0]

                    # 盈亏离场 或 无剩余价值离场
                    if self.profit_c + self.profit_p > 0.5*self.profit_o or self.profit_c + self.profit_p < -0.3*self.profit_o or abs(s_c.bar.close + s_p.bar.close) <= 3:
                        if self.engine.type == 'backtest':
                            s_c.cover(s_c.bar.close, self.fixed_size)
                            s_p.cover(s_p.bar.close, self.fixed_size)
                        else:
                            s_c.cover(s_c.bar.AskPrice, self.fixed_size)           # 挂卖价
                            s_p.cover(s_p.bar.AskPrice, self.fixed_size)           # 挂卖价

                        self.hold_c = 0
                        self.hold_p = 0

                        self.rec_profit(bar.date, bar.time, s_o.bar.close, s_c.bar.close, s_p.bar.close, '清仓')

                    # 已持仓
                    elif self.hold_c == -1 or self.hold_p == -1:
                        # 上涨4% 或 离行权价小于50点时
                        if s_o.bar.close > self.price_o_high or self.strike_high - s_o.bar.close < self.gap:
                            if self.engine.type == 'backtest':
                                s_c.cover(s_c.bar.close, self.fixed_size)
                                s_p.cover(s_p.bar.close, self.fixed_size)
                            else:
                                s_c.cover(s_c.bar.AskPrice, self.fixed_size)           # 挂卖价
                                s_p.cover(s_p.bar.AskPrice, self.fixed_size)           # 挂卖价

                            if self.engine.type == 'backtest':
                                self.price_c = self.price_c - s_c.bar.close
                                self.price_p = self.price_p - s_p.bar.close
                            else:
                                self.price_c = self.price_c - s_c.bar.AskPrice
                                self.price_p = self.price_p - s_p.bar.AskPrice

                            self.hold_c = 0
                            self.hold_p = 0
                            self.rec_profit(bar.date, bar.time, s_o.bar.close, s_c.bar.close, s_p.bar.close, '移仓')

                            self.price_o = s_o.bar.close
                            self.price_o_high = (1+self.percent) * self.price_o
                            self.price_o_low  = (1-self.percent) * self.price_o

                            self.strike_high += 2*self.gap
                            self.strike_low  += 2*self.gap

                            self.symbol_c = self.symbol_future + self.flag_c + str(self.strike_high)
                            self.symbol_p = self.symbol_future + self.flag_p + str(self.strike_low)

                            self.set_param([self.symbol_o,self.symbol_c,self.symbol_p,self.flag_c,self.flag_p,self.strike_high,self.strike_low,self.fixed_size,self.switch_state,self.percent,self.gap])
                            self.switch_state = 'on'
                            self.vtSymbolList = [self.symbol_o,self.symbol_c,self.symbol_p]
                            for s in [self.symbol_c,self.symbol_p]:
                                self.posDict[s] = 0
                                signal1 = Fut_FollowSignal(self, s)
                                l = self.signalDict[s]
                                l.append(signal1)

                        # 下跌4% 或 离行权价小于50点时
                    elif s_o.bar.close < self.price_o_low or s_o.bar.close - self.strike_low < self.gap:
                            if self.engine.type == 'backtest':
                                s_c.cover(s_c.bar.close, self.fixed_size)
                                s_p.cover(s_p.bar.close, self.fixed_size)
                            else:
                                s_c.cover(s_c.bar.AskPrice, self.fixed_size)           # 挂卖价
                                s_p.cover(s_p.bar.AskPrice, self.fixed_size)           # 挂卖价

                            if self.engine.type == 'backtest':
                                self.price_c = self.price_c - s_c.bar.close
                                self.price_p = self.price_p - s_p.bar.close
                            else:
                                self.price_c = self.price_c - s_c.bar.AskPrice
                                self.price_p = self.price_p - s_p.bar.AskPrice

                            self.hold_c = 0
                            self.hold_p = 0
                            self.rec_profit(bar.date, bar.time, s_o.bar.close, s_c.bar.close, s_p.bar.close, '移仓')

                            self.price_o = s_o.bar.close
                            self.price_o_high = (1+self.percent) * self.price_o
                            self.price_o_low  = (1-self.percent) * self.price_o

                            self.strike_high -= 2*self.gap
                            self.strike_low  -= 2*self.gap

                            self.symbol_c = self.symbol_future + self.flag_c + str(self.strike_high)
                            self.symbol_p = self.symbol_future + self.flag_p + str(self.strike_low)

                            self.set_param([self.symbol_o,self.symbol_c,self.symbol_p,self.flag_c,self.flag_p,self.strike_high,self.strike_low,self.fixed_size,self.switch_state,self.percent,self.gap])
                            self.switch_state = 'on'
                            self.vtSymbolList = [self.symbol_o,self.symbol_c,self.symbol_p]
                            for s in [self.symbol_c, self.symbol_p]:
                                self.posDict[s] = 0
                                signal1 = Fut_FollowSignal(self, s)
                                l = self.signalDict[s]
                                l.append(signal1)

                    self.got_dict[self.symbol_o] = False
                    self.got_dict[self.symbol_c] = False
                    self.got_dict[self.symbol_p] = False

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

        fn = get_dss() +  'fut/engine/follow/portfolio_' + self.name_second + '_save.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            if len(df) > 0:
                rec = df.iloc[-1,:]            # 取最近日期的记录

                self.profit_o = rec.profit_o
                self.price_o = rec.price_o
                self.price_o_high = (1+self.percent) * self.price_o
                self.price_o_low  = (1-self.percent) * self.price_o

                self.price_c = rec.price_c
                self.price_p = rec.price_p

                self.hold_c = rec.hold_c
                self.hold_p = rec.hold_p

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        r = [ [self.result.date, self.profit_o, self.price_o, self.price_c, self.price_p, self.hold_c, self.hold_p] ]

        df = pd.DataFrame(r, columns=['datetime', 'profit_o','price_o', 'price_c', 'price_p', 'hold_c', 'hold_p'])
        fn = get_dss() +  'fut/engine/follow/portfolio_' + self.name_second + '_save.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)
예제 #5
0
class Fut_Skew_BiliPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'skew_bili'
        self.tm = '00:00:00'
        self.got_dict = {}
        for symbol in symbol_list:
            self.got_dict[symbol] = False

        # self.d_base_dict = {}

        Portfolio.__init__(self, Fut_Skew_BiliSignal, engine, symbol_list,
                           signal_param)

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.tm != bar.time:
            self.tm = bar.time
            for symbol in self.vtSymbolList:
                self.got_dict[symbol] = False

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        # print('here')
        self.control_in_p(bar)
        # print('here3')

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def control_in_p(self, bar):
        if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0

            fn = get_dss(
            ) + 'fut/engine/skew_bili/portfolio_skew_bili_param.csv'
            cols_ratio = [
                'tm', 'symbol_b', 'symbol_s', 'num_b', 'num_s', 'gap',
                'profit', 'hold_b', 'hold_s', 'state', 'source', 'price_b',
                'price_s', 'gap_open', 'profit_b', 'profit_s', 'profit_o',
                'date', 'delta', 'theta'
            ]
            fn_ratio = get_dss() + 'fut/engine/ratio/portfolio_ratio_param.csv'

            df = pd.read_csv(fn)
            df_ratio = pd.read_csv(fn_ratio)
            symbol_got_list = []

            for i, row in df.iterrows():
                try:
                    r = []
                    if row.state == 'stop':
                        continue

                    basic_b = get_contract(row.symbol_b).basic
                    basic_s = get_contract(row.symbol_s).basic

                    if basic_b[:2] == 'IO':
                        symbol_obj = 'IF' + basic_b[2:]
                    else:
                        symbol_obj = basic_b

                    if symbol_obj not in self.got_dict or row.symbol_b not in self.got_dict or row.symbol_s not in self.got_dict:
                        continue

                    if self.got_dict[symbol_obj] == False or self.got_dict[
                            row.symbol_b] == False or self.got_dict[
                                row.symbol_s] == False:
                        continue
                    else:
                        symbol_got_list.append(symbol_obj)
                        symbol_got_list.append(row.symbol_b)
                        symbol_got_list.append(row.symbol_s)

                        s_obj = self.signalDict[symbol_obj][0]
                        s_b = self.signalDict[row.symbol_b][0]
                        s_s = self.signalDict[row.symbol_s][0]

                        df.at[i, 'tm'] = bar.time

                        # 开仓
                        if row.hold_b == 0 and row.hold_s == 0:
                            opt_flag = get_contract(row.symbol_b).opt_flag
                            strike_b = get_contract(row.symbol_b).strike
                            strike_s = get_contract(row.symbol_s).strike
                            if opt_flag == 'C':
                                iv_b = self.calc_iv(basic_b, 'C',
                                                    s_obj.bar.close, strike_b,
                                                    s_b.bar.close)
                                iv_s = self.calc_iv(basic_s, 'C',
                                                    s_obj.bar.close, strike_s,
                                                    s_s.bar.close)
                            else:
                                iv_b = self.calc_iv(basic_b, 'P',
                                                    s_obj.bar.close, strike_b,
                                                    s_b.bar.close)
                                iv_s = self.calc_iv(basic_s, 'P',
                                                    s_obj.bar.close, strike_s,
                                                    s_s.bar.close)
                            skew = round(100 * (iv_s / iv_b - 1), 2)
                            print(skew)

                            if skew > row.skew_max:
                                df.at[i, 'skew_max'] = skew
                                df.at[i, 'dida_max'] = 0
                            else:
                                df.at[i, 'dida_max'] = row.dida_max + 1
                                # print(df.at[i, 'dida_max'], row.dida_max)

                            if skew < row.skew_min:
                                df.at[i, 'skew_min'] = skew
                                df.at[i, 'dida_min'] = 0
                            else:
                                df.at[i, 'dida_min'] = row.dida_min + 1

                            # 做多symbol_s,做空symbol_b
                            if df.at[
                                    i,
                                    'skew_min'] < row.skew_low_open and skew >= row.skew_low_open and df.at[
                                        i, 'dida_min'] > 0:
                                r.append([
                                    '00:00:00', row.symbol_s, row.symbol_b,
                                    row.num_s, row.num_b, -1000, row.profit, 0,
                                    0, 'run', 'skew_bili', 0.0, 0.0, 0.0, 0.0,
                                    0.0, 0.0, bar.date, 0.0, 0.0
                                ])
                                df.at[i, 'hold_b'] = -row.num_b
                                df.at[i, 'hold_s'] = row.num_s
                                if self.engine.type == 'backtest':
                                    df.at[i, 'price_b'] = s_b.bar.close
                                    df.at[i, 'price_s'] = s_s.bar.close
                                else:
                                    df.at[i, 'price_b'] = s_b.bar.BidPrice
                                    df.at[i, 'price_s'] = s_s.bar.AskPrice

                            # 做多symbol_b,做空symbol_s
                            if df.at[
                                    i,
                                    'skew_max'] > row.skew_high_open and skew <= row.skew_high_open and df.at[
                                        i, 'dida_max'] > 0:
                                r.append([
                                    '00:00:00', row.symbol_b, row.symbol_s,
                                    row.num_b, row.num_s, -1000, row.profit, 0,
                                    0, 'run', 'skew_bili', 0.0, 0.0, 0.0, 0.0,
                                    0.0, 0.0, bar.date, 0.0, 0.0
                                ])
                                df.at[i, 'hold_b'] = row.num_b
                                df.at[i, 'hold_s'] = -row.num_s
                                if self.engine.type == 'backtest':
                                    df.at[i, 'price_b'] = s_b.bar.close
                                    df.at[i, 'price_s'] = s_s.bar.close
                                else:
                                    df.at[i, 'price_b'] = s_b.bar.AskPrice
                                    df.at[i, 'price_s'] = s_s.bar.BidPrice

                            df2_ratio = pd.DataFrame(r, columns=cols_ratio)
                            df_ratio = pd.concat([df_ratio, df2_ratio],
                                                 sort=False)

                        # 获利平仓
                        elif row.hold_b <= -1 and row.hold_s >= 1:
                            if self.engine.type == 'backtest':
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.close - row.price_b) * row.hold_b,
                                    2)
                                df.at[i, 'profit_s'] = round(
                                    (s_s.bar.close - row.price_s) * row.hold_s,
                                    2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)
                            else:
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.AskPrice - row.price_b) *
                                    row.hold_b, 2)
                                df.at[i, 'profit_s'] = round(
                                    (s_s.bar.BidPrice - row.price_s) *
                                    row.hold_s, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)
                            # print(df.at[i, 'profit_o'])

                            if df.at[i, 'profit_o'] >= row.profit:
                                df.at[i, 'hold_m0'] = 0
                                df.at[i, 'hold_m1'] = 0
                                df.at[i, 'state'] = 'stop'
                                for j, jow in df_ratio.iterrows():
                                    if jow.symbol_b == row.symbol_s and jow.symbol_s == row.symbol_b and jow.num_b == row.num_s and jow.num_s == row.num_b and jow.source == 'skew_bili':
                                        df_ratio.at[j, 'profit'] = -1000

                        # 获利平仓
                        elif row.hold_b >= 1 and row.hold_s <= -1:
                            if self.engine.type == 'backtest':
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.close - row.price_b) * row.hold_b,
                                    2)
                                df.at[i, 'profit_s'] = round(
                                    (s_s.bar.close - row.price_s) * row.hold_s,
                                    2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)
                            else:
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.BidPrice - row.price_b) *
                                    row.hold_b, 2)
                                df.at[i, 'profit_s'] = round(
                                    (s_s.bar.AskPrice - row.price_s) *
                                    row.hold_s, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)
                            # print(df.at[i, 'profit_o'])

                            if df.at[i, 'profit_o'] >= row.profit:
                                df.at[i, 'hold_b'] = 0
                                df.at[i, 'hold_s'] = 0
                                df.at[i, 'state'] = 'stop'
                                for j, jow in df_ratio.iterrows():
                                    if jow.symbol_b == row.symbol_b and jow.symbol_s == row.symbol_s and jow.num_b == row.num_b and jow.num_s == row.num_s and jow.source == 'skew_bili':
                                        df_ratio.at[j, 'profit'] = -1000

                except Exception as e:
                    s = traceback.format_exc()
                    to_log(s)

            df_ratio.to_csv(fn_ratio, index=False)
            df.to_csv(fn, index=False)

            for symbol in symbol_got_list:
                self.got_dict[symbol] = False

    #----------------------------------------------------------------------
    def calc_iv(self, basic, flag, S0, K, C0):
        r = 0.03
        fn = get_dss() + 'fut/cfg/opt_mature.csv'
        df2 = pd.read_csv(fn)
        df2 = df2[df2.pz == df2.pz]  # 筛选出不为空的记录
        df2 = df2.set_index('symbol')
        mature_dict = dict(df2.mature)
        date_mature = mature_dict[basic]
        date_mature = datetime.strptime(date_mature, '%Y-%m-%d')
        td = datetime.now()
        T = float((date_mature - td).days) / 365  # 剩余期限

        skew = 0
        if flag == 'C':
            skew = bsm_call_imp_vol(S0, K, T, r, C0)
        if flag == 'P':
            skew = bsm_put_imp_vol(S0, K, T, r, C0)

        return skew

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)
예제 #6
0
class Fut_SwapPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'swap'

        self.symbol_o = ''
        self.symbol_a = ''
        for symbol in symbol_list:
            if len(symbol) == 6:
                self.symbol_o = symbol
                break
        assert self.symbol_o != ''

        self.got_dict = {}

        self.price_o = 0
        self.price_a = 0

        self.hold_o = 0
        self.hold_a = 0

        self.profit_o = 0
        self.profit_a = 0

        self.can_duo = False
        self.can_kong = False

        self.switch_state = 'on'
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() + 'fut/engine/swap/swap_switch_' + pz + '.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            if len(df) > 0:
                rec = df.iloc[-1, :]
                if rec.state == 'off':
                    self.switch_state = 'off'

        Portfolio.__init__(self, Fut_SwapSignal, engine, symbol_list,
                           signal_param)

    #----------------------------------------------------------------------
    def rec_profit(self, dt, tm, price_o, price_c, price_p, note):
        r = [[
            dt, tm, price_o, price_c, self.hold_c, self.price_c, self.profit_c,
            price_p, self.hold_p, self.price_p, self.profit_p, note, 60,
            self.profit_c + self.profit_p
        ]]
        df = pd.DataFrame(r,
                          columns=[
                              'date', 'time', 'price_o', 'price_c', 'hold_c',
                              'cost_c', 'profit_c', 'price_p', 'hold_p',
                              'cost_p', 'profit_p', 'note', 'commission',
                              'profit'
                          ])
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() + 'fut/engine/swap/portfolio_profit_' + pz + '.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)

    #----------------------------------------------------------------------
    def got_all_bar(self):
        for symbol in self.vtSymbolList:
            if symbol not in self.got_dict:
                return False
            if self.got_dict[symbol] == False:
                return False

        for symbol in self.vtSymbolList:
            self.got_dict[symbol] = False

        return True

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""
        # 策略未启用
        if self.switch_state == 'off':
            return

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min30':  # 本策略为min30
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """

        if bar.time > '09:35:00' and self.got_all_bar() == True:
            s_o = self.signalDict[self.symbol_o][0]

            # 做多
            if self.can_duo == True:
                if self.hold_a == -1:
                    s_a = self.signalDict[self.symbol_a][0]
                    s_a.cover(s_a.bar.close, 1)
                    # s_a.cover(s_a.bar.AskPrice, 1)                  # 挂卖价
                    self.hold_a = 0
                    self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                    s_c.bar.close, s_p.bar.close, '平仓')

                strike = int(round((self.price_o - 150) / 100, 0) * 100)
                self.symbol_a = 'IO' + self.symbol_o[2:6] + '-P-' + str(strike)
                s_a = self.signalDict[self.symbol_a][0]
                s_a.short(s_a.bar.close, 1)
                # s_a.short(s_a.bar.BidPrice, 1)                  # 挂买价

                self.price_o = s_o.bar.close
                self.price_a = s_a.bar.close
                # self.price_a = s_a.bar.BidPrice

                self.hold_a = -1
                self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                s_c.bar.close, s_p.bar.close, '做多开仓')

                self.can_duo = False

            # 做空
            elif self.can_kong == True:
                if self.hold_a == -1:
                    s_a = self.signalDict[self.symbol_a][0]
                    s_a.cover(s_a.bar.close, 1)
                    # s_a.cover(s_a.bar.AskPrice, 1)                  # 挂卖价
                    self.hold_a = 0
                    self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                    s_c.bar.close, s_p.bar.close, '平仓')

                strike = int(round((self.price_o + 150) / 100, 0) * 100)
                self.symbol_a = 'IO' + self.symbol_o[2:6] + '-C-' + str(strike)
                s_a = self.signalDict[self.symbol_a][0]
                s_a.short(s_a.bar.close, 1)
                # s_a.short(s_a.bar.BidPrice, 1)                      # 挂买价

                self.price_o = s_o.bar.close
                self.price_a = s_a.bar.close
                # self.price_a = s_a.bar.BidPrice

                self.hold_a = -1
                self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                s_c.bar.close, s_p.bar.close, '做空开仓')

                self.can_kong = False

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)
예제 #7
0
class Fut_AvengerPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'avenger'

        assert len(symbol_list) == 3
        self.symbol_o = symbol_list[0]
        self.symbol_c = symbol_list[1]
        self.symbol_p = symbol_list[2]

        self.got_dict = {}
        self.got_dict[self.symbol_o] = False
        self.got_dict[self.symbol_c] = False
        self.got_dict[self.symbol_p] = False

        self.price_o = 0
        self.price_o_high = 0
        self.price_o_low = 0

        self.price_c = 0
        self.price_p = 0

        self.hold_o = 0
        self.hold_c = 0
        self.hold_p = 0

        self.profit_o = 0
        self.profit_c = 0
        self.profit_p = 0

        self.switch_state = 'off'
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() + 'fut/engine/avenger/avenger_switch_' + pz + '.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            if len(df) > 0:
                rec = df.iloc[-1, :]
                if rec.state == 'on':
                    self.switch_state = 'on'
                    rec.state = 'off'
                    df2 = pd.DataFrame([rec])
                    df2.to_csv(fn, index=False)  # 回写文件

        Portfolio.__init__(self, Fut_AvengerSignal, engine, symbol_list,
                           signal_param)

    #----------------------------------------------------------------------
    def rec_profit(self, dt, tm, price_o, price_c, price_p, note):
        r = [[
            dt, tm, price_o, price_c, self.hold_c, self.price_c, self.profit_c,
            price_p, self.hold_p, self.price_p, self.profit_p, note, 60,
            self.profit_c + self.profit_p
        ]]
        df = pd.DataFrame(r,
                          columns=[
                              'date', 'time', 'price_o', 'price_c', 'hold_c',
                              'cost_c', 'profit_c', 'price_p', 'hold_p',
                              'cost_p', 'profit_p', 'note', 'commission',
                              'profit'
                          ])
        pz = str(get_contract(self.symbol_c).pz)
        fn = get_dss() + 'fut/engine/avenger/portfolio_profit_' + pz + '.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """

        if bar.time > '09:35:00' and self.got_dict[
                self.symbol_o] == True and self.got_dict[
                    self.symbol_c] == True and self.got_dict[
                        self.symbol_p] == True:
            s_o = self.signalDict[self.symbol_o][0]
            s_c = self.signalDict[self.symbol_c][0]
            s_p = self.signalDict[self.symbol_p][0]

            # 开仓
            if self.switch_state == 'on':
                s_c.short(s_c.bar.BidPrice, 1)  # 挂买价
                s_p.short(s_p.bar.BidPrice, 1)  # 挂买价

                self.price_o = s_o.bar.close
                self.price_o_high = 1.01 * self.price_o
                self.price_o_low = 0.99 * self.price_o

                self.price_c = s_c.bar.BidPrice
                self.price_p = s_p.bar.BidPrice

                self.hold_c = -1
                self.hold_p = -1

                self.profit_o = self.price_c + self.price_p  # 止盈止损点
                self.switch_state = 'off'  # 不再开仓

                self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                s_c.bar.close, s_p.bar.close, '开仓')

            # 已持仓
            elif self.hold_c != 0 or self.hold_p != 0:
                # 盈亏离场 或 无剩余价值离场
                if abs(self.profit_c +
                       self.profit_p) > 0.5 * self.profit_o or abs(
                           self.hold_c * s_c.bar.close +
                           self.hold_p * s_p.bar.close) <= 3:
                    if self.hold_c == -1 and self.hold_p == -1:
                        s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                        s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价
                        self.hold_c = 0
                        self.hold_p = 0
                    if self.hold_c == 0 and self.hold_p == -2:
                        s_p.cover(s_p.bar.AskPrice, 2)  # 挂卖价
                        self.hold_p = 0
                    if self.hold_c == -2 and self.hold_p == 0:
                        s_c.cover(s_c.bar.AskPrice, 2)  # 挂卖价
                        self.hold_c = 0

                    self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                    s_c.bar.close, s_p.bar.close, '清仓')

                # 复仇
                if self.hold_c == -1 and self.hold_p == -1:
                    # 上涨1%
                    if s_o.bar.close > self.price_o_high:
                        s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                        s_p.short(s_p.bar.BidPrice, 1)  # 挂买价

                        self.price_c = self.price_c - s_c.bar.AskPrice
                        self.price_p = (s_p.bar.BidPrice + self.price_p) / 2
                        self.hold_c = 0
                        self.hold_p = -2

                        self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                        s_c.bar.close, s_p.bar.close, '上涨复仇')

                    # 下跌1%
                    if s_o.bar.close < self.price_o_low:
                        s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价
                        s_c.short(s_c.bar.BidPrice, 1)  # 挂买价

                        self.price_p = self.price_p - s_p.bar.AskPrice
                        self.price_c = (s_c.bar.BidPrice + self.price_c) / 2
                        self.hold_p = 0
                        self.hold_c = -2

                        self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                        s_c.bar.close, s_p.bar.close, '下跌复仇')

                # 复仇失败,上涨后又回原点
                if self.hold_c == 0 and self.hold_p == -2 and s_o.bar.close < self.price_o:
                    s_c.short(s_c.bar.BidPrice, 1)  # 挂买价
                    s_p.cover(s_p.bar.AskPrice, 1)  # 挂卖价

                    self.price_c = s_c.bar.BidPrice + self.price_c
                    self.price_p = 2 * self.price_p - s_p.bar.AskPrice
                    self.hold_p = -1
                    self.hold_c = -1
                    self.profit_c = self.hold_c * (s_c.bar.close -
                                                   self.price_c)

                    self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                    s_c.bar.close, s_p.bar.close, '复仇失败')

                # 复仇失败,下跌后又回原点
                if self.hold_c == -2 and self.hold_p == 0 and s_o.bar.close > self.price_o:
                    s_p.short(s_p.bar.BidPrice, 1)  # 挂买价
                    s_c.cover(s_c.bar.AskPrice, 1)  # 挂卖价
                    self.price_p = s_p.bar.BidPrice + self.price_p
                    self.price_c = 2 * self.price_c - s_c.bar.AskPrice
                    self.hold_p = -1
                    self.hold_c = -1
                    self.profit_p = self.hold_p * (s_p.bar.close -
                                                   self.price_p)

                    self.rec_profit(bar.date, bar.time, s_o.bar.close,
                                    s_c.bar.close, s_p.bar.close, '复仇失败')

            self.got_dict[self.symbol_o] = False
            self.got_dict[self.symbol_c] = False
            self.got_dict[self.symbol_p] = False

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)
예제 #8
0
class Fut_SdifferPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'sdiffer'
        self.tm = '00:00:00'
        self.got_dict = {}
        for symbol in symbol_list:
            self.got_dict[symbol] = False

        self.be_run = 'stop'
        self.d_low_open = -100.0
        self.d_high_open = 100.0
        self.d_low_mail = -100.0
        self.d_high_mail = 100.0
        self.mailed_low = False
        self.mailed_high = False
        self.load_switch()

        self.stop = False
        self.basic_m0 = None
        self.basic_m1 = None
        self.cacl_vars()

        self.symbol_obj = None
        self.d_base_dict = {}

        Portfolio.__init__(self, Fut_SdifferSignal, engine, symbol_list,
                           signal_param)

    #----------------------------------------------------------------------
    def load_switch(self):
        pass
        fn = get_dss() + 'fut/engine/sdiffer/portfolio_sdiffer_switch.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            rec = df.iloc[0]
            self.be_run = rec.be_run
            self.d_low_open = rec.d_low_open
            self.d_high_open = rec.d_high_open
            self.d_low_mail = rec.d_low_mail
            self.d_high_mail = rec.d_high_mail
            # print(self.be_run, self.d_low_open, self.d_high_open)

    #----------------------------------------------------------------------
    def cacl_vars(self):
        now = datetime.now()
        next_day = now + timedelta(days=10)
        next_day = next_day.strftime('%Y-%m-%d')

        fn = get_dss() + 'fut/cfg/opt_mature.csv'
        df_opt = pd.read_csv(fn)

        df = df_opt[(df_opt.pz == 'IO') & (df_opt.flag == 'm0')]
        self.basic_m0 = df.iat[0, 1]
        mature = df.iat[0, 2]

        df = df_opt[(df_opt.pz == 'IO') & (df_opt.flag == 'm1')]
        self.basic_m1 = df.iat[0, 1]

        if next_day >= mature:
            self.stop = True

        # fn = get_dss() + 'opt/straddle_differ.csv'
        # df = pd.read_csv(fn)
        # df = df[(df.basic_m0 == self.basic_m0) & (df.basic_m1 == self.basic_m1) & (df.stat == 'y')]
        # if len(df) >= 480:
        #     df = df.iloc[-480:, :]
        #     self.per_10 = df.differ.quantile(0.01)
        #     self.per_50 = df.differ.quantile(0.5)
        #     self.per_90 = df.differ.quantile(0.99)
        # else:
        #     self.per_10 = -100
        #     self.per_50 = 0
        #     self.per_90 = 100

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.tm != bar.time:
            self.tm = bar.time
            for symbol in self.vtSymbolList:
                self.got_dict[symbol] = False

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        # print('here')
        self.control_in_p(bar)
        # print('here3')

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def control_in_p(self, bar):
        if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0

            cols = [
                'date', 'basic_m0', 'basic_m1', 'strike', 'fixed_size',
                'hold_m0', 'hold_m1', 'price_c_m0', 'price_p_m0', 'price_c_m1',
                'price_p_m1', 'd_low_open', 'd_high_open', 'd_max', 'dida_max',
                'd_min', 'dida_min', 'profit', 'state', 'source', 'profit_m0',
                'profit_m1', 'profit_o'
            ]
            fn = get_dss() + 'fut/engine/sdiffer/portfolio_sdiffer_param.csv'
            # while get_file_lock(fn) == False:
            #     time.sleep(0.01)

            cols_straddle = [
                'tm', 'basic_c', 'strike_c', 'basic_p', 'strike_p', 'num_c',
                'num_p', 'direction', 'hold_c', 'hold_p', 'profit', 'state',
                'source', 'price_c', 'price_p', 'profit_c', 'profit_p',
                'profit_o', 'date'
            ]
            fn_straddle = get_dss(
            ) + 'fut/engine/straddle/portfolio_straddle_param.csv'
            # while get_file_lock(fn_straddle) == False:
            #     time.sleep(0.01)

            df = pd.read_csv(fn)
            df_straddle = pd.read_csv(fn_straddle)
            symbol_got_list = []

            # 先确定当日要交易的合约,生成当日交易记录
            if self.symbol_obj is None:
                try:
                    temp1 = 'IF' + self.basic_m0[2:]
                    # print(temp1)
                    if self.got_dict[temp1]:
                        self.symbol_obj = temp1

                        # 临近到期日,暂停自动交易,否则,发出条件单
                        if self.stop == False:
                            s_obj = self.signalDict[self.symbol_obj][0]
                            obj = s_obj.bar.close
                            gap = 50
                            atm = int(
                                round(
                                    round(obj * (100 / gap) / 1E4, 2) * 1E4 /
                                    (100 / gap), 0))  # 获得平值
                            r = [[bar.date, self.basic_m0, self.basic_m1, atm, 1, \
                                  0, 0, '','','','', \
                                  self.d_low_open, self.d_high_open, 0.0,0,0.0,0, \
                                  13,self.be_run,'sdiffer','','',''] ]
                            df2 = pd.DataFrame(r, columns=cols)
                            df = pd.concat([df, df2], sort=False)
                            # print(df)
                except Exception as e:
                    s = traceback.format_exc()
                    to_log(s)
            else:
                for i, row in df.iterrows():
                    try:
                        r = []
                        if row.state == 'stop':
                            continue

                        symbol_c_m0 = row.basic_m0 + '-C-' + str(row.strike)
                        symbol_p_m0 = row.basic_m0 + '-P-' + str(row.strike)
                        symbol_c_m1 = row.basic_m1 + '-C-' + str(row.strike)
                        symbol_p_m1 = row.basic_m1 + '-P-' + str(row.strike)

                        if symbol_c_m0 not in self.got_dict or symbol_p_m0 not in self.got_dict or symbol_c_m1 not in self.got_dict or symbol_p_m1 not in self.got_dict:
                            continue

                        if self.got_dict[symbol_c_m0] == False or self.got_dict[
                                symbol_p_m0] == False or self.got_dict[
                                    symbol_c_m1] == False or self.got_dict[
                                        symbol_p_m1] == False:
                            continue
                        else:
                            symbol_got_list.append(symbol_c_m0)
                            symbol_got_list.append(symbol_p_m0)
                            symbol_got_list.append(symbol_c_m1)
                            symbol_got_list.append(symbol_p_m1)

                            s_c_m0 = self.signalDict[symbol_c_m0][0]
                            s_p_m0 = self.signalDict[symbol_p_m0][0]
                            s_c_m1 = self.signalDict[symbol_c_m1][0]
                            s_p_m1 = self.signalDict[symbol_p_m1][0]

                            d_base_m0 = self.d_base_dict[row.basic_m0 + '_' +
                                                         str(row.strike)]
                            d_base_m1 = self.d_base_dict[row.basic_m1 + '_' +
                                                         str(row.strike)]

                            # 开仓
                            if row.hold_m0 == 0 and row.hold_m1 == 0:
                                diff_m0 = 0.5 * (
                                    s_c_m0.bar.AskPrice + s_c_m0.bar.BidPrice
                                ) + 0.5 * (s_p_m0.bar.AskPrice +
                                           s_p_m0.bar.BidPrice) - d_base_m0
                                diff_m1 = 0.5 * (
                                    s_c_m1.bar.AskPrice + s_c_m1.bar.BidPrice
                                ) + 0.5 * (s_p_m1.bar.AskPrice +
                                           s_p_m1.bar.BidPrice) - d_base_m1
                                differ = diff_m1 - diff_m0
                                print('differ: ', differ)

                                if differ <= self.d_low_mail and self.mailed_low == False:
                                    self.mailed_low = True
                                    send_email(get_dss(),
                                               'differ: ' + str(differ), '')

                                if differ >= self.d_high_mail and self.mailed_high == False:
                                    self.mailed_high = True
                                    send_email(get_dss(),
                                               'differ: ' + str(differ), '')

                                if differ >= row.d_max:
                                    df.at[i, 'd_max'] = differ
                                    df.at[i, 'dida_max'] = 0
                                else:
                                    df.at[i, 'dida_max'] = row.dida_max + 1
                                    # print(df.at[i, 'dida_max'], row.dida_max)

                                if differ <= row.d_min:
                                    df.at[i, 'd_min'] = differ
                                    df.at[i, 'dida_min'] = 0
                                else:
                                    df.at[i, 'dida_min'] = row.dida_min + 1
                                    # print(df.at[i, 'dida_min'], row.dida_min)

                                # 做多
                                # if differ < 9:
                                if df.at[
                                        i,
                                        'd_min'] <= row.d_low_open and differ >= row.d_low_open and df.at[
                                            i, 'dida_min'] > 0:
                                    r.append([
                                        '00:00:00', row.basic_m0, row.strike,
                                        row.basic_m0, row.strike, 1, 1, 'kong',
                                        0, 0, 1000, 'run', 'sdiffer', '', '',
                                        '', '', '', bar.date
                                    ])
                                    r.append([
                                        '00:00:00', row.basic_m1, row.strike,
                                        row.basic_m1, row.strike, 1, 1, 'duo',
                                        0, 0, 1000, 'run', 'sdiffer', '', '',
                                        '', '', '', bar.date
                                    ])
                                    df.at[i, 'hold_m0'] = -1
                                    df.at[i, 'hold_m1'] = 1
                                    df.at[i,
                                          'price_c_m0'] = s_c_m0.bar.BidPrice
                                    df.at[i,
                                          'price_p_m0'] = s_p_m0.bar.BidPrice
                                    df.at[i,
                                          'price_c_m1'] = s_c_m1.bar.AskPrice
                                    df.at[i,
                                          'price_p_m1'] = s_p_m1.bar.AskPrice

                                # 做空
                                # if differ > 9:
                                if df.at[
                                        i,
                                        'd_max'] >= row.d_high_open and differ <= row.d_high_open and df.at[
                                            i, 'dida_max'] > 0:
                                    r.append([
                                        '00:00:00', row.basic_m1, row.strike,
                                        row.basic_m1, row.strike, 1, 1, 'kong',
                                        0, 0, 1000, 'run', 'sdiffer', '', '',
                                        '', '', '', bar.date
                                    ])
                                    r.append([
                                        '00:00:00', row.basic_m0, row.strike,
                                        row.basic_m0, row.strike, 1, 1, 'duo',
                                        0, 0, 1000, 'run', 'sdiffer', '', '',
                                        '', '', '', bar.date
                                    ])
                                    df.at[i, 'hold_m0'] = 1
                                    df.at[i, 'hold_m1'] = -1
                                    df.at[i,
                                          'price_c_m0'] = s_c_m0.bar.AskPrice
                                    df.at[i,
                                          'price_p_m0'] = s_p_m0.bar.AskPrice
                                    df.at[i,
                                          'price_c_m1'] = s_c_m1.bar.BidPrice
                                    df.at[i,
                                          'price_p_m1'] = s_p_m1.bar.BidPrice

                                df2_straddle = pd.DataFrame(
                                    r, columns=cols_straddle)
                                df_straddle = pd.concat(
                                    [df_straddle, df2_straddle], sort=False)

                            # 多单获利平仓
                            elif row.hold_m0 == -1 and row.hold_m1 == 1:
                                df.at[i, 'profit_m0'] = round(
                                    (row.price_c_m0 + row.price_p_m0) -
                                    (s_c_m0.bar.AskPrice +
                                     s_p_m0.bar.AskPrice), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (s_c_m1.bar.BidPrice + s_p_m1.bar.BidPrice)
                                    - (row.price_c_m1 + row.price_p_m1), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)

                                if df.at[i, 'profit_o'] >= row.profit:
                                    df.at[i, 'hold_m0'] = 0
                                    df.at[i, 'hold_m1'] = 0
                                    df.at[i, 'state'] = 'stop'
                                    for j, jow in df_straddle.iterrows():
                                        if jow.basic == row.basic_m0 and jow.strike == row.strike and jow.direction == 'kong' and jow.source == 'sdiffer':
                                            df_straddle.at[j, 'profit'] = -1000
                                        if jow.basic == row.basic_m1 and jow.strike == row.strike and jow.direction == 'duo' and jow.source == 'sdiffer':
                                            df_straddle.at[j, 'profit'] = -1000

                            # 空单获利平仓
                            elif row.hold_m0 == 1 and row.hold_m1 == -1:
                                df.at[i, 'profit_m0'] = round(
                                    (s_c_m0.bar.BidPrice + s_p_m0.bar.BidPrice)
                                    - (row.price_c_m0 + row.price_p_m0), 2)
                                df.at[i, 'profit_m1'] = round(
                                    (row.price_c_m1 + row.price_p_m1) -
                                    (s_c_m1.bar.AskPrice +
                                     s_p_m1.bar.AskPrice), 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_m0'] +
                                    df.at[i, 'profit_m1'], 2)

                                if df.at[i, 'profit_o'] >= row.profit:
                                    df.at[i, 'hold_m0'] = 0
                                    df.at[i, 'hold_m1'] = 0
                                    df.at[i, 'state'] = 'stop'
                                    for j, jow in df_straddle.iterrows():
                                        if jow.basic == row.basic_m0 and jow.strike == row.strike and jow.direction == 'duo' and jow.source == 'sdiffer':
                                            df_straddle.at[j, 'profit'] = -1000
                                        if jow.basic == row.basic_m1 and jow.strike == row.strike and jow.direction == 'kong' and jow.source == 'sdiffer':
                                            df_straddle.at[j, 'profit'] = -1000

                    except Exception as e:
                        s = traceback.format_exc()
                        to_log(s)

            df_straddle.to_csv(fn_straddle, index=False)
            # release_file_lock(fn_straddle)

            df.to_csv(fn, index=False)
            # release_file_lock(fn)

            for symbol in symbol_got_list:
                self.got_dict[symbol] = False

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

        fn = get_dss() + 'opt/sdiffer_d_base.csv'
        df = pd.read_csv(fn)
        date_list = sorted(list(set(df.date)))
        # print(date_list)
        date = date_list[-1]
        df = df[df.date == date]
        for i, row in df.iterrows():
            self.d_base_dict[row.basic + '_' + str(row.strike)] = row.d_base

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        fn = get_dss() + 'fut/engine/sdiffer/portfolio_sdiffer_param.csv'
        df = pd.read_csv(fn)
        for i, row in df.iterrows():
            if row.date == self.result.date[:
                                            10] and row.source == 'sdiffer' and row.hold_m0 == 0:
                df.at[i, 'state'] = 'stop'

        df = df[(df.state == 'run') | (df.date == self.result.date[:10])]
        df.to_csv(fn, index=False)
예제 #9
0
class Fut_IcPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'ic'

        assert len(symbol_list) == 2
        self.symbol_g = symbol_list[0]
        self.symbol_d = symbol_list[1]
        self.dual_name = self.symbol_g + '_' + self.symbol_d
        symbol_list.append(self.dual_name)
        self.direction_g = 'direction_g'
        self.num_g = 0
        self.direction_d = 'direction_d'
        self.num_d = 0
        self.got_dict = {}
        self.got_dict[self.symbol_g] = False
        self.got_dict[self.symbol_d] = False

        df = self.load_param()
        if df is not None:
            for i, row in df.iterrows():
                if row.symbol_g in symbol_list and row.symbol_d in symbol_list:
                    self.direction_g = row.symbol_g
                    self.num_g = row.direction_g
                    self.direction_d = row.num_g
                    self.num_d = row.num_d

        Portfolio.__init__(self, Fut_IcSignal, engine, symbol_list, signal_param)

        self.name_second = 'ic_' + self.dual_name

        # print(symbol_list, self.dual_name)


    #----------------------------------------------------------------------
    def load_param(self):
        fn = get_dss() +  'fut/engine/ic/portfolio_ic_param.csv'
        df = None
        if os.path.exists(fn):
            df = pd.read_csv(fn)

        return df

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min15':               # 本策略为min15
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)

        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """


        if self.got_dict[self.symbol_g] == True and self.got_dict[self.symbol_d] == True:
            for signal in self.signalDict[self.dual_name]:
                for s_g in self.signalDict[self.symbol_g]:
                    price_g = s_g.bar.close
                for s_d in self.signalDict[self.symbol_d]:
                    price_d = s_d.bar.close

                price_gap = price_g - price_d
                bar_dual = VtBarData()
                bar_dual.vtSymbol = self.dual_name
                bar_dual.open = price_gap
                bar_dual.high = price_gap
                bar_dual.low = price_gap
                bar_dual.close = price_gap
                bar_dual.date = bar.date
                bar_dual.time = bar.time
                bar_dual.datetime = bar.date + ' ' + bar.time

                # 将bar推送给signal
                signal.onBar(bar_dual, minx)
                self.result.updateBar(bar_dual)

                # print(bar_dual.vtSymbol, bar_dual.datetime )

            self.got_dict[self.symbol_g] = False
            self.got_dict[self.symbol_d] = False


        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)


    #----------------------------------------------------------------------
    def _bc_dual_signal(self, direction, offset, volume_g, volume_d):
        for signal in self.signalDict[self.symbol_g]:
            signal_g = signal
        for signal in self.signalDict[self.symbol_d]:
            signal_d = signal

        if direction == DIRECTION_LONG and offset == OFFSET_OPEN:
            signal_g.buy(signal_g.bar.close, volume_g)
            signal_d.short(signal_d.bar.close, volume_d)
        if direction == DIRECTION_SHORT and offset == OFFSET_OPEN:
            signal_g.short(signal_g.bar.close, volume_g)
            signal_d.buy(signal_d.bar.close, volume_d)
        if direction == DIRECTION_LONG and offset == OFFSET_CLOSE:
            signal_g.cover(signal_g.bar.close, volume_g)
            signal_d.sell(signal_d.bar.close, volume_d)
        if direction == DIRECTION_SHORT and offset == OFFSET_CLOSE:
            signal_g.sell(signal_g.bar.close, volume_g)
            signal_d.cover(signal_d.bar.close, volume_d)
예제 #10
0
class Fut_RatioPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'ratio'

        self.tm = '00:00:00'
        self.got_dict = {}
        for symbol in symbol_list:
            self.got_dict[symbol] = False

        Portfolio.__init__(self, Fut_RatioSignal, engine, symbol_list,
                           signal_param)
        # self.promote = True

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        # 动态加载新维护的symbol
        config = open(get_dss() + 'fut/cfg/config.json')
        setting = json.load(config)
        symbols = setting['symbols_ratio']
        symbols_list = symbols.split(',')

        for vtSymbol in symbols_list:
            if vtSymbol not in self.vtSymbolList:
                self.vtSymbolList.append(vtSymbol)
                self.posDict[vtSymbol] = 0
                self.got_dict[vtSymbol] = False
                signal1 = Fut_RatioSignal(self, vtSymbol)

                l = self.signalDict[vtSymbol]
                l.append(signal1)

        if self.tm != bar.time:
            self.tm = bar.time
            for symbol in self.vtSymbolList:
                self.got_dict[symbol] = False

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        self.control_in_p(bar)

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def control_in_p(self, bar):
        if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0

            symbol_got_list = []
            fn = get_dss() + 'fut/engine/ratio/portfolio_ratio_param.csv'

            df = pd.read_csv(fn)  # 加载最新参数
            for i, row in df.iterrows():
                try:
                    if row.state == 'stop':
                        continue

                    if row.symbol_b not in self.got_dict or row.symbol_s not in self.got_dict:
                        continue

                    if self.got_dict[row.symbol_b] == False or self.got_dict[
                            row.symbol_s] == False:
                        continue
                    else:
                        df.at[i, 'tm'] = bar.time

                        symbol_got_list.append(row.symbol_b)
                        symbol_got_list.append(row.symbol_s)

                        s_b = self.signalDict[row.symbol_b][0]
                        s_s = self.signalDict[row.symbol_s][0]

                        # 开仓
                        if row.hold_b == 0 and row.hold_s == 0:
                            if self.engine.type == 'backtest':
                                if row.num_s * s_s.bar.close - row.num_b * s_b.bar.close >= row.gap:
                                    s_b.buy(s_b.bar.close, row.num_b)
                                    s_s.short(s_s.bar.close, row.num_s)
                                    df.at[i, 'price_b'] = s_b.bar.close
                                    df.at[i, 'price_s'] = s_s.bar.close
                                    df.at[i, 'hold_b'] = row.num_b
                                    df.at[i, 'hold_s'] = row.num_s
                            else:
                                gap_open = row.num_s * s_s.bar.BidPrice - row.num_b * s_b.bar.AskPrice
                                df.at[i, 'gap_open'] = gap_open
                                df.at[i,
                                      'price_b'] = round(s_b.bar.AskPrice, 2)
                                df.at[i,
                                      'price_s'] = round(s_s.bar.BidPrice, 2)
                                if gap_open >= row.gap:
                                    s_b.buy(s_b.bar.AskPrice, row.num_b)  # 挂卖价
                                    s_s.short(s_s.bar.BidPrice,
                                              row.num_s)  # 挂买价
                                    df.at[i, 'hold_b'] = row.num_b
                                    df.at[i, 'hold_s'] = row.num_s

                        # 获利平仓
                        if row.hold_b > 0 and row.hold_s > 0:
                            if self.engine.type == 'backtest':
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.close - row.price_b) * row.hold_b,
                                    2)
                                df.at[i, 'profit_s'] = round(
                                    -(s_s.bar.close - row.price_s) *
                                    row.hold_s, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)

                                if df.at[i, 'profit_o'] >= row.profit:
                                    s_b.sell(s_b.bar.close, row.num_b)
                                    s_s.cover(s_s.bar.close, row.num_s)
                                    df.at[i, 'hold_b'] = 0
                                    df.at[i, 'hold_s'] = 0
                                    df.at[i, 'state'] = 'stop'
                            else:
                                df.at[i, 'profit_b'] = round(
                                    (s_b.bar.BidPrice - row.price_b) *
                                    row.hold_b, 2)
                                df.at[i, 'profit_s'] = round(
                                    -(s_s.bar.AskPrice - row.price_s) *
                                    row.hold_s, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_b'] +
                                    df.at[i, 'profit_s'], 2)

                                if df.at[i, 'profit_o'] >= row.profit:
                                    s_b.sell(s_b.bar.BidPrice,
                                             row.num_b)  # 挂买价
                                    s_s.cover(s_s.bar.AskPrice,
                                              row.num_s)  # 挂卖价
                                    df.at[i, 'hold_b'] = 0
                                    df.at[i, 'hold_s'] = 0
                                    df.at[i, 'state'] = 'stop'

                except Exception as e:
                    s = traceback.format_exc()
                    to_log(s)

            df.to_csv(fn, index=False)  # 回写文件
            for symbol in symbol_got_list:
                self.got_dict[symbol] = False

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        fn = get_dss() + 'fut/engine/ratio/portfolio_ratio_param.csv'
        df = pd.read_csv(fn)
        for i, row in df.iterrows():
            if row.date == self.result.date[:
                                            10] and row.hold_b == 0 and row.hold_s == 0:
                df.at[i, 'state'] = 'stop'

        df = df[(df.state == 'run') |
                (df.date >= get_trade_preday(self.result.date[:10]))]
        df.to_csv(fn, index=False)
예제 #11
0
class Fut_StraddlePortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'straddle'
        self.tm = '00:00:00'
        self.got_dict = {}
        for symbol in symbol_list:
            self.got_dict[symbol] = False

        Portfolio.__init__(self, Fut_StraddleSignal, engine, symbol_list,
                           signal_param)
        self.promote = True

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        # 动态加载新维护的symbol
        config = open(get_dss() + 'fut/cfg/config.json')
        setting = json.load(config)
        symbols = setting['symbols_straddle']
        symbols_list = symbols.split(',')

        for vtSymbol in symbols_list:
            if vtSymbol not in self.vtSymbolList:
                self.vtSymbolList.append(vtSymbol)
                self.posDict[vtSymbol] = 0
                self.got_dict[vtSymbol] = False
                signal1 = Fut_StraddleSignal(self, vtSymbol)

                l = self.signalDict[vtSymbol]
                l.append(signal1)

        if self.tm != bar.time:
            self.tm = bar.time
            for symbol in self.vtSymbolList:
                self.got_dict[symbol] = False

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        self.control_in_p(bar)

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def control_in_p(self, bar):
        if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \
           (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0

            symbol_got_list = []
            fn = get_dss() + 'fut/engine/straddle/portfolio_straddle_param.csv'
            # while get_file_lock(fn) == False:
            #     time.sleep(0.01)

            df = pd.read_csv(fn)  # 加载最新参数
            for i, row in df.iterrows():
                try:
                    if row.state == 'stop':
                        continue

                    exchangeID = str(get_contract(row.basic_c).exchangeID)
                    if exchangeID in ['CFFEX', 'DCE']:
                        symbol_c = row.basic_c + '-C-' + str(row.strike_c)
                        symbol_p = row.basic_p + '-P-' + str(row.strike_p)
                    else:
                        symbol_c = row.basic_c + 'C' + str(row.strike_c)
                        symbol_p = row.basic_p + 'P' + str(row.strike_p)

                    if symbol_c not in self.got_dict or symbol_p not in self.got_dict:
                        continue

                    if self.got_dict[symbol_c] == False or self.got_dict[
                            symbol_p] == False:
                        continue
                    else:
                        df.at[i, 'tm'] = bar.time

                        symbol_got_list.append(symbol_c)
                        symbol_got_list.append(symbol_p)

                        s_c = self.signalDict[symbol_c][0]
                        s_p = self.signalDict[symbol_p][0]

                        # 开仓
                        if row.hold_c == 0 and row.hold_p == 0:
                            # print('come here ')
                            if row.direction == 'duo':
                                if self.engine.type == 'backtest':
                                    s_c.buy(s_c.bar.close, row.num_c)
                                    s_p.buy(s_p.bar.close, row.num_p)
                                    df.at[i, 'price_c'] = s_c.bar.close
                                    df.at[i, 'price_p'] = s_p.bar.close
                                else:
                                    s_c.buy(s_c.bar.AskPrice, row.num_c)  # 挂卖价
                                    s_p.buy(s_p.bar.AskPrice, row.num_p)  # 挂卖价
                                    df.at[i, 'price_c'] = round(
                                        s_c.bar.AskPrice, 2)
                                    df.at[i, 'price_p'] = round(
                                        s_p.bar.AskPrice, 2)
                                df.at[i, 'hold_c'] = row.num_c
                                df.at[i, 'hold_p'] = row.num_p

                            if row.direction == 'kong':
                                if self.engine.type == 'backtest':
                                    s_c.short(s_c.bar.close, row.num_c)
                                    s_p.short(s_p.bar.close, row.num_p)
                                    df.at[i, 'price_c'] = s_c.bar.close
                                    df.at[i, 'price_p'] = s_p.bar.close
                                else:
                                    s_c.short(s_c.bar.BidPrice,
                                              row.num_c)  # 挂买价
                                    s_p.short(s_p.bar.BidPrice,
                                              row.num_p)  # 挂买价
                                    df.at[i, 'price_c'] = round(
                                        s_c.bar.BidPrice, 2)
                                    df.at[i, 'price_p'] = round(
                                        s_p.bar.BidPrice, 2)
                                df.at[i, 'hold_c'] = -row.num_c
                                df.at[i, 'hold_p'] = -row.num_p

                        # 多单获利平仓
                        if row.hold_c >= 1 and row.hold_p >= 1:
                            if self.engine.type == 'backtest':
                                df.at[i,
                                      'profit_c'] = (s_c.bar.close -
                                                     row.price_c) * row.hold_c
                                df.at[i,
                                      'profit_p'] = (s_p.bar.close -
                                                     row.price_p) * row.hold_p
                                df.at[i, 'profit_o'] = df.at[
                                    i, 'profit_c'] + df.at[i, 'profit_p']

                                if row.profit_o >= row.profit:
                                    s_c.sell(s_c.bar.close, abs(row.hold_c))
                                    s_p.sell(s_p.bar.close, abs(row.hold_p))
                                    df.at[i, 'hold_c'] = 0
                                    df.at[i, 'hold_p'] = 0
                                    df.at[i, 'state'] = 'stop'
                            else:
                                df.at[i, 'profit_c'] = round(
                                    (s_c.bar.BidPrice - row.price_c) *
                                    row.hold_c, 2)
                                df.at[i, 'profit_p'] = round(
                                    (s_p.bar.BidPrice - row.price_p) *
                                    row.hold_p, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_c'] +
                                    df.at[i, 'profit_p'], 2)

                                if row.profit_o >= row.profit:
                                    s_c.sell(s_c.bar.BidPrice, abs(row.hold_c))
                                    s_p.sell(s_p.bar.BidPrice, abs(row.hold_p))
                                    df.at[i, 'hold_c'] = 0
                                    df.at[i, 'hold_p'] = 0
                                    df.at[i, 'state'] = 'stop'

                        # 空单获利平仓
                        if row.hold_c <= -1 and row.hold_p <= -1:
                            if self.engine.type == 'backtest':
                                df.at[i,
                                      'profit_c'] = (s_c.bar.close -
                                                     row.price_c) * row.hold_c
                                df.at[i,
                                      'profit_p'] = (s_p.bar.close -
                                                     row.price_p) * row.hold_p
                                df.at[i, 'profit_o'] = df.at[
                                    i, 'profit_c'] + df.at[i, 'profit_p']

                                if row.profit_o >= row.profit:
                                    s_c.cover(s_c.bar.close, abs(row.hold_c))
                                    s_p.cover(s_p.bar.close, abs(row.hold_p))
                                    df.at[i, 'hold_c'] = 0
                                    df.at[i, 'hold_p'] = 0
                                    df.at[i, 'state'] = 'stop'
                            else:
                                df.at[i, 'profit_c'] = round(
                                    (s_c.bar.AskPrice - row.price_c) *
                                    row.hold_c, 2)
                                df.at[i, 'profit_p'] = round(
                                    (s_p.bar.AskPrice - row.price_p) *
                                    row.hold_p, 2)
                                df.at[i, 'profit_o'] = round(
                                    df.at[i, 'profit_c'] +
                                    df.at[i, 'profit_p'], 2)

                                if row.profit_o >= row.profit:
                                    s_c.cover(s_c.bar.AskPrice,
                                              abs(row.hold_c))
                                    s_p.cover(s_p.bar.AskPrice,
                                              abs(row.hold_p))
                                    df.at[i, 'hold_c'] = 0
                                    df.at[i, 'hold_p'] = 0
                                    df.at[i, 'state'] = 'stop'

                except Exception as e:
                    s = traceback.format_exc()
                    to_log(s)

            df.to_csv(fn, index=False)  # 回写文件
            # release_file_lock(fn)
            for symbol in symbol_got_list:
                self.got_dict[symbol] = False

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        fn = get_dss() + 'fut/engine/straddle/portfolio_straddle_param.csv'
        df = pd.read_csv(fn)
        for i, row in df.iterrows():
            if row.date == self.result.date[:
                                            10] and row.hold_c == 0 and row.hold_p == 0:
                df.at[i, 'state'] = 'stop'

        df = df[(df.state == 'run') | (df.date == self.result.date[:10])]
        df.to_csv(fn, index=False)
class Fut_RatioPortfolio(Portfolio):

    #----------------------------------------------------------------------
    def __init__(self, engine, symbol_list, signal_param={}):
        self.name = 'ratio'

        assert len(symbol_list) == 2
        self.symbol_c = symbol_list[0]
        self.symbol_p = symbol_list[1]
        self.dual_name = self.symbol_c + '_' + self.symbol_p

        self.got_dict = {}
        self.got_dict[self.symbol_c] = False
        self.got_dict[self.symbol_p] = False

        self.price_c = 0
        self.price_p = 0

        self.hold_c = 0
        self.hold_p = 0

        self.profit_c = 0
        self.profit_p = 0

        self.fixed_size = 1
        self.gap = 100
        self.profit = 100
        self.load_param(self.symbol_c, self.symbol_p)

        Portfolio.__init__(self, Fut_RatioSignal, engine, symbol_list,
                           signal_param)

        self.name_second = 'ratio_' + self.dual_name

    #----------------------------------------------------------------------
    def load_param(self, s_c, s_p):
        fn = get_dss() + 'fut/engine/ratio/portfolio_ratio_param.csv'
        df = pd.read_csv(fn)
        df = df[(df.symbol_c == s_c) & (df.symbol_p == s_p)]
        if len(df) > 0:
            row = df.iloc[-1, :]
            self.fixed_size = int(row.fixed_size)
            self.gap = int(row.gap)
            self.profit = int(row.profit)

    #----------------------------------------------------------------------
    def onBar(self, bar, minx='min1'):
        """引擎新推送过来bar,传递给每个signal"""

        # 不处理不相关的品种
        if bar.vtSymbol not in self.vtSymbolList:
            return

        if minx != 'min1':  # 本策略为min1
            return

        if self.result.date != bar.date + ' ' + bar.time:
            previousResult = self.result
            self.result = DailyResult(bar.date + ' ' + bar.time)
            self.resultList.append(self.result)
            if previousResult:
                self.result.updateClose(previousResult.closeDict)

        # 将bar推送给signal
        for signal in self.signalDict[bar.vtSymbol]:
            signal.onBar(bar, minx)
            # print(bar.vtSymbol, bar.time)
        """
        在此实现P层的业务控制逻辑
        为每一个品种来检查是否触发下单条件
        # 开始处理组合关心的bar , 尤其是品种对价差的加工和处理
        """
        if (bar.time > '09:35:00' and bar.time < '11:25:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '13:05:00' and bar.time < '14:55:00' and bar.vtSymbol[:2] in ['IF','IO']) or \
           (bar.time > '09:05:00' and bar.time < '11:25:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '13:35:00' and bar.time < '14:55:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \
           (bar.time > '21:05:00' and bar.time < '22:55:00' and bar.vtSymbol[:2] not in ['IF','IO']) :    # 因第一根K线的价格为0
            # 开仓
            if self.hold_c == 0 and self.hold_p == 0:
                self.load_param(self.symbol_c, self.symbol_p)  # 加载最新参数
                if self.got_dict[self.symbol_c] == True and self.got_dict[
                        self.symbol_p] == True:
                    self.got_dict[self.symbol_c] = False
                    self.got_dict[self.symbol_p] = False

                    s_c = self.signalDict[self.symbol_c][0]
                    s_p = self.signalDict[self.symbol_p][0]

                    if 2 * s_p.bar.close - s_c.bar.close >= self.gap:
                        if self.engine.type == 'backtest':
                            s_c.buy(s_c.bar.close, self.fixed_size)
                            s_p.short(s_p.bar.close, 2 * self.fixed_size)
                            self.price_c = s_c.bar.close
                            self.price_p = s_p.bar.close
                        else:
                            s_c.buy(s_c.bar.AskPrice, self.fixed_size)  # 挂卖价
                            s_p.short(s_p.bar.BidPrice,
                                      2 * self.fixed_size)  # 挂买价
                            self.price_c = s_c.bar.AskPrice
                            self.price_p = s_p.bar.BidPrice

                        self.hold_c = 1
                        self.hold_p = -2

            # 获利平仓
            if self.hold_c == 1 and self.hold_p == -2:
                self.load_param(self.symbol_c, self.symbol_p)  # 加载最新参数
                if self.got_dict[self.symbol_c] == True and self.got_dict[
                        self.symbol_p] == True:
                    self.got_dict[self.symbol_c] = False
                    self.got_dict[self.symbol_p] = False

                    s_c = self.signalDict[self.symbol_c][0]
                    s_p = self.signalDict[self.symbol_p][0]

                    if self.profit_c + self.profit_p >= self.profit:
                        if self.engine.type == 'backtest':
                            s_c.sell(s_c.bar.close, self.fixed_size)
                            s_p.cover(s_p.bar.close, 2 * self.fixed_size)
                        else:
                            s_c.sell(s_c.bar.BidPrice, self.fixed_size)  # 挂买价
                            s_p.cover(s_p.bar.AskPrice,
                                      2 * self.fixed_size)  # 挂卖价

                        self.hold_c = 0
                        self.hold_p = 0

        self.result.updateBar(bar)
        self.result.updatePos(self.posDict)

    #----------------------------------------------------------------------
    def daily_open(self):
        Portfolio.daily_open(self)

        fn = get_dss(
        ) + 'fut/engine/ratio/portfolio_' + self.name_second + '_save.csv'
        if os.path.exists(fn):
            df = pd.read_csv(fn)
            df = df[(df.symbol_c == self.symbol_c)
                    & (df.symbol_p == self.symbol_p)]
            if len(df) > 0:
                rec = df.iloc[-1, :]  # 取最近日期的记录
                self.price_c = rec.price_c
                self.price_p = rec.price_p
                self.hold_c = rec.hold_c
                self.hold_p = rec.hold_p

    #----------------------------------------------------------------------
    def daily_close(self):
        Portfolio.daily_close(self)

        r = [[
            self.result.date, self.symbol_c, self.symbol_p, self.price_c,
            self.price_p, self.hold_c, self.hold_p
        ]]

        df = pd.DataFrame(r,
                          columns=[
                              'datetime', 'symbol_c', 'symbol_p', 'price_c',
                              'price_p', 'hold_c', 'hold_p'
                          ])
        fn = get_dss(
        ) + 'fut/engine/ratio/portfolio_' + self.name_second + '_save.csv'
        if os.path.exists(fn):
            df.to_csv(fn, index=False, mode='a', header=False)
        else:
            df.to_csv(fn, index=False)