diff --git a/spread_backtest.py b/spread_backtest.py index 4e2291e..3b700c1 100644 --- a/spread_backtest.py +++ b/spread_backtest.py @@ -36,6 +36,7 @@ class Spread_Backtest(): else: bkt_end = rec_end print(f'回测区间: {bkt_start} - {bkt_end}') + start_time = time.time() target_list = self.trader.signal[list(self.trader.signal.keys())[0]].loc[bkt_start:bkt_end].index for idx,date in enumerate(sorted(target_list), start=1): diff --git a/trader.py b/trader.py index 58eef0c..7c88c6b 100644 --- a/trader.py +++ b/trader.py @@ -235,7 +235,8 @@ class Trader(Account): stock_ipo_filter = stock_ipo_days.copy() stock_ipo_filter.loc[:] = 0 stock_ipo_filter.loc[stock_ipo_days > self.ipo_days] = 1 - # 剔除列表 + # 剔除列表 = ipo筛选 + 成交量筛选 + 额外剔除 + # 其中额外提出会强制执行,因此单独保存一份强制执行的列表 exclude_stock = [] for exclude in self.exclude_list: if exclude == 'abnormal': @@ -344,19 +345,36 @@ class Trader(Account): normal_list = [] margin_list = [] - for stock in last_position.index: + # 获取历史融资融券池 + if len(last_position) > 0: + last_margin_list = self.position.loc[self.position['margin_trade'] == 1, 'stock_code'].to_list() + else: + last_margin_list = [] + # 获取历史非融资融券标的 + if len(last_position) > 0: + last_normal_list = self.position.loc[self.position['margin_trade'] == 0, 'stock_code'].to_list() + else: + last_normal_list = [] + + for stock in last_margin_list: # 如果停牌或者跌停继续持有 if stock_status.loc[stock] in [0,2]: - normal_list, margin_list = assign_stock(normal_list, margin_list, margin_needed, stock, is_margin.loc[stock]) + margin_list.append(stock) + for stock in last_normal_list: + # 如果停牌或者跌停继续持有 + if stock_status.loc[stock] in [0,2]: + normal_list.append(stock) # 剔除过滤条件后 after_filter_list = list(set(factor.index) - set(exclude_stock)) for stock in factor.loc[after_filter_list].dropna().sort_values(ascending=self.ascending).index.values: - if stock_amt_filter.loc[stock] != 1: - continue + if len(normal_list + margin_list) == self.num: + break if self.with_st: if stock_status.loc[stock] in [0,2,5,7]: - if stock in last_position.index: - normal_list, margin_list = assign_stock(normal_list, margin_list, margin_needed, stock, is_margin.loc[stock]) + if stock in last_margin_list: + margin_list.append(stock) + else: + normal_list.append(stock) else: normal_list, margin_list = assign_stock(normal_list, margin_list, margin_needed, stock, is_margin.loc[stock]) else: @@ -366,24 +384,23 @@ class Trader(Account): else: # 如果停牌或者跌停继续持有 if stock_status.loc[stock] in [0,2,7]: - if stock in last_position.index: - normal_list, margin_list = assign_stock(normal_list, margin_list, margin_needed, stock, is_margin.loc[stock]) - if len(normal_list + margin_list) == self.num: - break + if stock in last_margin_list: + margin_list.append(stock) + else: + normal_list.append(stock) + margin_list = list(OrderedSet(margin_list)) + normal_list = list(OrderedSet(normal_list)) target_list = normal_list + margin_list # ----- 卖出 ----- buy_list = [] sell_list = [] # 融资融券池的和非融资融券池的分开更新 # 更新融资融券池 - if len(last_position) > 0: - last_margin_list = self.position.loc[self.position['margin_trade'] == 1, 'stock_code'].to_list() - else: - last_margin_list = [] # 异常强制卖出 for stock in last_margin_list: if stock in force_exclude: sell_list.append(stock) + force_sell_num = len(sell_list) for stock in factor.loc[last_margin_list].sort_values(ascending=self.ascending).index.values[::-1]: if len(sell_list) >= int(max_sell_num * margin_ratio) + force_sell_num + 1: @@ -398,10 +415,6 @@ class Trader(Account): sell_list = list(set(sell_list)) next_margin_list = list(set(last_margin_list) - set(sell_list)) # 更新非融资融券池 - if len(last_position) > 0: - last_normal_list = self.position.loc[self.position['margin_trade'] == 0, 'stock_code'].to_list() - else: - last_normal_list = [] # 异常强制卖出 for stock in last_normal_list: if stock in force_exclude: