Exemple #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("action", choices=["backtest", "trade"])
    args = parser.parse_args()
    if args.action == "backtest":
        backtest.backtest()
    if args.action == "trade":
        trade.trade()
def sf_test_multiple_pools(factor=None, sf_obj=single_factor_strategy(), *, direction='+', bb_obj=None,
                           discard_factor=(), folder_names=None, holding_freq='w', benchmarks=None,
                           stock_pools=('all', 'hs300', 'zz500', 'zz800'), bkt_start=None, bkt_end=None,
                           select_method=0, do_bb_pure_factor=False, do_pa=False, do_active_pa=False,
                           do_data_description=False, do_factor_corr_test=False, loc=-1):
    # 打印当前测试的策略名称
    print('Name Of Strategy Under Test: {0}\n'.format(sf_obj.__class__.__name__))

    cp_adj = data.read_data('ClosePrice_adj')
    temp_position = position(cp_adj)
    # 先要初始化bkt对象
    bkt_obj = backtest(temp_position, bkt_start=bkt_start, bkt_end=bkt_end, buy_cost=0.0015,
                       sell_cost=0.0015, bkt_stock_data=['ClosePrice_adj', 'ClosePrice_adj'])
    # 建立bb对象,否则之后每次循环都要建立一次新的bb对象
    if bb_obj is None:
        bb_obj = barra_base()
    # 外部传入的bb对象,要检测其股票池是否为all,如果不是all,则输出警告,因为可能丢失了数据
    elif bb_obj.bb_data.stock_pool != 'all':
        print('The stockpool of the barra_base obj from outside is NOT "all", be aware of possibile'
              'data loss due to this situation!\n')

    # 根据股票池进行循环
    for cursor, stock_pool in enumerate(stock_pools):
        # 进行当前股票池下的单因子测试
        # 注意bb obj进行了一份深拷贝,这是因为在业绩归因的计算中,会根据不同的股票池丢弃数据,导致数据不全,因此不能传引用
        # 对bkt obj做了同样的处理,尽管这里并不是必要的
        sf_obj.single_factor_test(factor=factor, loc=loc, direction=direction, bkt_obj=copy.deepcopy(bkt_obj),
            base_obj=copy.deepcopy(bb_obj), discard_factor=discard_factor,
            folder_name=folder_names[cursor], bkt_start=bkt_start, bkt_end=bkt_end,
            holding_freq=holding_freq, benchmark=benchmarks[cursor], stock_pool=stock_pool,
            select_method=select_method, do_base_pure_factor=do_bb_pure_factor,
            do_pa=do_pa, do_active_pa=do_active_pa, do_data_description=do_data_description,
            do_factor_corr_test=do_factor_corr_test)
    def backtest(self, config):
        results = []
        all_daily_returns = []
        all_objectives = []

        for splits in self:
            start, end = splits["train"]["start_idx"], splits["train"][
                "end_idx"]
            self.update_config(
                config, splits["train"])  # Update n_days and start/end date
            fills, stats, did_finish = backtest(config, self.ticks[start:end])
            _, _, result_ = analyze_backtest(fills, stats, self.bc)
            results.append(result_)

            all_daily_returns.append(
                result_["returns_daily" +
                        "_obj"])  # stats is more accurate than fills
            all_objectives.append(result_[self.bc["metric"] + "_obj"])

        result = {}
        for k in results[0]:
            try:
                result[k] = np.mean([r[k] for r in results])
            except:
                result[k] = results[0][k]

        # Geometrical mean is often used to average returns
        result["daily_gains_gmean"] = np.exp(
            np.mean(np.log(np.array(all_daily_returns) + 1)))
        result["objective_gmean"] = np.exp(
            np.mean(np.log(np.array(all_objectives) + 1))) - 1

        return result
Exemple #4
0
def backtest_single_wrap(config_: dict):
    config = config_.copy()
    exchange_name = config['exchange'] + ('_spot' if config['market_type'] == 'spot' else '')
    cache_filepath = f"backtests/{exchange_name}/{config['symbol']}/caches/"
    ticks_filepath = cache_filepath + f"{config['start_date']}_{config['end_date']}_ticks_cache.npy"
    mss = json.load(open(cache_filepath + 'market_specific_settings.json'))
    ticks = np.load(ticks_filepath)
    config.update(mss)
    try:
        fills, stats = backtest(config, ticks)
        fdf, sdf, analysis = analyze_fills(fills, stats, config)
        pa_closeness_long = analysis['pa_closeness_mean_long']
        pa_closeness_shrt = analysis['pa_closeness_mean_shrt']
        adg = analysis['average_daily_gain']
        print(f"backtested {config['symbol']: <12} pa closeness long {pa_closeness_long:.6f} "
              f"pa closeness shrt {pa_closeness_shrt:.6f} adg {adg:.6f}")
    except Exception as e:
        print(f'error with {config["symbol"]} {e}')
        print('config')
        traceback.print_exc()
        adg = 0.0
        pa_closeness_long = pa_closeness_shrt = 100.0
        with open(make_get_filepath('tmp/harmony_search_errors.txt'), 'a') as f:
            f.write(json.dumps([time(), 'error', str(e), denumpyize(config)]) + '\n')
    return (pa_closeness_long, pa_closeness_shrt, adg)
Exemple #5
0
def wrap_backtest(config, ticks):
    results = []
    for ticks_slice in iter_slices(ticks, 0.4, 4):
        fills, _, did_finish = backtest(config, ticks_slice)
        result_ = prepare_result(fills, ticks_slice, config['do_long'],
                                 config['do_shrt'])
        results.append(result_)
    result = {}
    for k in results[0]:
        try:
            result[k] = np.mean([r[k] for r in results])
        except:
            result[k] = results[0][k]

    # fills, _, did_finish = backtest(config, ticks)
    # result = prepare_result(fills, ticks, config['do_long'], config['do_shrt'])
    objective = objective_function(result,
                                   config['minimum_liquidation_distance'],
                                   config['max_hrs_no_fills'],
                                   config['max_hrs_no_fills_same_side'])
    tune.report(
        objective=objective,
        daily_gain=result['average_daily_gain'],
        closest_liquidation=result['closest_liq'],
        max_hrs_no_fills=result['max_hrs_no_fills'],
        max_hrs_no_fills_same_side=result['max_hrs_no_fills_same_side'])
Exemple #6
0
def wrap_backtest(config, ticks):
    fills, _, did_finish = backtest(config, ticks)
    result = prepare_result(fills, ticks, config['do_long'], config['do_shrt'])
    objective = objective_function(result,
                                   config['minimum_liquidation_distance'],
                                   config['max_n_hours_between_fills'])
    tune.report(objective=objective, daily_gain=result['average_daily_gain'], closest_liquidation=result['closest_liq'],
                max_hours_between_fills=result['max_n_hours_between_fills'])
Exemple #7
0
def main():
    #general init done on config import

    #train weights
    weights = {}
    if cfg.train:
        msg('beginning to train', '+')
        weights = train()
        msg('done training', '+')

    #backtest algorithm
    if cfg.backtest:
        msg('beginning backtest', '+')
        start = time.time()
        backtest(weights)
        msg('finished testing in %s' % round(time.time() - start, 3), '+')
        cfg.api.account_info(cfg.today)
Exemple #8
0
def daily_test(feature,dts,index,initMoney,startDt,modelFile,strategy):
    idx = dts>=startDt;
    fea = feature[idx];
    cls = pickle.load(open(modelFile));
    #pred = np.squeeze(cls.predict_proba(fea)[:,cls.classes_==1]);
    pred = np.squeeze(cls.predict(fea));
    index = index[idx];
    dfDec = pd.DataFrame(pred,
                         index=pd.MultiIndex.from_tuples(index,
                                                         names=['secID','tradeDate']),
                         columns = ['DecFactor']
                         );

    dfDec = utils_common.shiftDtPost(dfDec);
    dfDec.reset_index(inplace=True);
    dfDec.sort_values(['tradeDate','DecFactor'],inplace=True,ascending=False);
    decFactor = utils_common.groupDt(dfDec);
    backtest.backtest(initMoney,startDt,'2019-01-01',strategy,decFactor);
    pass;
