Example #1
0
from haasomeapi.HaasomeClient import HaasomeClient
from haasomeapi.apis.MarketDataApi import MarketDataApi
from haasomeapi.enums.EnumPriceSource import EnumPriceSource
from haasomeapi.enums.EnumErrorCode import EnumErrorCode
from haasomeapi.enums.EnumCustomBotType import EnumCustomBotType
from haasomeapi.dataobjects.custombots.BaseCustomBot import BaseCustomBot
from botdatabase import BotDB
import configserver
from backtesting import Backtest ,Strategy
from MarketDataClass import MarketData as md
from backtesting.lib import SignalStrategy, TrailingStrategy
# from MadHatterBotClass import MadHatterBot as mh
# from botdb import BotDB as bdb
md = md()
md = md.read_csv(
    '/Users/cosmos/GitHub/Haasomeapitools/haasomeapitools/market_data/BITFINEX|ABS|USD.csv')

print(md)
bt = Backtest(data=md, strategy=SignalStrategy()).run()
Example #2
0
 def test_data_invalid(self):
     with self.assertRaises(TypeError):
         Backtest(GOOG.index, SmaCross).run()
     with self.assertRaises(ValueError):
         Backtest(GOOG.iloc[:0], SmaCross).run()
Example #3
0
 def test_broker_params(self):
     bt = Backtest(GOOG.iloc[:100], SmaCross,
                   cash=1000, commission=.01, margin=.1, trade_on_close=True)
     bt.run()
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.sell()


# In[ ]:

# In[ ]:

# In[ ]:

# In[91]:

bt = Backtest(STOCK,
              SmaCross,
              cash=1000,
              commission=.002,
              exclusive_orders=True)

output = bt.run()
bt.plot()

# In[92]:

output

# In[ ]:

# In[ ]:

# In[ ]:
Example #5
0
from backtesting import Backtest, Strategy
from backtesting.lib import crossover

from backtesting.test import SMA, GOOG


class SmaCross(Strategy):
    def init(self):
        price = self.data.Close
        self.ma1 = self.I(SMA, price, 10)
        self.ma2 = self.I(SMA, price, 20)

    def next(self):
        if crossover(self.ma1, self.ma2):
            self.buy()
        elif crossover(self.ma2, self.ma1):
            self.sell()


bt = Backtest(GOOG, SmaCross, commission=.002,
              exclusive_orders=True)
stats = bt.run()
bt.plot()
Example #6
0
 def test_run_invalid_param(self):
     bt = Backtest(GOOG, SmaCross)
     self.assertRaises(AttributeError, bt.run, foo=3)
Example #7
0
 def test_data_missing_columns(self):
     df = GOOG.copy(deep=False)
     del df['Open']
     with self.assertRaises(ValueError):
         Backtest(df, SmaCross).run()
Example #8
0
from backtesting.test import SMA
import GetSecurityInfo as GetSecurityInfo


class SmaCross(Strategy):
    n1 = 10
    n2 = 20

    def init(self):
        close = self.data.Close
        self.sma1 = self.I(SMA, close, self.n1)
        self.sma2 = self.I(SMA, close, self.n2)

    def next(self):
        if crossover(self.sma1, self.sma2):
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.sell()


bt = Backtest(GetSecurityInfo.GetSecurityInfo(2618, "1d", "20100101",
                                              "20210312"),
              SmaCross,
              cash=10000,
              commission=.002,
              exclusive_orders=True)

print(bt.run())
bt.plot()
# **Note**: `self.data` and any indicators wrapped with `self.I` (e.g. `self.sma1`) are NumPy arrays for performance reasons. If you prefer pandas Series or DataFrame objects, use `Strategy.data.<column>.s` or `Strategy.data.df` accessors respectively. You could also construct the series manually, e.g. `pd.Series(self.data.Close, index=self.data.index)`.
#
# We might avoid `self.position.close()` calls if we primed the
# [`Backtest`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Backtest)
# instance with `Backtest(..., exclusive_orders=True)`.

# ## Backtesting
#
# Let's see how our strategy performs on historical Google data. The
# [`Backtest`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Backtest)
# instance is initialized with OHLC data and a strategy _class_ (see API reference for additional options), and we begin with 10,000 units of cash and set broker's commission to realistic 0.2%.

# +
from backtesting import Backtest

bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002)
stats = bt.run()
stats
# -

