Пример #1
0
def SMA_cross(data):
    sma50 = data.rolling(50).mean()
    sma200 = data.rolling(200).mean()
    
    tw = sma200.copy()
    tw[sma50 > sma200] = 1.0
    tw[sma50 <= sma200] = -1.0
    
    tw[sma200.isnull()] = 0.0
    
    tmp = bt.merge(tw, data, sma50, sma200)
    tmp.columns = ["tw", "price", "sma50", "sma200"]
    # tmp.columns = ['tw', 'price', 'sma50', 'sma200']
    ax = tmp.plot(figsize = (15, 5), secondary_y = ["tw"])
    plt.savefig("smacross.png")
    
    ma_cross = bt.Strategy("ma_cross",
    [WeighTarget(tw),
     bt.algos.Rebalance()
    ])
    t = bt.Backtest(ma_cross, data)
    res = bt.run(t)
    res.display()
    
    res.plot()
    plt.savefig("smacross_res")
Пример #2
0
def SMA(data):
    sma = data.rolling(50).mean()
    plot = bt.merge(data, sma).plot(figsize=(15, 5))
    plt.savefig("sma.png")
    
    # 建立策略
    s = bt.Strategy("above50sma",
        [SelectWhere(data > sma),
         bt.algos.WeighEqually(),
         bt.algos.Rebalance()
        ])
    # 建立回测
    t = bt.Backtest(s, data)
    # 执行回测
    res = bt.run(t)
    # 输出结果
    res.display()
    res.plot()
    plt.savefig("sma_result.png")
    
    # 多种策略的测试
    sma10 = above_sma(data, sma_per = 10, name = "sma10")
    sma20 = above_sma(data, sma_per = 10, name = "sma20")
    sma40 = above_sma(data, sma_per = 10, name = "sma40")
    base_line = baseTest(data)
    
    # 一起运行回测
    res2 = bt.run(sma10, sma20, sma40, base_line)
    # 输出结果
    res2.display()
    res2.plot()
    plt.savefig("sma.png")
    plt.savefig("multi_sma_result.png")
Пример #3
0
import bt
import talib

# Construct the signal
signal[stock_rsi > 70] = -1
signal[stock_rsi < 30] = 1
signal[(stock_rsi <= 70) & (stock_rsi >= 30)] = 0

# Merge the data
combined_df = bt.merge(signal, price_data)
combined_df.columns = ['signal', 'Price']
combined_df.plot(secondary_y=['signal'])
plt.show()


# Define the strategy
bt_strategy = bt.Strategy('RSI_MeanReversion', 
                          [bt.algos.WeighTarget(signal),
                           bt.algos.Rebalance()])

# Create the backtest and run it
bt_backtest = bt.Backtest(bt_strategy, price_data)
bt_result = bt.run(bt_backtest)
# Plot the backtest result
bt_result.plot(title='Backtest result')
plt.show()
Пример #4
0
### Finds optimal SMA cross settings and return percentage
# [best_low, best_high, best_percentage] = sma_cross_optimal_values(data, sma_low_bot, sma_low_top, sma_high_bot, sma_high_top, within_percentage)

### Get SMA based on the data
# sma_low_plot = pd.rolling_mean(data, best_low)
# sma_high_plot = pd.rolling_mean(data, best_high)
#
# plot = bt.merge(data, sma_low_plot, sma_high_plot).plot()
############################
### Finds optimal SMA value for price crossing the SMA line
# [best_sma, best_percentage] = above_sma_optimal_value(data, 5, sma_high_top, within_percentage)

### Get SMA based on the data
# sma_best_plot = pd.rolling_mean(data, best_sma)

# Do final test to print full results
test = above_sma(data, best_sma)
results = bt.run(test)

# Display graphical plot of the data
plot = bt.merge(data, sma_best_plot).plot()
results.plot()
results.display_monthly_returns()

results.display()
# Necessary to show matlibplot graphic produced with res.plot()
plt.show()

results.values()
Пример #5
0
#all_loaded_data = load_data('600519,000858,601318,600036,603288,600276,600900,600887', do_normalize_data)
all_loaded_data = load_data('600732', do_normalize_data)
bench_data = load_data('sh000001', do_normalize_data)

start_date = '20210501'
end_date = '20210630'

print(start_date, end_date)