Exemple #9
0
def daily_test(feature, dts, index, initMoney, startDt, modelFile, strategy):
    idx = dts >= startDt
    fea = feature[idx]
    cls = pickle.load(open(modelFile))
    #pred = np.squeeze(cls.predict_proba(fea)[:,cls.classes_==1]);
    pred = np.squeeze(cls.predict(fea))
    index = index[idx]
    dfDec = pd.DataFrame(pred,
                         index=pd.MultiIndex.from_tuples(
                             index, names=['secID', 'tradeDate']),
                         columns=['DecFactor'])

    dfDec = utils_common.shiftDtPost(dfDec)
    dfDec.reset_index(inplace=True)
    dfDec.sort_values(['tradeDate', 'DecFactor'],
                      inplace=True,
                      ascending=False)
    decFactor = utils_common.groupDt(dfDec)
    backtest.backtest(initMoney, startDt, '2019-01-01', strategy, decFactor)
    pass
Exemple #10
0
def single_sliding_window_run(config, data, do_print=True) -> (float, [dict]):
    analyses = []
    objective = 0.0
    n_days = config['n_days']
    metric = config['metric'] if 'metric' in config else 'adjusted_daily_gain'
    if config['sliding_window_days'] == 0.0:
        sliding_window_days = n_days
    else:
        # sliding window n days should be greater than max hrs no fills
        sliding_window_days = min(
            n_days,
            max([
                config['hrs_stuck_max_long'] * 2.1 / 24,
                config['hrs_stuck_max_shrt'] * 2.1 / 24,
                config['sliding_window_days']
            ]))
    sample_size_ms = data[1][0] - data[0][0]
    max_span = config['max_span'] if 'max_span' in config else 0
    max_span_ito_n_samples = int(max_span * 60 / (sample_size_ms / 1000))
    for z, data_slice in enumerate(
            iter_slices(data,
                        sliding_window_days,
                        max_span=int(round(max_span)))):
        if len(data_slice[0]) == 0:
            print('debug b no data')
            continue
        try:
            packed = pack_config(config)
            fills, stats = backtest(packed, data_slice)
        except Exception as e:
            print(e)
            break
        _, _, analysis = analyze_fills(fills, stats, config)
        analysis['score'], do_break, line = objective_function(analysis,
                                                               config,
                                                               metric=metric)
        analysis['score'] *= (analysis['n_days'] / config['n_days'])
        analyses.append(analysis)
        objective = np.sum([e['score'] for e in analyses]) * max(
            1.01, config['reward_multiplier_base'])**(z + 1)
        analyses[-1]['objective'] = objective
        line = (
            f'{str(z).rjust(3, " ")} adg {analysis["average_daily_gain"]:.4f}, '
            f'bkr {analysis["closest_bkr"]:.4f}, '
            f'eqbal {analysis["eqbal_ratio_min"]:.4f} n_days {analysis["n_days"]:.1f}, '
            f'score {analysis["score"]:.4f}, objective {objective:.4f}, '
            f'hrs stuck ss {str(round(analysis["hrs_stuck_max"], 1)).zfill(4)}, '
        ) + line
        if do_print:
            print(line)
        if do_break:
            break
    return objective, analyses
Exemple #11
0
def simple_sliding_window_wrap(config, ticks):
    sliding_window_size = config[
        'sliding_window_size'] if 'sliding_window_size' in config else 0.4
    n_windows = config[
        'n_sliding_windows'] if 'n_sliding_windows' in config else 4
    test_full = config['test_full'] if 'test_full' in config else False
    results = []
    for ticks_slice in iter_slices(ticks,
                                   sliding_window_size,
                                   n_windows,
                                   yield_full=test_full):
        try:
            fills, _, did_finish = backtest(config, ticks_slice)
        except Exception as e:
            print('debug a', e, config)
        try:
            _, result_ = analyze_fills(fills, config, ticks_slice[-1][2])
        except Exception as e:
            print('b', e)
        results.append(result_)
        if config['break_early_factor'] > 0.0 and \
                (not did_finish or
                 result_['closest_liq'] < config['minimum_liquidation_distance'] * (1 - config['break_early_factor']) or
                 result_['max_hrs_no_fills'] > config['max_hrs_no_fills'] * (1 + config['break_early_factor']) or
                 result_['max_hrs_no_fills_same_side'] > config['max_hrs_no_fills_same_side'] * (1 + config['break_early_factor'])):
            break
    if results:
        result = {}
        for k in results[0]:
            try:
                if k == 'closest_liq':
                    result[k] = np.min([r[k] for r in results])
                elif 'max_hrs_no_fills' in k:
                    result[k] = np.max([r[k] for r in results])
                else:
                    result[k] = np.mean([r[k] for r in results])
            except:
                result[k] = results[0][k]
    else:
        result = get_empty_analysis()

    try:
        objective = objective_function(result, 'average_daily_gain', config)
    except Exception as e:
        print('c', e)
    tune.report(
        objective=objective,
        daily_gain=result['average_daily_gain'],
        closest_liquidation=result['closest_liq'],
        max_hrs_no_fills=result['max_hrs_no_fills'],
        max_hrs_no_fills_same_side=result['max_hrs_no_fills_same_side'])
Exemple #12
0
    def do_opt_portfolio_test(self, *, start_date=None, end_date=None, loc=-1, foldername='',
                              indus_neutral=False):
        # 生成调仓日
        self.generate_holding_days(loc=loc, start_date=start_date, end_date=end_date)

        # 初始化持仓矩阵
        self.initialize_position(self.strategy_data.stock_price.ix[0, self.holding_days, :])

        # 过滤不可交易数据
        self.strategy_data.handle_stock_pool(shift=True)
        self.strategy_data.discard_uninv_data()
        self.factor_return = self.factor_return.where(self.strategy_data.if_tradable['if_inv'], np.nan)

        # # 投资域为全市场时的tricky解法, 只保留有alpha, 且在benchmark中的股票
        # self.factor_return = self.factor_return.mask(np.logical_and(self.strategy_data.benchmark_price.iloc[0]>0,
        #         self.factor_return.isnull()), 0)

        # 解优化组合
        self.construct_optimized_portfolio(indus_neutral=indus_neutral)

        # 如果没有路径名, 则自己创建一个
        if not os.path.exists(str(os.path.abspath('.')) + '/' + foldername + self.strategy_data.stock_pool +
                                      '/'):
            os.makedirs(str(str(os.path.abspath('.')) + '/' + foldername + self.strategy_data.stock_pool +
                            '/'))
        # 建立画pdf的对象
        self.pdfs = PdfPages(str(os.path.abspath('.')) + '/' + foldername + self.strategy_data.stock_pool +
                             '/allfigs.pdf')

        # 进行回测
        self.bkt_obj = backtest(self.position, bkt_start=start_date, bkt_end=end_date,
                                bkt_benchmark_data='ClosePrice_adj_'+self.strategy_data.stock_pool)
        self.bkt_obj.execute_backtest()
        self.bkt_obj.get_performance(foldername=foldername + self.strategy_data.stock_pool, pdfs=self.pdfs)

        # 做真实情况下的超额归因
        pa_benchmark_weight = data.read_data(['Weight_' + self.strategy_data.stock_pool],
                                             ['Weight_' + self.strategy_data.stock_pool])
        pa_benchmark_weight = pa_benchmark_weight['Weight_' + self.strategy_data.stock_pool]
        # pa_benchmark_weight = data.read_data(['Weight_hs300'],
        #                                      ['Weight_hs300'])
        # pa_benchmark_weight = pa_benchmark_weight['Weight_hs300']

        self.bkt_obj.get_performance_attribution(benchmark_weight=pa_benchmark_weight, show_warning=False,
            pdfs=self.pdfs, is_real_world=True, foldername=foldername + self.strategy_data.stock_pool,
            real_world_type=2, enable_read_base_expo=True, enable_read_pa_return=True,
            base_stock_pool=self.strategy_data.stock_pool)

        self.pdfs.close()