# [`Backtest.run()`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Backtest.run)
# method returns a pandas Series of simulation results and statistics associated with our strategy. We see that this simple strategy makes almost 600% return in the period of 9 years, with maximum drawdown 33%, and with longest drawdown period spanning almost two years ...
#
# [`Backtest.plot()`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Backtest.plot)
# method provides the same insights in a more visual form.

bt.plot()

# ## Optimization
#
# We hard-coded the two lag parameters (`n1` and `n2`) into our strategy above. However, the strategy may work better with 15–30 or some other cross-over. **We declared the parameters as optimizable by making them [class variables](https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables)**.
Example #10
0
                    and crossover(self.data.Close, self.sma_exit)):

                self.position.close()


# -

# It's not a robust strategy, but we can optimize it. Let's optimize our strategy on Google stock data.

# +
# %%time

from backtesting import Backtest
from backtesting.test import GOOG

backtest = Backtest(GOOG, Sma4Cross, commission=.002)

stats, heatmap = backtest.optimize(
    n1=range(10, 110, 10),
    n2=range(20, 210, 20),
    n_enter=range(15, 35, 5),
    n_exit=range(10, 25, 5),
    constraint=lambda p: p.n_exit < p.n_enter < p.n1 < p.n2,
    maximize='Equity Final [$]',
    return_heatmap=True)
# -

# Notice `return_heatmap=True` parameter passed to
# [`Backtest.optimize()`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Backtest.optimize).
# It makes the function return a heatmap series along with the usual stats of the best run.
# `heatmap` is a pandas Series indexed with a MultiIndex, a cartesian product of all permissible parameter values.
Example #11
0
from backtesting import Backtest
import pandas as pd
from backtesting import Strategy
from backtesting.lib import crossover
from backtesting.lib import SignalStrategy, TrailingStrategy
import talib


def run_strategy(strategy: Strategy,
                 data: pd.DataFrame,
                 cash: int = 10_000,
                 commission: float = .002):
    """run the backtest for a specific strategy

    Args:
        strategy (Strategy): The strategy you want to execute
        path (pd.DataFrame): the data to backtest
        cash (int, optional): the entry cash you will have. Defaults to 10_000.
        commission (float, optional): the broker commision. Defaults to .002.
    """
    bt = Backtest(data, strategy, cash=10_000, commission=.002)
    stats = bt.run()

    print(stats)
    print(bt.plot())
Example #12
0
def hisse(request, name):
    bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002)
    name = bt.run()
    html = "<html><body>It is now %s.</body></html>" % name
    return HttpResponse(html)
            # Buy at market price on next open, but do
            # set 8% fixed stop loss.
            self.buy(sl=.92 * price)
        
        # If the price closes 2% or more below 10-day MA
        # close the position, if any.
        elif price < .98 * self.ma10[-1]:
            self.position.close()
# -

# Let's see how our strategy fares replayed on nine years of Google stock data.

# +
from backtesting.test import GOOG

backtest = Backtest(GOOG, System, commission=.002)
backtest.run()
# -

# Meager four trades in the span of nine years and with zero return? How about if we optimize the parameters a bit?

# +
# %%time

backtest.optimize(d_rsi=range(10, 35, 5),
                  w_rsi=range(10, 35, 5),
                  level=range(30, 80, 10))
# -

backtest.plot()
Example #14
0
 def test_compute_drawdown(self):
     dd = pd.Series([0, 1, 7, 0, 4, 0, 0])
     durations, peaks = Backtest._compute_drawdown_duration_peaks(dd)
     np.testing.assert_array_equal(durations, pd.Series([3, 2], index=[3, 5]).reindex(dd.index))
     np.testing.assert_array_equal(peaks, pd.Series([7, 4], index=[3, 5]).reindex(dd.index))
Example #15
0
 def test_file_size(self):
     bt = Backtest(GOOG, SmaCross)
     bt.run()
     with _tempfile() as f:
         bt.plot(filename=f[:-len('.html')], open_browser=False)
         self.assertLess(os.path.getsize(f), 500000)
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
import pandas
from backtesting.test import MACD, GOOG

binance_data = pandas.read_csv('backtest/data/binance-btc-usd.csv')


class MacdCross(Strategy):
    def init(self):
        price = self.data.Close
        self.macd, self.macd_signal, self.macd_histogram = self.I(
            MACD, price, 12, 26, 9)

    def next(self):
        if crossover(self.macd, self.macd_signal):
            self.buy()
        elif crossover(self.macd_signal, self.macd):
            self.sell()


