if __name__ == '__main__':
    cerebro = bt.Cerebro(maxcpus=1)

    data = bt.feeds.YahooFinanceCSVData(
        dataname="datas/orcl-1995-2014.txt",
        fromdate=datetime.datetime(2000, 1, 1),
        todate=datetime.datetime(2001, 2, 28),
    )
    cerebro.adddata(data)
    cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)

    cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30))

    optres = cerebro.run(optreturn=False)

    def benchmark(optresults):
        a = [x.analyzers.tradeanalyzer.get_analysis() for x in optresults]
        return sum([x.pnl.gross.total if 'pnl' in x else 0 for x in a])

    result = [
        OrderedOptResult.BenchmarkedResult(benchmark(x), x) for x in optres
    ]
    ordered_result = sorted(result, key=lambda x: x.benchmark, reverse=True)

    ordered_result = OrderedOptResult("Profit & Losss", ordered_result)

    b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo())
    b.plot_result(ordered_result)
Beispiel #2
0
        if pos == self.p.buydate:
            self.buy(self.datas[0], size=None)

        if pos == self.p.buydate + self.p.holdtime:
            self.sell(self.datas[0], size=None)


if __name__ == '__main__':
    cerebro = bt.Cerebro(maxcpus=1)

    data = bt.feeds.YahooFinanceCSVData(
        dataname="datas/orcl-1995-2014.txt",
        fromdate=datetime.datetime(2000, 1, 1),
        todate=datetime.datetime(2001, 2, 28),
    )
    cerebro.adddata(data)
    cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)

    cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30))

    result = cerebro.run(optreturn=False)

    def get_pnl_gross(strats):
        a = strats[0].analyzers.tradeanalyzer.get_analysis()
        return a.pnl.gross.total if 'pnl' in a else 0

    columns = dict(pnl=get_pnl_gross)

    b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo())
    b.plot_result(result, columns)
Beispiel #3
0
        sma1 = bt.indicators.SMA(period=11, subplot=True)
        bt.indicators.SMA(period=17, plotmaster=sma1)
        bt.indicators.RSI()

    def next(self):
        pos = len(self.data)
        if pos == self.p.buydate:
            self.buy(self.datas[0], size=None)

        if pos == self.p.buydate + self.p.holdtime:
            self.sell(self.datas[0], size=None)


if __name__ == '__main__':
    cerebro = bt.Cerebro(maxcpus=1)

    data = bt.feeds.YahooFinanceCSVData(
        dataname="datas/orcl-1995-2014.txt",
        fromdate=datetime.datetime(2000, 1, 1),
        todate=datetime.datetime(2001, 2, 28),
    )
    cerebro.adddata(data)
    cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)

    cerebro.optstrategy(MyStrategy, buydate=range(40, 180, 30))

    result = cerebro.run(optreturn=False)

    b = Bokeh(style='bar', plot_mode="single", scheme=Tradimo())
    b.plot_result(result)