Exemple #13
0
def main(strategy, scoreFile, scoreColumn):
    df = pd.read_csv(scoreFile)
    df.sort_values(['tradeDate', scoreColumn], inplace=True, ascending=False)
    dfdt = utils_common.groupDt(df)
    backtest.backtest(1000000, '0000-00-00', '9999-99-99', strategy, dfdt)
    pass
 # backtest results
 assets = {}
 returns = {}
 for key, model in models.items():
     print(f'Optimizing {key}...')
     data = sp500
     if key == 'Momentum':
         lookback_period = 12
     elif key == 'ResidualMomentum':
         lookback_period = 36
     else:
         lookback_period = 36
     start = time.time()
     a, r = backtest(model=model,
                     invest_start=invest_start,
                     invest_period=invest_period,
                     lookback_period=lookback_period,
                     rebalance_period=rebalance_period,
                     historical_data=data)
     end = time.time()
     print(f'Optimization took: {end - start:8.4f}sec')
     assets[key] = a
     returns[key] = r
 pfo_rets = pd.DataFrame(returns,
                         index=pd.period_range(invest_start,
                                               freq='M',
                                               periods=invest_period))
 # get S&P500 index
 pfo_rets['S&P500'] = get_sp500_index(invest_start, invest_period)
 print(
     '***************************** Optimization summary *****************************'
 )
Exemple #15
0
import backtest

if __name__ == "__main__":
    testStock = ["AAPL"]
    newTest = backtest.backtest(testStock,
                                start="2020-05-30",
                                end="2020-12-30")
    newTest.algo_1(risk=0.05, profit=0.10, starting_capital=500, testing=False)
    print("\n\n" + newTest.get_summary())
def sf_test_multiple_pools_parallel(factor=None,
                                    *,
                                    direction='+',
                                    bb_obj=None,
                                    discard_factor=(),
                                    folder_name=None,
                                    stock_pools=('all', 'hs300', 'zz500',
                                                 'zz800'),
                                    bkt_start=None,
                                    bkt_end=None,
                                    select_method=0,
                                    do_bb_pure_factor=False,
                                    do_pa=False,
                                    do_factor_corr_test=False,
                                    do_active_pa=False,
                                    holding_freq='w',
                                    do_data_description=False,
                                    loc=-1):
    cp_adj = data.read_data(['ClosePrice_adj'])
    cp_adj = cp_adj['ClosePrice_adj']
    temp_position = position(cp_adj)

    # 先要初始化bkt对象
    bkt_obj = backtest(temp_position,
                       bkt_start=bkt_start,
                       bkt_end=bkt_end,
                       buy_cost=1.5 / 1000,
                       sell_cost=1.5 / 1000)
    # 建立bb对象,否则之后每次循环都要建立一次新的bb对象
    if bb_obj is None:
        bb_obj = barra_base()
    # 外部传入的bb对象,要检测其股票池是否为all,如果不是all,则输出警告,因为可能丢失了数据
    elif bb_obj.bb_data.stock_pool != 'all':
        print(
            'The stockpool of the barra_base obj from outside is NOT "all", be aware of possibile'
            'data loss due to this situation!\n')

    def single_task(stock_pool):
        # curr_sf = single_factor_strategy()
        from intangible_info import intangible_info_earnings
        curr_sf = intangible_info_earnings()

        # 进行当前股票池下的单因子测试
        # 注意bb obj进行了一份深拷贝,这是因为在业绩归因的计算中,会根据不同的股票池丢弃数据,导致数据不全,因此不能传引用
        # 对bkt obj做了同样的处理,这是因为尽管bkt obj不会被改变,但是多进程同时操作可能出现潜在的问题
        curr_sf.single_factor_test(stock_pool=stock_pool,
                                   factor=factor,
                                   loc=loc,
                                   direction=direction,
                                   folder_name=folder_name,
                                   bkt_obj=copy.deepcopy(bkt_obj),
                                   base_obj=copy.deepcopy(bb_obj),
                                   discard_factor=discard_factor,
                                   bkt_start=bkt_start,
                                   bkt_end=bkt_end,
                                   select_method=select_method,
                                   do_base_pure_factor=do_bb_pure_factor,
                                   holding_freq=holding_freq,
                                   do_pa=do_pa,
                                   do_active_pa=do_active_pa,
                                   do_data_description=do_data_description,
                                   do_factor_corr_test=do_factor_corr_test)

    import multiprocessing as mp
    mp.set_start_method('fork')
    # 根据股票池进行循环
    for stock_pool in stock_pools:
        p = mp.Process(target=single_task, args=(stock_pool, ))
        p.start()
Exemple #17
0
        grid = (klines['close'] - fma) / atr
        return grid

    def buy_signal(self, index_code):
        rsrs = self.get_rsrs_value(index_code)

        return rsrs > 1 and self.buy_filter(index_code)

    def sell_signal(self, index_code):
        rsrs = self.get_rsrs_value(index_code)
        return rsrs < -1 and self.sell_filter(index_code)

    def buy_filter(self, index_code):
        grid = self.get_grid(index_code)
        return grid.values[-1] > 1

    def sell_filter(self, index_code):
        grid = self.get_grid(index_code)
        return grid.values[-1] < -1



if __name__ == '__main__':
    import backtest
    import account

    acc = account.IndexAccount(data=backtest.get_datasource())
    stra = RSRS_Strategy(['399300.SZ'], account=acc)
    report = backtest.backtest(stra, start='20160101', end='20181231')
    report.show()
Exemple #18
0
def backtest_wrap(config_: dict, ticks_caches: dict):
    """
    loads historical data from disk, runs backtest and returns relevant metrics
    """
    config = {
        **{
            "long": deepcopy(config_["long"]),
            "short": deepcopy(config_["short"])
        },
        **{
            k: config_[k]
            for k in [
                "starting_balance",
                "latency_simulation_ms",
                "symbol",
                "market_type",
                "config_no",
            ]
        },
        **{k: v
           for k, v in config_["market_specific_settings"].items()},
    }
    if config["symbol"] in ticks_caches:
        ticks = ticks_caches[config["symbol"]]
    else:
        ticks = np.load(config_["ticks_cache_fname"])
    try:
        fills_long, fills_short, stats = backtest(config, ticks)
        longs, shorts, sdf, analysis = analyze_fills(fills_long, fills_short,
                                                     stats, config)
        pa_distance_mean_long = analysis["pa_distance_mean_long"]
        pa_distance_mean_short = analysis["pa_distance_mean_short"]
        PAD_std_long = analysis["pa_distance_std_long"]
        PAD_std_short = analysis["pa_distance_std_short"]
        adg_long = analysis["adg_long"]
        adg_short = analysis["adg_short"]
        adg_DGstd_ratio_long = analysis["adg_DGstd_ratio_long"]
        adg_DGstd_ratio_short = analysis["adg_DGstd_ratio_short"]
        """
        with open("logs/debug_harmonysearch.txt", "a") as f:
            f.write(json.dumps({"config": denumpyize(config), "analysis": analysis}) + "\n")
        """
        logging.debug(
            f"backtested {config['symbol']: <12} pa distance long {pa_distance_mean_long:.6f} "
            +
            f"pa distance short {pa_distance_mean_short:.6f} adg long {adg_long:.6f} "
            + f"adg short {adg_short:.6f} std long {PAD_std_long:.5f} " +
            f"std short {PAD_std_short:.5f}")
    except Exception as e:
        logging.error(f'error with {config["symbol"]} {e}')
        logging.error("config")
        traceback.print_exc()
        adg_long = adg_short = adg_DGstd_ratio_long = adg_DGstd_ratio_short = 0.0
        pa_distance_mean_long = pa_distance_mean_short = PAD_std_long = PAD_std_short = 100.0
        with open(make_get_filepath("tmp/harmony_search_errors.txt"),
                  "a") as f:
            f.write(
                json.dumps([time(), "error",
                            str(e),
                            denumpyize(config)]) + "\n")
    return {
        "pa_distance_mean_long": pa_distance_mean_long,
        "pa_distance_mean_short": pa_distance_mean_short,
        "adg_DGstd_ratio_long": adg_DGstd_ratio_long,
        "adg_DGstd_ratio_short": adg_DGstd_ratio_short,
        "pa_distance_std_long": PAD_std_long,
        "pa_distance_std_short": PAD_std_short,
        "adg_long": adg_long,
        "adg_short": adg_short,
    }
hls = [10, 40, 100]