bt = Backtest(binance_data,
              MacdCross,
              commission=.002,
              exclusive_orders=True,
              cash=10_000)
stats = bt.run()
print(stats)
# bt.plot()
Example #17
0
 def test_run(self):
     bt = Backtest(EURUSD, SmaCross)
     bt.run()
Example #18
0
    def test_assertions(self):
        class Assertive(Strategy):
            def init(self):
                self.sma = self.I(SMA, self.data.Close, 10)
                self.remains_indicator = np.r_[2] * np.cumsum(self.sma * 5 +
                                                              1) * np.r_[2]

                resampled = resample_apply('W', SMA, self.data.Close, 3)
                resampled_ind = resample_apply('W', SMA, self.sma, 3)
                assert np.unique(resampled[-5:]).size == 1
                assert np.unique(resampled[-6:]).size == 2
                assert resampled in self._indicators, "Strategy.I not called"
                assert resampled_ind in self._indicators, "Strategy.I not called"

                try:
                    self.data.X
                except KeyError:
                    pass
                else:
                    assert False

                assert self.data.pip == .01

                assert float(self.data.Close) == self.data.Close[-1]

            def next(self, FIVE_DAYS=pd.Timedelta('3 days')):
                assert self.equity >= 0

                assert isinstance(self.sma, _Indicator)
                assert isinstance(self.remains_indicator, _Indicator)
                assert self.remains_indicator.name
                assert isinstance(self.remains_indicator._opts, dict)

                assert not np.isnan(self.data.Open[-1])
                assert not np.isnan(self.data.High[-1])
                assert not np.isnan(self.data.Low[-1])
                assert not np.isnan(self.data.Close[-1])
                assert not np.isnan(self.data.Volume[-1])
                assert not np.isnan(self.sma[-1])
                assert self.data.index[-1]

                self.orders.is_long
                self.orders.is_short
                self.orders.entry
                self.orders.sl
                self.orders.tp

                self.position
                self.position.size
                self.position.pl
                self.position.pl_pct
                self.position.open_price
                self.position.open_time
                self.position.is_long

                if crossover(self.sma, self.data.Close):
                    self.orders.cancel()
                    self.sell()
                    assert not self.orders.is_long
                    assert self.orders.is_short
                    assert self.orders.entry
                    assert not self.orders.sl
                    assert not self.orders.tp
                    price = self.data.Close[-1]
                    sl, tp = 1.05 * price, .9 * price
                    self.sell(price, sl=sl, tp=tp)
                    self.orders.set_entry(price)
                    self.orders.set_sl(sl)
                    self.orders.set_tp(tp)
                    assert self.orders.entry == price
                    assert self.orders.sl == sl
                    assert self.orders.tp == tp

                elif self.position:
                    assert not self.orders.entry
                    assert not self.position.is_long
                    assert not not self.position.is_short
                    assert self.position.open_price
                    assert self.position.pl
                    assert self.position.pl_pct
                    assert self.position.size < 0
                    if self.data.index[
                            -1] - self.position.open_time > FIVE_DAYS:
                        self.position.close()

        bt = Backtest(GOOG, Assertive)
        stats = bt.run()
        self.assertEqual(stats['# Trades'], 144)
Example #19
0
 def test_run_speed(self):
     bt = Backtest(GOOG, SmaCross)
     start = time.process_time()
     bt.run()
     end = time.process_time()
     self.assertLess(end - start, .2)