def perform_backtest(symbol_par,
                     n_fast_par,
                     n_slow_par,
                     long_macd_threshold_par,
                     long_per_threshold_par,
                     long_close_threshold_par,
                     short_macd_threshold_par,
                     short_per_threshold_par,
                     short_close_threshold_par,
                     initial_cash=10000,
                     comission=0.1,
                     df=None):
    '''
    Parameter:
    __________

    symbol_par (string):
    The symbol to use

    n_fast_par (int):
    Fast EMA line used during MACD calculation

    n_slow_par (int):
    Slower EMA line used during MACD calculation

    long_macd_threshold_par (int):
    The threshold of normalized macd, above which we might open a long position

    long_per_threshold_par (int):
    The value of percentage change over the last 2 hours above which we might open a long position
    #Might make this a parameter too

    long_close_threshold_par (int):
    Threshold of normalized macd, below which we will close the opened long position

    short_macd_threshold_par (int):
    The threshold of normalized macd, below which we might open a short position

    short_per_threshold_par (int):
    The value of percentage change over the last 2 hours below which we might open a short position

    short_close_threshold_par (int):
    Threshold of normalized macd, above which we will close the opened short position

    initial_cash (int) (optional):
    The cash to start from. Initiall 10k

    comission (int) (option):
    int fraction value. Defaults to 0.1%. This is much higher than normal. Staying on the safe side.

    df (Dataframe) (option):
    Uses df as features dataframe if specified. Otherwise reads the coin folder
    
    '''
    global n_fast
    global n_slow

    global long_macd_threshold
    global long_per_threshold
    global long_close_threshold
    global short_macd_threshold
    global short_per_threshold
    global short_close_threshold
    global symbol

    n_fast = n_fast_par
    n_slow = n_slow_par

    long_macd_threshold = long_macd_threshold_par
    long_per_threshold = long_per_threshold_par
    long_close_threshold = long_close_threshold_par
    short_macd_threshold = short_macd_threshold_par
    short_per_threshold = short_per_threshold_par
    short_close_threshold = short_close_threshold_par
    symbol = symbol_par

    json_info = {}
    json_info['n_fast'] = n_fast
    json_info['n_slow'] = n_slow
    json_info['long_macd_threshold'] = long_macd_threshold_par
    json_info['long_per_threshold'] = long_per_threshold_par
    json_info['long_close_threshold'] = long_close_threshold_par
    json_info['short_macd_threshold'] = short_macd_threshold_par
    json_info['short_per_threshold'] = short_per_threshold_par
    json_info['short_close_threshold'] = short_close_threshold_par
    json_info['initial_cash'] = initial_cash
    json_info['comission'] = comission

    with open(get_root_dir() + "/data/parameters.json", 'w') as f:
        json.dump(json_info, f)

    features_file = get_root_dir() + "/data/features/{}.csv".format(symbol)

    if df is None:
        df = pd.read_csv(features_file)

    df['macd'] = ta.trend.macd(df['sentistrength_total'],
                               n_fast=n_fast,
                               n_slow=n_slow,
                               fillna=True)
    df['macd'] = df['macd'].fillna(0)

    df['Time'] = pd.to_datetime(df['Time'])

    json_data = {}

    json_data['mean'] = df['macd'].mean()
    json_data['std'] = df['macd'].std()

    df['macd'] = (df['macd'] - json_data['mean']) / json_data['std']

    df = df.dropna(subset=['Time'])

    curr_dir = get_root_dir() + "/data/backtest/{}".format(symbol)

    if not os.path.exists(curr_dir):
        os.makedirs(curr_dir)

    fig = create_plot(df, 'macd', 'SentiStength')

    plotly_json = fig.to_json()

    html = fig.to_html()

    with open(curr_dir + '/plotly.html', 'w') as file:
        file.write(html)

    with open(curr_dir + '/plotly.json', 'w') as file:
        file.write(plotly_json)

    df = df[['Time', 'Open', 'High', 'Low', 'Close', 'Volume', 'macd']]
    df.to_csv(os.path.join(curr_dir, "data.csv"), index=None)

    data = PandasData_Custom(dataname=df)
    cerebro = bt.Cerebro(cheat_on_open=True, maxcpus=None)
    cerebro.adddata(data)

    cerebro.addstrategy(tradeStrategy)

    cerebro.addanalyzer(bt.analyzers.SharpeRatio_A)
    cerebro.addanalyzer(bt.analyzers.Calmar)
    cerebro.addanalyzer(bt.analyzers.DrawDown)
    cerebro.addanalyzer(bt.analyzers.Returns)
    cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)

    cerebro.broker.setcash(initial_cash)
    cerebro.broker.setcommission(comission / 100)

    run = cerebro.run()

    analysis = run[0].analyzers.getbyname('tradeanalyzer').get_analysis()

    trade_analyzer = {}
    trade_analyzer['total'] = analysis['total']['total']
    trade_analyzer['open'] = analysis['total']['open']
    trade_analyzer['closed'] = analysis['total']['closed']

    with open(curr_dir + "/stats.json", 'w') as f:
        json.dump(trade_analyzer, f)

    portfolioValue, trades, operations = run[0].get_logs()

    # fig = cerebro.plot()
    # figure = fig[0][0]
    # figure.savefig(curr_dir + "/backtest.png")

    output_file(curr_dir + "/backtest.html")
    b = Bokeh(style='bar', plot_mode="tabs", scheme=Tradimo())
    b.plot_result(run)

    df = df.set_index('Time')
    df = df.resample('1D').apply(resampler)
    df = df.reset_index()
    df = df[['Time', 'Open']].merge(portfolioValue,
                                    left_on='Time',
                                    right_on='Date').drop('Time', axis=1)
    df['hodl'] = (initial_cash / df['Open'].iloc[0]) * df['Open']
    df = df.drop('Open', axis=1)

    df.to_csv(curr_dir + '/portfolio.csv', index=None)
    trades.to_csv(curr_dir + '/trades.csv', index=None)
    operations.to_csv(curr_dir + '/operations.csv', index=None)

    with open(os.path.join(curr_dir, "data.json"), 'w') as fp:
        json.dump(json_data, fp)