for quotes, trades in data:
    features.label_data(quotes, label_hls=hls)
    features.add_ema(quotes, halflives=hls)
    features.add_dema(quotes, halflives=hls)
    features.add_momentum(quotes, halflives=hls)
    features.add_log_return_ema(quotes, halflives=hls)
    features.add_trade_momentum(quotes, trades, bar_width='second')

quotes_list, trades_list = zip(*data)
quotes = pd.concat(quotes_list)
trades = pd.concat(trades_list)

pnl_history, order_history = backtest(magic_strategy, quotes, trades,
                                      transaction_costs=0.005, slippage_rate=0.25, delay_fill=True)

fig, axes = plt.subplots(nrows=4)

axes[0].plot(quotes['DATE_TIME'].values, quotes['price'].values)

for hl in hls:
    axes[0].plot(quotes['DATE_TIME'].values, quotes['EMA_{}'.format(hl)].values)

long_orders = filter(lambda x: x[2] > 0, order_history)
short_orders = filter(lambda x: x[2] < 0, order_history)
long_order_times = map(lambda x: x[0], long_orders)
short_order_times = map(lambda x: x[0], short_orders)
long_order_prices = map(lambda x: x[3], long_orders)
short_order_prices = map(lambda x: x[3], short_orders)
Exemple #20
0
def get_lines():
    count = 0

    game_list = []
    r = {}
    while type(r) != list:
        league = input('What league? ')
        r = requests.get(
            "https://www.bovada.lv/services/sports/event/v2/events/A/description/football/"
            + league,
            verify=False).json()

    print(BORDER)
    data = r[0]
    for game in data:
        for team in data['events']:
            try:
                count += 1
                EpochTime = team['startTime']
                Epoch = datetime.datetime.fromtimestamp(EpochTime / 1e3)
                date = Epoch.strftime('%m-%d-%Y %H:%M:%S')
                team_1 = team['competitors'][0]['name'].rstrip()
                team_2 = team['competitors'][1]['name'].rstrip()
                if team_1 in game_list:
                    break
                else:
                    try:
                        odd_1_1 = team['displayGroups'][0]['markets'][1][
                            'outcomes'][0]['price']['handicap']
                    except KeyError:
                        odd_1_1 = None
                    try:
                        odd_1_2 = team['displayGroups'][0]['markets'][1][
                            'outcomes'][0]['price']['american']
                    except KeyError:
                        odd_1_2 = None
                    try:
                        odd_2_1 = team['displayGroups'][0]['markets'][1][
                            'outcomes'][1]['price']['handicap']
                    except KeyError:
                        odd_2_1 = None
                    try:
                        odd_2_2 = team['displayGroups'][0]['markets'][1][
                            'outcomes'][1]['price']['american']
                    except KeyError:
                        odd_2_2 = None
                    try:
                        ML_2 = team['displayGroups'][0]['markets'][0][
                            'outcomes'][0]['price']['american']
                    except KeyError:
                        ML_2 = None
                    try:
                        ML_1 = team['displayGroups'][0]['markets'][0][
                            'outcomes'][1]['price']['american']
                    except KeyError:
                        ML_1 = None
                    try:
                        o = team['displayGroups'][0]['markets'][2]['outcomes'][
                            0]['price']['handicap']
                    except KeyError:
                        o = None
                    try:
                        o_1 = team['displayGroups'][0]['markets'][2][
                            'outcomes'][0]['price']['american']
                    except KeyError:
                        o_1 = None
                    try:
                        u = team['displayGroups'][0]['markets'][2]['outcomes'][
                            1]['price']['handicap']
                    except KeyError:
                        o = None
                    try:
                        u_1 = team['displayGroups'][0]['markets'][2][
                            'outcomes'][1]['price']['american']
                    except KeyError:
                        o_1 = None
                    if team['displayGroups'][0]['markets'][0]['period'][
                            'live'] is True:
                        print('{0}  | {1}'.format(count, 'LIVE!'))
                    else:
                        print('{0}  |'.format(count))
                    print(date)
                    print("{0} ({1},{2}) | {3} | o({4},{5})".format(
                        team_2, odd_1_1, odd_1_2, ML_2, o, o_1))
                    print("{0} ({1},{2}) | {3} | u({4},{5})".format(
                        team_1, odd_2_1, odd_2_2, ML_1, u, u_1))
                    if team['competitors'][0]['home'] is True:
                        print(get_weather(abbrev(team_1, 'city'), date))
                    else:
                        print(get_weather(abbrev(team_2, 'city'), date))
                    print(SUBSET)
                    game_list.append(team_1)
                    game_info = [{
                        'Time': date,
                        'Away Team': team_2,
                        'odds': odd_1_1,
                        'Win': odd_1_2,
                        'Money Line': ML_2,
                        'Over': o,
                        'Over Line': o_1,
                        'Under': u,
                        'Under Line': u_1,
                        'Home Team': team_1,
                        'odds': odd_2_1,
                        'Win': odd_2_2,
                        'Money Line': ML_1
                    }]
                    backtest(game_info)
            except KeyError:
                odd_1_1 = None
            except IndexError:
                pass
Exemple #21
0
def main(strategy,scoreFile,scoreColumn):
    df = pd.read_csv(scoreFile);
    df.sort_values(['tradeDate',scoreColumn],inplace=True,ascending=False);
    dfdt = utils_common.groupDt(df);
    backtest.backtest(1000000,'0000-00-00','9999-99-99',strategy,dfdt);
    pass;
Exemple #22
0
def sf_test_multiple_pools(factor='default',
                           *,
                           direction='+',
                           bb_obj='Empty',
                           discard_factor=[],
                           holding_freq='m',
                           stock_pools=['all', 'hs300', 'zz500', 'zz800'],
                           bkt_start='default',
                           bkt_end='default',
                           select_method=0,
                           do_bb_pure_factor=False,
                           do_active_bb_pure_factor=False,
                           do_pa=False,
                           do_active_pa=False,
                           do_data_description=False):
    # 如果传入的是str,则将其传入到single factor test中去让其自己处理,如果是dataframe,则直接传入因子
    # 注意:这里的因子数据并不储存到self.strategy_data.factor中,因为循环股票池会丢失数据
    if type(factor) != str:
        factor_data = data.read_data([factor], [factor], shift=True)
        factor = factor_data[factor]
        # 初始化一个持仓对象,以用来初始化backtest对象,索引以factor为标准
        temp_position = position(factor)
    else:
        # 如过传入的是string, 则读取closeprice_adj来初始化backtest对象
        cp_adj = data.read_data(['ClosePrice_adj'])
        cp_adj = cp_adj['ClosePrice_adj']
        temp_position = position(cp_adj)

    # 先要初始化bkt对象
    bkt_obj = backtest(temp_position,
                       bkt_start=bkt_start,
                       bkt_end=bkt_end,
                       buy_cost=1.5 / 1000,
                       sell_cost=1.5 / 1000)
    # 建立bb对象,否则之后每次循环都要建立一次新的bb对象
    if bb_obj == 'Empty':
        bb_obj = barra_base()
        bb_obj.just_get_sytle_factor()
    # 外部传入的bb对象,要检测其股票池是否为all,如果不是all,则输出警告,因为可能丢失了数据
    elif bb_obj.bb_data.stock_pool != 'all':
        print(
            'The stockpool of the barra_base obj from outside is NOT "all", be aware of possibile'
            'data loss due to this situation!\n')

    # 根据股票池进行循环
    for stock_pool in stock_pools:
        # 建立单因子测试对象
        # curr_sf = single_factor_strategy()
        from analyst_coverage import analyst_coverage
        curr_sf = analyst_coverage()

        # 进行当前股票池下的单因子测试
        # 注意bb obj进行了一份深拷贝,这是因为在业绩归因的计算中,会根据不同的股票池丢弃数据,导致数据不全,因此不能传引用
        # 对bkt obj做了同样的处理,尽管这里并不是必要的
        curr_sf.single_factor_test(
            factor=factor,
            direction=direction,
            bkt_obj=copy.deepcopy(bkt_obj),
            bb_obj=copy.deepcopy(bb_obj),
            discard_factor=discard_factor,
            bkt_start=bkt_start,
            bkt_end=bkt_end,
            holding_freq=holding_freq,
            stock_pool=stock_pool,
            select_method=select_method,
            do_bb_pure_factor=do_bb_pure_factor,
            do_active_bb_pure_factor=do_active_bb_pure_factor,
            do_pa=do_pa,
            do_active_pa=do_active_pa,
            do_data_description=do_data_description)
    def run(self):
        bc = deepcopy(self.bc)

        balance_and_pos = {
            "starting_balance": bc["starting_balance"],
            "long_pprice": 0.0,
            "long_psize": 0.0,
            "shrt_pprice": 0.0,
            "shrt_psize": 0.0,
        }

        all_daily_returns = []

        for k, split in enumerate(self):
            train = split["train"]
            test = split["test"]

            print("*** STARTIN BALANCE", balance_and_pos["starting_balance"])

            self.update_config(bc, train, balance_and_pos)

            analysis = backtest_tune(
                self.ticks[train["start_idx"]:train["end_idx"]], bc)
            candidate = clean_result_config(analysis.best_config)

            self.update_config(bc, test)
            fills, stats, did_finish = backtest(
                candidate, self.ticks[test["start_idx"]:test["end_idx"]])

            _, _, result = analyze_backtest(
                fills,
                stats,
                bc,
            )

            # Update the balance and positions with the last filled values of the testing run
            balance_and_pos = {
                key: fills[-1][key]
                for key in (balance_and_pos.keys() & fills[-1].keys())
            }
            balance_and_pos["starting_balance"] = stats[-1][
                "balance"]  # Same as fills

            all_daily_returns.append(
                result["returns_daily"])  # stats is more accurate than fills
            print("*** EQUITY", stats[-1]["equity"], all_daily_returns, "\n")

            # json.dump: candidate, result, stats, fills
            # we can load these files and generate plots/reports later
            #  with open(f"/tmp/candidate_test_{k}.json", "w") as f:
            #      json.dump(candidate, f)
            #  with open(f"/tmp/res_test_{k}.json", "w") as f:
            #      json.dump(result, f)
            #  with open(f"/tmp/stats_test_{k}.json", "w") as f:
            #      json.dump(stats, f)
            #  with open(f"/tmp/fills_test_{k}.json", "w") as f:
            #      json.dump(fills, f)

        returns_gmean = np.exp(np.mean(
            np.log(np.array(all_daily_returns) + 1))) - 1
        print("Geometrical mean of all the daily returns", returns_gmean)