Example #20
0
 def test_compute_stats(self):
     stats = Backtest(GOOG, SmaCross).run()
     # Pandas compares in 'almost equal' manner
     from pandas.testing import assert_series_equal
     assert_series_equal(
         stats.filter(regex='^[^_]').sort_index(),
         pd.Series({
             # NOTE: These values are also used on the website!
             '# Trades':
             65,
             'Avg. Drawdown Duration':
             pd.Timedelta('41 days 00:00:00'),
             'Avg. Drawdown [%]':
             -6.087158560194047,
             'Avg. Trade Duration':
             pd.Timedelta('46 days 00:00:00'),
             'Avg. Trade [%]':
             3.0404430275631444,
             'Best Trade [%]':
             54.05363186670138,
             'Buy & Hold Return [%]':
             703.4582419772772,
             'Calmar Ratio':
             0.0631443286380662,
             'Duration':
             pd.Timedelta('3116 days 00:00:00'),
             'End':
             pd.Timestamp('2013-03-01 00:00:00'),
             'Equity Final [$]':
             52624.29346696951,
             'Equity Peak [$]':
             76908.27001642012,
             'Expectancy [%]':
             8.774692825628644,
             'Exposure [%]':
             93.93453145057767,
             'Max. Drawdown Duration':
             pd.Timedelta('584 days 00:00:00'),
             'Max. Drawdown [%]':
             -48.15069053929621,
             'Max. Trade Duration':
             pd.Timedelta('183 days 00:00:00'),
             'Return [%]':
             426.2429346696951,
             'SQN':
             0.91553210127173,
             'Sharpe Ratio':
             0.23169782960690408,
             'Sortino Ratio':
             0.7096713270577958,
             'Start':
             pd.Timestamp('2004-08-19 00:00:00'),
             'Win Rate [%]':
             46.15384615384615,
             'Worst Trade [%]':
             -18.85561318387153,
         }).sort_index())
     self.assertTrue(
         stats._trade_data.columns.equals(
             pd.Index([
                 'Equity', 'Exit Entry', 'Exit Position', 'Entry Price',
                 'Exit Price', 'P/L', 'Returns', 'Drawdown',
                 'Drawdown Duration'
             ])))
Example #21
0
 def test_data_nan_columns(self):
     df = GOOG.copy()
     df['Open'] = np.nan
     with self.assertRaises(ValueError):
         Backtest(df, SmaCross).run()
Example #22
0
 def test_optimize_invalid_param(self):
     bt = Backtest(GOOG.iloc[:100], SmaCross)
     self.assertRaises(AttributeError, bt.optimize, foo=range(3))
Example #23
0
from backtesting import Backtest, Strategy
from backtesting.lib import crossover

from backtesting.test import SMA, GOOG

class SmaCross(Strategy):
    n1 = 10
    n2 = 30

    def init(self):
        self.sma1 = self.I(SMA, self.data.Close, self.n1)
        self.sma2 = self.I(SMA, self.data.Close, self.n2)

    def next(self):
        if crossover(self.sma1, self.sma2):
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.sell()


if __name__ == '__main__':
    # Windows: avoid concurrent.futures.process.BrokenProcessPool by wrapping in this if __name__ section
    bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002)

    output = bt.run()
    print(output)
    bt.optimize(n1=range(5, 20, 5),
                n2=range(10, 100, 10),)
    bt.plot()
Example #24
0
 def test_optimize_no_trades(self):
     bt = Backtest(GOOG, SmaCross)
     stats = bt.optimize(fast=[3], slow=[3])
     self.assertTrue(stats.isnull().any())
Example #25
0

# Load dataframes
natdf = pkl.load(open('XXXNATDFXXX', 'rb'))
endf = pkl.load(open('XXXENDFXXX', 'rb'))

# Find max length of df
max = natdf.shape[0]
if max > endf.shape[0]:
    max = endf.shape[0]

# Create backtest based on df data
comm = XXXCOMMXXX * 0.01
bt = Backtest(natdf.tail(max),
              XXXNAMEXXX,
              cash=XXXCASHXXX,
              commission=comm,
              margin=XXXMARGINXXX)

# Run backtest sts are the returned stats
sts = bt.run()
sts.to_csv('XXXRESULTXXXX')

# Optimization based on Strategy class variables
# optstats = bt.optimize(SL=range(1,5,1),TP=range(1,5,1))
# optstats = bt.optimize(SMAPER=range(7,98,7))
# print(optstats)

# Quantstats report https://github.com/ranaroussi/quantstats
# Create up Buy and Hold returns
hodler = natdf['Close'].tail(max).pct_change()
Example #26
0
 def test_optimize_speed(self):
     bt = Backtest(GOOG.iloc[:100], SmaCross)
     start = time.process_time()
     bt.optimize(fast=(2, 5, 7), slow=[10, 15, 20, 30])
     end = time.process_time()
     self.assertLess(end - start, .2)