all_data = panel = create_dataframe(all_loaded_data, 'close')
bench_data = create_dataframe(bench_data, 'close')

panel = filter_dataframe(panel, start_date, end_date)
bench_data = filter_dataframe(bench_data, start_date, end_date)

bt.merge(panel).plot()
plt.show()

# create the strategy
from strategy.rsi_25_75_talib import create_strategy
from strategy.r3 import create_strategy as r3_create_strategy
from strategy.sma import above_sma, long_only_ew
from strategy.macd_talib import create_strategy as macd_create_strategy
from strategy.ibs import create_strategy as ibs_create_strategy
from strategy.ibs_rsi import create_strategy as ibs_rsi_create_strategy

ss = bt.Strategy('s1', [
    bt.algos.RunMonthly(),
    bt.algos.SelectAll(),
    bt.algos.WeighEqually(),
    bt.algos.Rebalance()
Пример #6
0
import bt
import matplotlib.pyplot as plt

# Construct the signal
signal[EMA_short > EMA_long] = 1
signal[EMA_short < EMA_long] = -1

# Merge the data
combined_df = bt.merge(signal, price_data, EMA_short, EMA_long)
combined_df.columns = ['Signal', 'Price', 'EMA_short', 'EMA_long']
# Plot the signal, price and MAs
combined_df.plot(secondary_y=['Signal'])
plt.show()

# Define the strategy
bt_strategy = bt.Strategy('EMA_crossover',
                          [bt.algos.WeighTarget(signal),
                           bt.algos.Rebalance()])

# Create the backtest and run it
bt_backtest = bt.Backtest(bt_strategy, price_data)
bt_result = bt.run(bt_backtest)

# Plot the backtest result
bt_result.plot(title='Backtest result')
plt.show()
Пример #7
0
def rsi_strat(ticker: str, start_date: Union[datetime, str],
              other_args: List[str]):
    """Strategy that buys when the stock is less than a threshold and shorts when it exceeds a threshold.

    Parameters
    ----------
    ticker : str
        Stock to test
    start : Union[str, datetime]
        Backtest start date.  Can be either string or datetime
    other_args : List[str]
        List of argparse arguments
    """
    parser = argparse.ArgumentParser(
        add_help=False,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        prog="rsi_strat",
        description="""Strategy that buys when the stock is less than a threshold
        and shorts when it exceeds a threshold.""",
    )
    parser.add_argument(
        "-p",
        "--periods",
        dest="periods",
        help="Number of periods for RSI calculation",
        type=check_positive,
        default=14,
    )
    parser.add_argument(
        "-u",
        "--high",
        default=70,
        dest="high",
        type=check_positive,
        help="High (upper) RSI Level",
    )
    parser.add_argument("-l",
                        "--low",
                        default=30,
                        dest="low",
                        type=check_positive,
                        help="Low RSI Level")
    parser.add_argument(
        "--spy",
        action="store_true",
        default=False,
        help="Flag to add spy hold comparison",
        dest="spy",
    )
    parser.add_argument(
        "--no_bench",
        action="store_true",
        default=False,
        help="Flag to not show buy and hold comparison",
        dest="no_bench",
    )
    parser.add_argument(
        "--no_short",
        action="store_false",
        default=True,
        dest="shortable",
        help="Flag that disables the short sell",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, other_args)
        if not ns_parser:
            return

        if ns_parser.high < ns_parser.low:
            print("Low RSI value is higher than Low RSI value\n")
            return

        ticker = ticker.lower()
        # prices = bt.get(ticker, start=start_date)
        prices = get_data(ticker, start_date)
        rsi = pd.DataFrame(ta.rsi(prices[ticker], ns_parser.periods))
        rsi.columns = [ticker]

        signal = 0 * rsi.copy()
        signal[rsi > ns_parser.high] = -1
        signal[rsi < ns_parser.low] = 1
        signal[rsi.isnull()] = 0

        merged_data = bt.merge(signal, prices)
        merged_data.columns = ["signal", "price"]

        bt_strategy = bt.Strategy(
            "RSI Reversion",
            [bt.algos.WeighTarget(signal),
             bt.algos.Rebalance()])
        bt_backtest = bt.Backtest(bt_strategy, prices)

        if ns_parser.spy:
            spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
            if ns_parser.no_bench:
                res = bt.run(bt_backtest, spy_bt)
            else:
                stock_bt = buy_and_hold(ticker, start_date,
                                        ticker.upper() + " Hold")
                res = bt.run(bt_backtest, spy_bt, stock_bt)
        else:
            if ns_parser.no_bench:
                res = bt.run(bt_backtest)
            else:
                stock_bt = buy_and_hold(ticker, start_date,
                                        ticker.upper() + " Hold")
                res = bt.run(bt_backtest, stock_bt)

        plot_bt(res,
                f"RSI Strategy between ({ns_parser.low}, {ns_parser.high})")
        print(res.display(), "\n")

    except Exception as e:
        print(e, "\n")
Пример #8
0
def ema_cross(ticker: str, start_date: Union[str, datetime],
              other_args: List[str]):
    """Strategy where we go long/short when EMA(short) is greater than/less than EMA(short)

    Parameters
    ----------
    ticker : str
        Stock to test
    start : Union[str, datetime]
        Backtest start date.  Can be either string or datetime
    other_args : List[str]
        List of argparse arguments
    """
    parser = argparse.ArgumentParser(
        add_help=False,
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        prog="ema_cross",
        description=
        "Cross between a long and a short Exponential Moving Average.",
    )
    parser.add_argument(
        "-l",
        "--long",
        default=50,
        dest="long",
        type=check_positive,
        help="Long EMA period",
    )
    parser.add_argument(
        "-s",
        "--short",
        default=20,
        dest="short",
        type=check_positive,
        help="Short EMA period",
    )
    parser.add_argument(
        "--spy",
        action="store_true",
        default=False,
        help="Flag to add spy hold comparison",
        dest="spy",
    )
    parser.add_argument(
        "--no_bench",
        action="store_true",
        default=False,
        help="Flag to not show buy and hold comparison",
        dest="no_bench",
    )
    parser.add_argument(
        "--no_short",
        action="store_false",
        default=True,
        dest="shortable",
        help="Flag that disables the short sell",
    )

    try:
        ns_parser = parse_known_args_and_warn(parser, other_args)
        if not ns_parser:
            return

        if ns_parser.long < ns_parser.short:
            print("Short EMA period is longer than Long EMA period\n")
            return

        ticker = ticker.lower()
        # prices = bt.get(ticker, start=start_date)
        prices = get_data(ticker, start_date)
        short_ema = pd.DataFrame(ta.ema(prices[ticker], ns_parser.short))
        short_ema.columns = [ticker]
        long_ema = pd.DataFrame(ta.ema(prices[ticker], ns_parser.long))
        long_ema.columns = [ticker]

        # signals
        signals = long_ema.copy()
        signals[short_ema > long_ema] = 1.0
        signals[short_ema <= long_ema] = -1.0 * ns_parser.shortable
        signals[long_ema.isnull()] = 0.0

        combined_data = bt.merge(signals, prices, short_ema, long_ema)
        combined_data.columns = ["signal", "price", "ema_short", "ema_long"]
        bt_strategy = bt.Strategy(
            "EMA_Cross",
            [
                bt.algos.WeighTarget(signals),
                bt.algos.Rebalance(),
            ],
        )
        bt_backtest = bt.Backtest(bt_strategy, prices)

        if ns_parser.spy:
            spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
            if ns_parser.no_bench:
                res = bt.run(bt_backtest, spy_bt)
            else:
                stock_bt = buy_and_hold(ticker, start_date,
                                        ticker.upper() + " Hold")
                res = bt.run(bt_backtest, spy_bt, stock_bt)
        else:
            if ns_parser.no_bench:
                res = bt.run(bt_backtest)
            else:
                stock_bt = buy_and_hold(ticker, start_date,
                                        ticker.upper() + " Hold")
                res = bt.run(bt_backtest, stock_bt)

        plot_bt(res,
                f"EMA Cross for EMA({ns_parser.short})/EMA({ns_parser.long})")
        print(res.display(), "\n")

    except Exception as e:
        print(e, "\n")
Пример #9
0
import bt
import matplotlib
matplotlib.get_backend()

# download data
from bt.algos import SelectWhere

data = bt.get('aapl,msft', start='2016-01-01')

# calculate moving average DataFrame using pandas' rolling_mean
import pandas as pd
# a rolling mean is a moving average, right?
sma = pd.rolling_mean(data, 50)

bt.merge(data, sma).plot(figsize=(15, 5))

signal = data > sma

# first we create the Strategy
s = bt.Strategy('above50sma', [SelectWhere(data > sma),
                               bt.algos.WeighEqually(),
                               bt.algos.Rebalance()])

# now we create the Backtest
t = bt.Backtest(s, data)

# and let's run it!
res = bt.run(t)
res.plot('d')
print(type(res))
res.display()
Пример #10
0
    name,
    [bt.algos.WeighTarget(tw), bt.algos.Rebalance()])

# Set up the backtest
uvxy_dynamic = bt.Backtest(strategy_4_uvxy,
                           strategy_4_data[['UVXY']],
                           integer_positions=False)

# Why integer positions? See UVXY head data
print(strategy_4_data['UVXY'].head(10))

# Run the backtest
res = bt.run(uvxy_dynamic, benchmark_test)

# Once we ran the previous backtest, we can extract the prices data to create synthetic securities
synthetic = bt.merge(res['uvxy_dynamic'].prices, res['long_spy'].prices)

# This is our new data, which is essentially the equity curve of each sub-strategy we tested.
# We can use this data to test our final strategy, just as before.
strategy_4 = bt.Strategy('combined_uvxy_spy', [
    bt.algos.SelectAll(),
    bt.algos.WeighSpecified(uvxy_dynamic=0.5, long_spy=0.5),
    bt.algos.Rebalance()
])

# Create and run
t = bt.Backtest(strategy_4, synthetic, integer_positions=False)
res = bt.run(t, benchmark_test)

# Display summary statistics and plot the weights
res.display()
Пример #11
0

if __name__ == "__main__":
    # 获取数据
    # data = getData()
    #data = bt.get("spy", start = "2010-01-01")
    #print(data.head())
    #print(data.describe())
    # SMA(data)
    #SMA_cross(data)
    t1 = sma_cross("aapl", name = "aapl_mass_cross")
    t2 = sma_cross("msft", name = "msft_mass_cross")
    
    res = bt.run(t1, t2)
    
    data = bt.merge(res["aapl_mass_cross"].prices,
    res["msft_mass_cross"].prices)
    
    s = bt.Strategy('s',
    [bt.algos.SelectAll(),
     bt.algos.WeighInvVol(),
     bt.algos.Rebalance()
    ])
    
    t = bt.Backtest(s, data)
    res = bt.run(t)
    
    res.display()
    res.plot()
    plt.savefig("multi_smacross.png")
    res.plot_weights()
    plt.savefig("multi_smacross_weights.png")
Пример #12
0
def rsi_strategy(
    ticker: str,
    df_stock: pd.DataFrame,
    periods: int,
    low_rsi: int,
    high_rsi: int,
    spy_bt: bool = True,
    no_bench: bool = False,
    shortable: bool = True,
) -> bt.backtest.Result:
    """Perform backtest for simple EMA strategy. Buys when price>EMA(l)

    Parameters
    ----------
    ticker : str
        Stock ticker
    df_stock : pd.DataFrame
        Dataframe of prices
    periods : int
        Number of periods for RSI calculati
    low_rsi : int
        Low RSI value to buy
    hirh_rsi : int
        High RSI value to sell
    spy_bt : bool
        Boolean to add spy comparison
    no_bench : bool
        Boolean to not show buy and hold comparison
    shortable : bool
        Flag to disable the ability to short sell

    Returns
    -------
    Result
        Backtest results
    """
    ticker = ticker.lower()
    start_date = df_stock.index[0]
    prices = pd.DataFrame(df_stock["Adj Close"])
    prices.columns = [ticker]
    rsi = pd.DataFrame(ta.rsi(prices[ticker], periods))
    rsi.columns = [ticker]

    signal = 0 * rsi.copy()
    signal[rsi > high_rsi] = -1 * shortable
    signal[rsi < low_rsi] = 1
    signal[rsi.isnull()] = 0

    merged_data = bt.merge(signal, prices)
    merged_data.columns = ["signal", "price"]

    bt_strategy = bt.Strategy(
        "RSI Reversion", [bt.algos.WeighTarget(signal),
                          bt.algos.Rebalance()])
    bt_backtest = bt.Backtest(bt_strategy, prices)
    bt_backtest = bt.Backtest(bt_strategy, prices)
    backtests = [bt_backtest]
    if spy_bt:
        spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
        backtests.append(spy_bt)
    if not no_bench:
        stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
        backtests.append(stock_bt)

    res = bt.run(*backtests)
    return res
Пример #13
0
def ema_cross_strategy(
    ticker: str,
    df_stock: pd.DataFrame,
    short_length: int,
    long_length: int,
    spy_bt: bool = True,
    no_bench: bool = False,
    shortable: bool = True,
) -> bt.backtest.Result:
    """Perform backtest for simple EMA strategy. Buys when price>EMA(l)

    Parameters
    ----------
    ticker : str
        Stock ticker
    df_stock : pd.DataFrame
        Dataframe of prices
    short_length : int
        Length of short ema window
    long_length : int
        Length of long ema window
    spy_bt : bool
        Boolean to add spy comparison
    no_bench : bool
        Boolean to not show buy and hold comparison
    shortable : bool
        Boolean to allow for selling of the stock at cross

    Returns
    -------
    Result
        Backtest results
    """
    ticker = ticker.lower()
    start_date = df_stock.index[0]
    prices = pd.DataFrame(df_stock["Adj Close"])
    prices.columns = [ticker]
    short_ema = pd.DataFrame(ta.ema(prices[ticker], short_length))
    short_ema.columns = [ticker]
    long_ema = pd.DataFrame(ta.ema(prices[ticker], long_length))
    long_ema.columns = [ticker]

    # signals
    signals = long_ema.copy()
    signals[short_ema > long_ema] = 1.0
    signals[short_ema <= long_ema] = -1.0 * shortable
    signals[long_ema.isnull()] = 0.0

    combined_data = bt.merge(signals, prices, short_ema, long_ema)
    combined_data.columns = ["signal", "price", "ema_short", "ema_long"]
    bt_strategy = bt.Strategy(
        "EMA_Cross",
        [
            bt.algos.WeighTarget(signals),
            bt.algos.Rebalance(),
        ],
    )
    bt_backtest = bt.Backtest(bt_strategy, prices)
    backtests = [bt_backtest]
    if spy_bt:
        spy_bt = buy_and_hold("spy", start_date, "SPY Hold")
        backtests.append(spy_bt)
    if not no_bench:
        stock_bt = buy_and_hold(ticker, start_date, ticker.upper() + " Hold")
        backtests.append(stock_bt)

    res = bt.run(*backtests)
    return res
Пример #14
0
import bt
import matplotlib
matplotlib.get_backend()

# download data
from bt.algos import SelectWhere

data = bt.get('aapl,msft', start='2016-01-01')

# calculate moving average DataFrame using pandas' rolling_mean
import pandas as pd
# a rolling mean is a moving average, right?
sma = pd.rolling_mean(data, 50)

bt.merge(data, sma).plot(figsize=(15, 5))

signal = data > sma

# first we create the Strategy
s = bt.Strategy(
    'above50sma',
    [SelectWhere(data > sma),
     bt.algos.WeighEqually(),
     bt.algos.Rebalance()])

# now we create the Backtest
t = bt.Backtest(s, data)

# and let's run it!
res = bt.run(t)
res.plot('d')
Пример #15
0
            # save in temp - this will be used by the weighing algo
            target.temp['selected'] = selected

        # return True because we want to keep on moving down the stack
        return True

data = bt.get('aapl,msft,c,gs,ge', start='2010-01-01')

# calculate moving average DataFrame using pandas' rolling_mean
import pandas as pd
# a rolling mean is a moving average, right?
sma = pd.rolling_mean(data, 50)

# let's see what the data looks like - this is by no means a pretty chart, but it does the job
tmp = bt.merge(data, sma).asfreq('m', 'ffill').rebase()
plot = tmp.plot(figsize=(15, 5))

signal = data > sma

# first we create the Strategy
s = bt.Strategy('above50sma', [SelectWhere(data > sma),
                               bt.algos.WeighEqually(),
                               bt.algos.Rebalance()])

# now we create the Backtest
t = bt.Backtest(s, data)

# and let's run it!
res = bt2.run(t)