Exemple #24
0
    def do_opt_portfolio_test(self,
                              *,
                              start_date=None,
                              end_date=None,
                              loc=-1,
                              foldername='',
                              indus_neutral=False):
        # 生成调仓日
        self.generate_holding_days(loc=loc,
                                   start_date=start_date,
                                   end_date=end_date)

        # 初始化持仓矩阵
        self.initialize_position(
            self.strategy_data.stock_price.ix[0, self.holding_days, :])

        # 过滤不可交易数据
        self.strategy_data.handle_stock_pool(shift=True)
        self.strategy_data.discard_uninv_data()
        self.factor_return = self.factor_return.where(
            self.strategy_data.if_tradable['if_inv'], np.nan)

        # # 投资域为全市场时的tricky解法, 只保留有alpha, 且在benchmark中的股票
        # self.factor_return = self.factor_return.mask(np.logical_and(self.strategy_data.benchmark_price.iloc[0]>0,
        #         self.factor_return.isnull()), 0)

        # 解优化组合
        self.construct_optimized_portfolio(indus_neutral=indus_neutral)
        # 将优化组合中小于万分之一的持仓扔掉
        self.position.holding_matrix = self.position.holding_matrix.where(
            self.position.holding_matrix >= 1e-4, 0)

        # 如果没有路径名, 则自己创建一个
        if not os.path.exists(
                str(os.path.abspath('.')) + '/' + foldername +
                self.strategy_data.stock_pool + '/'):
            os.makedirs(
                str(
                    str(os.path.abspath('.')) + '/' + foldername +
                    self.strategy_data.stock_pool + '/'))
        # 建立画pdf的对象
        self.pdfs = PdfPages(
            str(os.path.abspath('.')) + '/' + foldername +
            self.strategy_data.stock_pool + '/allfigs.pdf')

        # 进行回测
        self.bkt_obj = backtest(self.position,
                                bkt_start=start_date,
                                bkt_end=end_date,
                                bkt_benchmark_data='ClosePrice_adj_' +
                                self.strategy_data.benchmark)
        self.bkt_obj.execute_backtest()
        self.bkt_obj.get_performance(foldername=foldername +
                                     self.strategy_data.stock_pool,
                                     pdfs=self.pdfs)

        # 根据策略的超额净值, 可以计算策略的实现的超额收益波动率, 对比实现波动率和预测波动率, 可以看出风险预测能力
        # 由于是周5换仓, 因此实现的区间为周5到下周4, 标签选择周5, 因此选择的resample区间为周五开始, 周五结束
        # 闭区间选择为left, 即这周五, 标签也选择为left, 即这周五, 这样就能和预测风险的标签相吻合
        active_nav_ret_std = self.bkt_obj.bkt_performance.active_nav.pct_change(). \
            resample('w-fri', closed='left', label='left').std().mul(np.sqrt(252))
        # 统计量为实现波动率除以预测波动率
        self.risk_pred_ratio = active_nav_ret_std / self.forecasted_vol
        # 实现波动率储存起来以供参考
        self.realized_vol = active_nav_ret_std
        # 打印统计量的均值和方差
        str_risk = 'Risk forecast accuracy ratio, mean: {0}, std: {1}\n'. \
            format(self.risk_pred_ratio.mean(), self.risk_pred_ratio.std())
        print(str_risk)
        # 根据优化组合算每期组合的预期alpha
        self.forecasted_alpha = self.position.holding_matrix.mul(
            self.factor_return.reindex(
                index=self.position.holding_matrix.index)).sum(1)
        # 打印组合的预期alpha均值和方差
        str_alpha = 'Alpha forecast, mean: {0}, std: {1}\n'. \
            format(self.forecasted_alpha.mean(), self.forecasted_alpha.std())
        print(str_alpha)

        # 将风险预测统计量, 预期alpha, 以及风险厌恶系数等量写入txt文件
        target_str = str_risk + str_alpha
        target_str += 'Cov Mat risk aversion: {0}, Spec Var risk aversion: {1}\n'. \
            format(self.cov_risk_aversion, self.spec_risk_aversion)
        with open(str(os.path.abspath('.')) + '/' + foldername +
                  self.strategy_data.stock_pool + '/performance.txt',
                  'a',
                  encoding='GB18030') as text_file:
            text_file.write(target_str)

        # 做真实情况下的超额归因
        pa_benchmark_weight = data.read_data(
            'Weight_' + self.strategy_data.benchmark).fillna(0.0)
        # pa_benchmark_weight = data.read_data(['Weight_hs300'],
        #                                      ['Weight_hs300'])
        # pa_benchmark_weight = pa_benchmark_weight['Weight_hs300']

        self.bkt_obj.get_performance_attribution(
            benchmark_weight=pa_benchmark_weight,
            show_warning=False,
            pdfs=self.pdfs,
            is_real_world=True,
            foldername=foldername + self.strategy_data.stock_pool,
            real_world_type=2,
            enable_read_pa_return=True,
            base_stock_pool=self.strategy_data.stock_pool)

        self.pdfs.close()
Exemple #25
0
s0, r, var_type, method, window_length, VaR_Horizon, VaRp, evaluation, simulations = loadInputs()
stocks, stock_weights = loadStockInputs()
options, option_type, option_wgt = loadOptionInputs()

stock_prices, stock_dates = loadPrices(stocks)

implied_vol, option_dates = loadOptions(options)


# Calibrate Portfolio
stock_prices, portVal, portDt = calibratePortfolio(stocks, options, option_type, option_wgt, r, stock_prices, stock_dates, option_dates, stock_weights, implied_vol, s0)

# Calculate VaR, Loss and Backtest
if var_type == 'Par GBM':
    var = gbmVaR(stock_weights, method, window_length, portVal, s0, VaRp, VaR_Horizon)
    bt, loss = backtest(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, var, stock_weights, VaR_Horizon, evaluation, s0)