Example #27
0
    def test_assertions(self):
        class Assertive(Strategy):
            def init(self):
                self.sma = self.I(SMA, self.data.Close, 10)
                self.remains_indicator = np.r_[2] * np.cumsum(self.sma * 5 + 1) * np.r_[2]

                self.transpose_invalid = self.I(lambda: np.column_stack((self.data.Open,
                                                                         self.data.Close)))

                resampled = resample_apply('W', SMA, self.data.Close, 3)
                resampled_ind = resample_apply('W', SMA, self.sma, 3)
                assert np.unique(resampled[-5:]).size == 1
                assert np.unique(resampled[-6:]).size == 2
                assert resampled in self._indicators, "Strategy.I not called"
                assert resampled_ind in self._indicators, "Strategy.I not called"

                assert 1 == try_(lambda: self.data.X, 1, AttributeError)
                assert 1 == try_(lambda: self.data['X'], 1, KeyError)

                assert self.data.pip == .01

                assert float(self.data.Close) == self.data.Close[-1]

            def next(self, FIVE_DAYS=pd.Timedelta('3 days')):
                assert self.equity >= 0

                assert isinstance(self.sma, _Indicator)
                assert isinstance(self.remains_indicator, _Indicator)
                assert self.remains_indicator.name
                assert isinstance(self.remains_indicator._opts, dict)

                assert not np.isnan(self.data.Open[-1])
                assert not np.isnan(self.data.High[-1])
                assert not np.isnan(self.data.Low[-1])
                assert not np.isnan(self.data.Close[-1])
                assert not np.isnan(self.data.Volume[-1])
                assert not np.isnan(self.sma[-1])
                assert self.data.index[-1]

                self.position
                self.position.size
                self.position.pl
                self.position.pl_pct
                self.position.is_long

                if crossover(self.sma, self.data.Close):
                    self.orders.cancel()  # cancels only non-contingent
                    price = self.data.Close[-1]
                    sl, tp = 1.05 * price, .9 * price

                    n_orders = len(self.orders)
                    self.sell(size=.21, limit=price, stop=price, sl=sl, tp=tp)
                    assert len(self.orders) == n_orders + 1

                    order = self.orders[-1]
                    assert order.limit == price
                    assert order.stop == price
                    assert order.size == -.21
                    assert order.sl == sl
                    assert order.tp == tp
                    assert not order.is_contingent

                elif self.position:
                    assert not self.position.is_long
                    assert self.position.is_short
                    assert self.position.pl
                    assert self.position.pl_pct
                    assert self.position.size < 0

                    trade = self.trades[0]
                    if self.data.index[-1] - self.data.index[trade.entry_bar] > FIVE_DAYS:
                        assert not trade.is_long
                        assert trade.is_short
                        assert trade.size < 0
                        assert trade.entry_bar > 0
                        assert isinstance(trade.entry_time, pd.Timestamp)
                        assert trade.exit_bar is None
                        assert trade.exit_time is None
                        assert trade.entry_price > 0
                        assert trade.exit_price is None
                        assert trade.pl / 1
                        assert trade.pl_pct / 1
                        assert trade.value > 0
                        assert trade.sl
                        assert trade.tp
                        # Close multiple times
                        self.position.close(.5)
                        self.position.close(.5)
                        self.position.close(.5)
                        self.position.close()
                        self.position.close()

        bt = Backtest(GOOG, Assertive)
        with self.assertWarns(UserWarning):
            stats = bt.run()
        self.assertEqual(stats['# Trades'], 145)
Example #28
0
 def test_plot_before_run(self):
     bt = Backtest(GOOG, SmaCross)
     self.assertRaises(RuntimeError, bt.plot)
Example #29
0
 def test_strategy_str(self):
     bt = Backtest(GOOG.iloc[:100], SmaCross)
     self.assertEqual(str(bt.run()._strategy), SmaCross.__name__)
     self.assertEqual(str(bt.run(fast=11)._strategy), SmaCross.__name__ + '(fast=11)')
Example #30
0

ns_path = "C:/dataset/amex-nyse-nasdaq-stock-histories/fh_20190420/NASDAQ.txt"
namespace = vh.data.local.namespace_from_tab_delimited(ns_path)
earnings_df = vh.data.local.get_all_earnings()
earn_summary = vh.data.local.get_dataset_summary()
earnings_df = vh.data.compat.set_datetime_index(earnings_df)

everything = []
for ticker in namespace:
    print('computing', ticker)

    try:
        df = vh.data.local.get_price_history(ticker)
    except FileNotFoundError as e:
        print('NO DATA @', ticker)
        continue
    df = vh.data.compat.format_df_backtest(df)
    earn = vh.data.local.get_ticker_earnings(earnings_df, ticker)

    edf = DataFrame(df.index.isin(earn.index, level='date'), index=df.index)
    edf = edf.iloc[::-1]
    bt = Backtest(df, MacdChain, cash=10000, commission=.002)
    results = bt.run()
    bt.plot()
    results['Symbol'] = ticker
    everything.append(results)

everything = pd.DataFrame(everything)
print(everything)