elif var_type == 'Par BM':
    var = ParVaR(stocks, options, option_type, option_wgt, implied_vol, r, stock_prices, stock_weights, s0, VaR_Horizon, window_length, evaluation, VaRp, method)
    bt, loss = backtest(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, var, stock_weights, VaR_Horizon, evaluation, s0)
elif var_type == 'Hist':
    var = HistVaR(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, stock_weights, s0, VaR_Horizon, window_length, evaluation, VaRp)
    bt, loss = backtest(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, var, stock_weights, VaR_Horizon, evaluation, s0)
elif var_type == 'MC GBM':
    var = MonteCarloVaR_GBM(portVal, method, window_length, VaR_Horizon, evaluation, VaRp, s0, simulations)
    bt, loss = backtest(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, var, stock_weights, VaR_Horizon, evaluation, s0)
elif var_type == 'MC BM':
    var = MonteCarloVaR(stocks, options, option_type, option_wgt, implied_vol, r, stock_prices, stock_weights, s0, VaR_Horizon, window_length, evaluation, VaRp, method, simulations)
    bt, loss = backtest(stocks, options, implied_vol, option_type, option_wgt, r, stock_prices, var, stock_weights, VaR_Horizon, evaluation, s0)
else:
    print('Incorrect VaR Type. Check Inputs')
Exemple #26
0
    cv_split = 0.05

    ticker = input("Choose a Ticker to Model: ")

    df, Close_list = prepare_data(ticker)

    X_full2d, X_full3d, Y, X_train2d, X_test2d, X_train3d, X_test3d, y_train, y_test, split_value = flatten_dataset(
        df, test_size=cv_split)

    model, history, predictions, targets = lstm_train(X_full2d,
                                                      X_full3d,
                                                      Y,
                                                      X_train2d,
                                                      X_test2d,
                                                      X_train3d,
                                                      X_test3d,
                                                      y_train,
                                                      y_test,
                                                      batch_size=100,
                                                      epochs=10)

    backtest(predictions,
             10000,
             Close_list,
             targets,
             ticker,
             split_value,
             sell_tolerance=0.5,
             buy_tolerance=0.5)
Exemple #27
0
def main(strategy, startDt, endDt, initMoney):
    decFactor = utils_server.getDecFactors(startDt, endDt)
    decFactor = {k: filterDf(df) for k, df in decFactor.items()}

    backtest.backtest(initMoney, startDt, endDt, strategy, decFactor)
    pass
Exemple #28
0
from get_dayprice import collect_dayprice_everyday
from generate_training_test_data import generate_training_test_data
from generate_ARIMA_model import generate_ARIMA_model
from backtest import backtest
if __name__ == '__main__':

    collect_dayprice_everyday()
    generate_training_test_data()
    generate_ARIMA_model()
    backtest()
Exemple #29
0
def main(argv):
    period = 0
    pair = ''
    kpair = ''
    linearPair = ''
    checkLastPrice = False
    showCurrentBalance = False
    forecast = False
    testSymbol = ''
    buyParams = ''
    sellParams = ''
    cancelParams = ''
    predictPair = ''
    backtestParams = ''

    try:
        opts, args = getopt.getopt(argv, "efwlhp:c:k:m:t:b:s:x:a:r:", [
            "period=", "asset=", "klines=", "model=", "test=", "buy=", "sell=",
            "cancel=", "predict=", "btest="
        ])
    except getopt.GetoptError:
        help()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-p", "--period"):
            period = arg
        elif opt in ("-c", "--asset"):
            pair = arg
        elif opt == '-h':
            help()
        elif opt == '-l':
            checkLastPrice = True
        elif opt == '-w':
            showCurrentBalance = True
        elif opt in ("-k", "--klines"):
            kpair = arg
        elif opt in ("-m", "--model"):
            linearPair = arg
        elif opt == '-f':
            forecast = True
        elif opt == '-e':
            exchange_info = client.get_exchange_info()
            rate_limits = exchange_info['rateLimits']
            for r in rate_limits:
                print(
                    f"{r['rateLimitType']} per {r['interval']}: {r['limit']}")
        elif opt in ("-t", "--test"):
            testSymbol = arg
        elif opt in ("-b", "--buy"):
            buyParams = arg
        elif opt in ("-s", "--sell"):
            sellParams = arg
        elif opt in ("-x", "--cancel"):
            cancelParams = arg
        elif opt in ("-a", "--predict"):
            predictPair = arg
        elif opt in ("-r", "--btest"):
            backtestParams = arg

    while True:
        if (backtestParams):
            params_arr = backtestParams.split("_")
            bt = backtest.backtest(client, params_arr[0], params_arr[1],
                                   params_arr[2])
            bt.testModel()

        if (cancelParams):
            trade.cancelAllOrders(client, cancelParams)

        if (sellParams):
            params_arr = sellParams.split("_")
            print(params_arr)
            trade.sellOrder(client, params_arr[0], params_arr[1],
                            params_arr[2])

        if (buyParams):
            params_arr = buyParams.split("_")
            print(params_arr)
            trade.buyOrder(client, params_arr[0], params_arr[1], params_arr[2])

        if (testSymbol):
            print(datetime.now())
            t0 = time.time()
            if (testSymbol == 'ALL') or (testSymbol == 'all'):
                filename1 = datetime.now().strftime("%Y%m%d-%H%M%S")
                #open('output.txt', 'w').close()
                sys.stdout = open(f'output/{filename1}.txt', 'w')

                print(datetime.now())
                prices = client.get_all_tickers()
                marketsymbols = []
                ta = []
                for symbol in prices:
                    if symbol['symbol'][-3:] == 'BTC':
                        marketsymbols.append(symbol['symbol'])

                for symbol in marketsymbols:
                    ta.append(test.testMethod(client, symbol, True))

                ta = list(filter(None.__ne__, ta))
                print("Stoch K lower than 20")
                for t in ta:
                    if (t['slowk'] <= 20):
                        if (t['macd'] <= t['macdsignal']):
                            if (t['price'] <= t['middleband']):
                                test.printOutputs(t)

                print("\n-------------------------------")
                print("Stoch K lower than D")

                for t in ta:
                    if (t['slowk'] <= 80 and t['slowk'] <= t['slowd']):
                        if (t['macd'] <= t['macdsignal']):
                            if (t['price'] <= t['middleband']):
                                test.printOutputs(t)

                sys.stdout.close()
                sys.stdout = sys.__stdout__
                print(f'Results displayed in output/{filename1}.txt')
            else:
                t0 = time.time()
                test.printOutputs(test.testMethod(client, testSymbol, False))
                t1 = time.time()
                total = t1 - t0
                #print(total)
            t1 = time.time()
            total = t1 - t0
            print(f"Finished in: {total}")

        if (checkLastPrice):
            printLastMarketPrices()

        if (showCurrentBalance):
            printCurrentAssets()

        if (kpair):
            printKlines(kpair)

        if (forecast):
            prices = client.get_all_tickers()
            marketsymbols = []
            for symbol in prices:
                if symbol['symbol'][-3:] == 'BTC':
                    marketsymbols.append(symbol['symbol'])

            for symbol in marketsymbols:
                candles = client.get_klines(
                    symbol=symbol, interval=Client.KLINE_INTERVAL_5MINUTE)
                depth = client.get_order_book(symbol=symbol)
                predict.linearRegressionModel(symbol, candles, depth)

        if (predictPair):
            candles = client.get_klines(symbol=predictPair,
                                        interval=Client.KLINE_INTERVAL_4HOUR,
                                        limit=100)
            depth = client.get_order_book(symbol=predictPair)
            predict.linearRegressionModel(predictPair, candles, depth)

        if (pair):
            printCurrentAssetBalance(pair)
            #
            #printCurrentAssets(info)
            #printLastPrices(prices)

        if (int(period) > 0):
            time.sleep(int(period))
        else:
            sys.exit()
def main(strategy, startDt,endDt,initMoney):
    decFactor = utils_server.getDecFactors(startDt,endDt);
    decFactor = {k:filterDf(df) for k,df in decFactor.items()}
    
    backtest.backtest(initMoney,startDt,endDt,strategy,decFactor);
    pass;
Exemple #31
0
def main():
    ''' 标的 '''
    code = '000300'
    ''' 个股 '''
    code = '000016'
    img_path = './img/' + code
    train_s_date = '2005-01-01'  # 训练集时间范围
    train_e_date = '2010-12-31'
    test_s_date = '2011-01-01'  # 测试集时间范围
    test_e_date = '2017-12-31'
    # test_e_date = datetime.datetime.now().strftime('%Y-%m-%d')
    shutil.rmtree(img_path)
    os.mkdir(img_path)
    is_feature_select = False  # 是否特征选择
    is_standardize = False  # 是否标准化
    maxperiod = 33  # 生成属性的最大周期

    index_hist_train_df = dao.get_local_bar_data(code, train_s_date,
                                                 train_e_date)  # 获取训练集
    index_hist_test_df = dao.get_local_bar_data(code, test_s_date,
                                                test_e_date)  # 获取测试集
    index_hist_train_df.sort_index(inplace=True)  # 按照日期排序
    index_hist_test_df.sort_index(inplace=True)  # 按照日期排序
    train_datelist = pd.to_datetime(
        index_hist_train_df.close.index[maxperiod + 1:])  # 获取训练集的日期列表
    train_closeidx = index_hist_train_df.close[maxperiod + 1:]  # 获取训练集每日收盘价
    test_datelist = pd.to_datetime(
        index_hist_test_df.close.index[maxperiod + 1:])  # 获取测试集的日期列表
    test_closeidx = index_hist_test_df.close[maxperiod + 1:]  # 获取测试集每日收盘价
    # train
    train_X, train_logreturn = features.gen_attrs(img_path,
                                                  index_hist_train_df,
                                                  maxperiod)  # 生成属性
    # test
    test_X, test_logreturn = features.gen_attrs(img_path, index_hist_test_df,
                                                maxperiod)  # 生成属性
    # train hmm model
    hmm = GaussianHMM(n_components=5,
                      covariance_type='diag',
                      n_iter=1000000,
                      algorithm='viterbi',
                      random_state=0)
    hmm = hmm.fit(train_X)  # 训练HMM
    latent_states_sequence_train = simulate_predict(train_X,
                                                    hmm)  # 训练集模拟每天预测一天
    draw_result(img_path, train_datelist, train_closeidx,
                latent_states_sequence_train, hmm)  # 训练集状态图
    draw_back(img_path, train_datelist, train_logreturn,
              latent_states_sequence_train, hmm)  # 训练集收益曲线
    latent_states_sequence_test = simulate_predict(test_X, hmm)  # 测试集模拟每天预测一天
    latent_states_sequence_test[:-1].tofile('states_sequence.csv',
                                            sep=',')  # 保存模拟预测每日状态
    draw_result(img_path, test_datelist, test_closeidx,
                latent_states_sequence_test, hmm)  # 测试集状态图
    selected_states = draw_back(img_path, test_datelist, test_logreturn,
                                latent_states_sequence_test, hmm)  # 测试集收益曲线
    print(selected_states)
    joblib.dump(hmm, 'model/hmm_50.m')  # 本地化模型

    # 本地回测
    latent_states_sequence_backtest = latent_states_sequence_test[
        len(latent_states_sequence_train):]
    import backtest
    backtest.backtest(latent_states_sequence_backtest, [0, 1, 2],
                      dao.get_local_bar_data(code, '2015-01-01', '2017-12-31'))
    # joblib.dump(min_max_scaler, 'model/std.m')    # 数据标准化模型
    features.gen_attrs(
        img_path, dao.get_local_bar_data(code, '2010-01-01', '2017-12-31'), 10)
Exemple #32
0
    def single_factor_test(self,
                           *,
                           factor='default',
                           direction='+',
                           bkt_obj='Empty',
                           bb_obj='Empty',
                           pa_benchmark_weight='default',
                           discard_factor=[],
                           bkt_start='default',
                           bkt_end='default',
                           stock_pool='all',
                           select_method=0,
                           do_pa=True,
                           do_active_pa=False,
                           do_bb_pure_factor=False,
                           do_active_bb_pure_factor=False,
                           holding_freq='m',
                           do_data_description=False):
        ###################################################################################################
        # 生成调仓日和生成可投资标记是第一件事, 因为之后包括因子构建的函数都要用到它

        # 生成调仓日
        if self.holding_days.empty:
            self.generate_holding_days(holding_freq=holding_freq)

        # 将策略的股票池设置为当前股票池
        self.strategy_data.stock_pool = stock_pool
        # 根据股票池生成标记
        self.strategy_data.handle_stock_pool(shift=True)

        ###################################################################################################
        # 第二部分是读取或生成要研究的因子

        # 如果传入的是str,则读取同名文件,如果是dataframe,则直接传入因子
        if type(factor) == str:
            if factor != 'default':
                self.read_factor_data([factor], [factor], shift=True)
            else:
                # 如果传入的是'default', 那么首先看策略类本身是否有内部构建其因子的函数
                self.construct_factor()
            # 检测是否已经有因子存在,1. 因子是由策略类内部自身构建的
            # 2. 有可能该实例化的类已经有了计算好的要测试的因子
            if self.strategy_data.factor.shape[0] >= 1:
                print(
                    'The factor has been set to be the FIRST one in strategy_data.factor\n'
                )
            elif self.strategy_data.factor_expo.shape[0] >= 1:
                self.strategy_data.factor = self.strategy_data.factor_expo
                print(
                    'The factor data has been copied from factor_expo data, and the factor will be'
                    'the FIRST one in strategy_data.factor_expo\n')
            else:
                print(
                    'Error: No factor data, please try to specify a factor!\n')
        elif self.strategy_data.factor.empty:
            self.strategy_data.factor = pd.Panel({'factor_one': factor})
        else:
            self.strategy_data.factor.iloc[0] = factor

        ###################################################################################################
        # 第三部分是除去不可投资的数据, 初始化或者重置策略持仓,
        # 处理barra base类, backtest类, 以及建立文件夹等零碎的事情

        # 除去不可交易或不可投资的数据
        # 注意,对策略数据的修改是永久性的,无法恢复,因此在使用过某个股票池的单因子测试后,对策略数据的再使用要谨慎
        if self.strategy_data.stock_pool == 'all':
            self.strategy_data.discard_untradable_data()
        else:
            self.strategy_data.discard_uninv_data()

        # 初始化持仓或重置策略持仓
        if self.position.holding_matrix.empty:
            self.initialize_position(
                self.strategy_data.factor.ix[0, self.holding_days, :])
        else:
            self.reset_position()

        # 如果有传入的bb对象
        if bb_obj == 'Empty':
            pass
        else:
            # 将bb的股票池改为当前股票池
            bb_obj.bb_data.stock_pool = stock_pool
            # 根据股票池生成标记,注意:股票池数据不需要shift,因为这里的barrabase数据是用来事后归因的,不涉及策略构成
            bb_obj.bb_data.handle_stock_pool(shift=False)

        # 将回测的基准改为当前的股票池,若为all,则用默认的基准值
        if stock_pool != 'all':
            bkt_obj.reset_bkt_benchmark(['ClosePrice_adj_' + stock_pool])

        # 如果没有文件夹,则建立一个文件夹
        if not os.path.exists(
                str(os.path.abspath('.')) + '/' +
                self.strategy_data.stock_pool + '/'):
            os.makedirs(
                str(os.path.abspath('.')) + '/' +
                self.strategy_data.stock_pool + '/')
        # 建立画pdf的对象
        self.pdfs = PdfPages(
            str(os.path.abspath('.')) + '/' + self.strategy_data.stock_pool +
            '/allfigs.pdf')

        ###################################################################################################
        # 第四部分为, 1. 若各策略类有对原始因子数据的计算等, 可以在data description中进行
        # 2. 根据选择的一组因子base(可以是barra的, 也可以不是), 进行与当前因子的相关性检验
        # 3. 根据选择的一组因子base, 对当前因子进行提纯, 注意尽管与2差不多, 但是这里使得2, 3可以选择不同的base以及提纯方法
        # 4. 未来还可添加: 如果是基础财务因子, 还可以添加对净利润增长的预测情况

        # 如果有对原始数据的表述,则进行原始数据表述
        if do_data_description:
            self.data_description()
            print('Data description completed...\n')

        # # 根据某一base, 做当前因子与其他因子的相关性检验
        # if do_factor_corr_test:
        #     self.get_factor_corr_test()

        # 如果要做基于barra base的纯因子组合,则要对因子进行提纯
        if do_bb_pure_factor:
            self.get_pure_factor(
                bb_obj, do_active_bb_pure_factor=do_active_bb_pure_factor)

        ###################################################################################################
        # 第五部分为, 1.根据不同的单因子选股策略, 进行选股
        # 2. 对策略选出的股票进行回测, 画图
        # 3. 如果有归因, 则对策略选出的股票进行归因

        # 按策略进行选股
        if select_method == 0:
            # 简单分位数选股
            self.select_stocks(weight=1,
                               direction=direction,
                               select_ratio=[0.8, 1])
        elif select_method == 1:
            # 分行业选股
            self.select_stocks_within_indus(weight=2, direction=direction)
        elif select_method == 2 or select_method == 3:
            # 用构造纯因子组合的方法选股,2为组合自己是纯因子组合,3为组合相对基准是纯因子组合
            # 首先和计算纯因子一样,要计算bb因子的暴露
            if bb_obj.bb_data.factor_expo.empty:
                bb_obj.just_get_factor_expo()
            # 同样需要lag
            lag_bb_expo = bb_obj.bb_data.factor_expo.shift(1).reindex(
                major_axis=bb_obj.bb_data.factor_expo.major_axis)
            # 同样不能有country factor
            lag_bb_expo_no_cf = lag_bb_expo.drop('country_factor', axis=0)
            # # 构造纯因子组合,权重使用回归权重,即市值的根号
            # 初始化temp weight为'Empty',即如果选股方法是2,则传入默认的benchmark weight
            temp_weight = 'Empty'
            if select_method == 2:
                # self.select_stocks_pure_factor_bb(bb_expo=lag_bb_expo_no_cf, reg_weight=np.sqrt(
                #     self.strategy_data.stock_price.ix['FreeMarketValue']), direction=direction)
                self.select_stocks_pure_factor(
                    base_expo=lag_bb_expo_no_cf,
                    reg_weight=np.sqrt(
                        self.strategy_data.stock_price.ix['FreeMarketValue']),
                    direction=direction,
                    benchmark_weight=temp_weight,
                    is_long_only=False)
            if select_method == 3 and self.strategy_data.stock_pool == 'all':
                temp_weight = data.read_data(['Weight_zz500'],
                                             ['Weight_zz500'],
                                             shift=True)
                temp_weight = temp_weight['Weight_zz500']
            elif select_method == 3 and self.strategy_data.stock_pool != 'all':
                # 注意股票池为非全市场时,基准的权重数据已经shift过了
                temp_weight = self.strategy_data.benchmark_price.ix[
                    'Weight_' + self.strategy_data.stock_pool]
            if select_method == 3:
                self.select_stocks_pure_factor(
                    base_expo=lag_bb_expo_no_cf,
                    reg_weight=np.sqrt(
                        self.strategy_data.stock_price.ix['FreeMarketValue']),
                    direction=direction,
                    benchmark_weight=temp_weight,
                    is_long_only=True)

        # ------------------------------------------------------------------------------------
        # holding = pd.read_csv('HOLDING500.csv', index_col=0, parse_dates=True)
        # new_col = []
        # for curr_stock in holding.columns:
        #     new_col.append(curr_stock.zfill(6))
        # holding.columns = new_col
        # self.position.holding_matrix = holding.reindex(self.position.holding_matrix.index,
        #                             self.position.holding_matrix.columns, method='ffill').fillna(0.0)
        # pass

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

        # 如果有外来的backtest对象,则使用这个backtest对象,如果没有,则需要自己建立,同时传入最新持仓
        if bkt_obj == 'Empty':
            bkt_obj = backtest(self.position,
                               bkt_start=bkt_start,
                               bkt_end=bkt_end)
        else:
            bkt_obj.reset_bkt_position(self.position)
        # 将回测的基准改为当前的股票池,若为all,则用默认的基准值
        if stock_pool != 'all':
            bkt_obj.reset_bkt_benchmark(['ClosePrice_adj_' + stock_pool])

        # 回测、画图、归因
        bkt_obj.execute_backtest()
        bkt_obj.get_performance(foldername=stock_pool, pdfs=self.pdfs)

        # 如果要进行归因的话
        if do_pa:
            # 如果指定了要做超额收益的归因,且有股票池,则用相对基准的持仓来归因
            # 而股票池为全市场时的超额归因默认基准为中证500
            if do_active_pa and self.strategy_data.stock_pool != 'all':
                # 注意:策略里的strategy_data里的数据都是shift过后的,而进行归因的数据和回测一样,不能用shift数据,要用当天最新数据
                pa_benchmark_weight = data.read_data(
                    ['Weight_' + self.strategy_data.stock_pool],
                    ['Weight_' + self.strategy_data.stock_pool])
                pa_benchmark_weight = pa_benchmark_weight[
                    'Weight_' + self.strategy_data.stock_pool]
            elif do_active_pa and self.strategy_data.stock_pool == 'all':
                temp_weight = data.read_data(['Weight_zz500'],
                                             ['Weight_zz500'])
                pa_benchmark_weight = temp_weight['Weight_zz500']
            # 注意bb obj进行了一份深拷贝,这是因为在业绩归因的计算中,会根据不同的股票池丢弃数据,导致数据不全,因此不能传引用
            bkt_obj.get_performance_attribution(
                outside_bb=bb_obj,
                benchmark_weight=pa_benchmark_weight,
                discard_factor=discard_factor,
                show_warning=False,
                foldername=stock_pool,
                pdfs=self.pdfs,
                is_real_world=False,
                real_world_type=2,
                enable_reading_pa_return=False)

        ###################################################################################################
        # 第六部分为, 1. 根据回归算单因子的纯因子组合收益率
        # 2. 计算单因子的ic序列
        # 3. 单因子选股策略的n分位图
        # 4. 画单因子策略n分位图的long-short图

        # 画单因子组合收益率
        self.get_factor_return(weights=np.sqrt(
            self.strategy_data.stock_price.ix['FreeMarketValue']),
                               holding_freq='w',
                               direction=direction,
                               start=bkt_start,
                               end=bkt_end)
        # 画ic的走势图
        self.get_factor_ic(direction=direction,
                           holding_freq='w',
                           start=bkt_start,
                           end=bkt_end)
        # 画分位数图和long short图
        self.plot_qgroup(bkt_obj, 3, direction=direction, value=1, weight=1)

        ###################################################################################################
        # 第七部分, 最后的收尾工作

        self.pdfs.close()
Exemple #33
0
#             learning_rate=0.003,
#             n_iter=100)

mlp_clf = mlp.Classifier(
    layers=[
        mlp.Layer("Sigmoid", units=5),
        mlp.Layer("Softmax", units=3)],
    learning_rule="sgd",
    learning_rate=0.003,
    n_iter=150)

# auto_encoder.fit(X.values)
# auto_encoder.transfer(mlp_clf)
mlp_clf.fit(X.values, y.values)

pnl_history, order_history = backtest(testing_quotes, testing_trades, nn_strategy,
                                      transaction_costs=0.005, slippage_rate=0.25, delay_fill=True, nn_clf=mlp_clf)

fig, axes = plt.subplots(nrows=4)

axes[0].plot(quotes['DATE_TIME'].values, quotes['price'].values)

for hl in hls:
    axes[0].plot(quotes['DATE_TIME'].values, quotes['EMA_{}'.format(hl)].values)

long_orders = filter(lambda x: x[2] > 0, order_history)
short_orders = filter(lambda x: x[2] < 0, order_history)
long_order_times = map(lambda x: x[0], long_orders)
short_order_times = map(lambda x: x[0], short_orders)
long_order_prices = map(lambda x: x[3], long_orders)
short_order_prices = map(lambda x: x[3], short_orders)
import yfinance as yf
import numpy as np
import pandas as pd
import datetime
from dataSource import data_source
from trade_Robot import trade_Robot
from wallet import wallet
from backtest import backtest
from strategy_01 import strategy_01

st = strategy_01()
m = backtest("TSLA", 1000000, st, '2021-03-01', datetime.date.today())
m.execute()