Beispiel #1
0
    def __init__(
        self,
        algo: GQAlgo,
        symbols,
        start_datetime,
        end_datetime,
        data_freq=FREQ_DAY,
        initial_cash=10000,
    ):
        self.algo = algo
        self.symbols = symbols
        self.start_datetime = start_datetime
        self.end_datetime = end_datetime
        self.data_freq = data_freq
        self.datasource = algo.datasource
        self.initial_cash = initial_cash

        self.data = GQData()

        freq_map = {
            FREQ_DAY: Frequency.DAY,
            FREQ_MINUTE: Frequency.MINUTE,
        }
        self.datafeed = csvfeed.GenericBarFeed(freq_map[data_freq])
        self._load_datafeed()

        self.my_strategy = MyStrategy(self.datafeed, self.symbols, self.algo,
                                      self.initial_cash)
        self.returnsAnalyzer = returns.Returns()
        self.my_strategy.attachAnalyzer(self.returnsAnalyzer)
Beispiel #2
0
    def __init__(self, trading_platform, datasource):
        self.trading_platform = trading_platform
        self.datasource = datasource
        self.account = get_account_class(trading_platform)
        self.data = GQData()
        self.t = None  # current time in UTC

        self.backtest_strategy = None
        self.metrics = {}

        self.init()
Beispiel #3
0
    def test_fill_nan(self):
        df1 = pd.DataFrame.from_dict({
            "date":
            [datetime(2019, 1, 1),
             datetime(2019, 1, 2),
             datetime(2019, 1, 3)],
            "value": [1, 2, 3],
        }).set_index("date")
        df2 = pd.DataFrame.from_dict({
            "date": [datetime(2019, 1, 1),
                     datetime(2019, 1, 3)],
            "value": [1, 3],
        }).set_index("date")
        df1.index = pd.to_datetime(df1.index, unit='ms')
        df2.index = pd.to_datetime(df2.index, unit='ms')
        data_dict = {
            "s1": df1,
            "s2": df2,
        }
        data_dict_out = GQData._fill_nan(data_dict,
                                         fill_nan_method=None,
                                         remove_nan_rows=False)
        self.assertEqual(data_dict_out["s1"].shape, (3, 1))
        self.assertEqual(data_dict_out["s2"].shape, (3, 1))
        self.assertTrue(math.isnan(data_dict_out["s2"]["value"][1]))

        data_dict_out = GQData._fill_nan(data_dict,
                                         fill_nan_method=None,
                                         remove_nan_rows=True)
        self.assertEqual(data_dict_out["s1"].shape, (2, 1))
        self.assertEqual(data_dict_out["s2"].shape, (2, 1))

        data_dict_out = GQData._fill_nan(data_dict,
                                         fill_nan_method="ffill",
                                         remove_nan_rows=False)
        self.assertEqual(data_dict_out["s1"].shape, (3, 1))
        self.assertEqual(data_dict_out["s2"].shape, (3, 1))
        self.assertEqual(data_dict_out["s2"]["value"][1], 1)
Beispiel #4
0
 def test_get_data_binance(self):
     self._test_datasource(GQData(), ["ETHBTC", "BTCUSDT"],
                           DATASOURCE_BINANCE)
Beispiel #5
0
 def test_get_data_alpaca(self):
     self._test_datasource(GQData(), ["SPY", "UBER"], DATASOURCE_ALPACA)
Beispiel #6
0
class GQBacktest(object):
    def __init__(
        self,
        algo: GQAlgo,
        symbols,
        start_datetime,
        end_datetime,
        data_freq=FREQ_DAY,
        initial_cash=10000,
    ):
        self.algo = algo
        self.symbols = symbols
        self.start_datetime = start_datetime
        self.end_datetime = end_datetime
        self.data_freq = data_freq
        self.datasource = algo.datasource
        self.initial_cash = initial_cash

        self.data = GQData()

        freq_map = {
            FREQ_DAY: Frequency.DAY,
            FREQ_MINUTE: Frequency.MINUTE,
        }
        self.datafeed = csvfeed.GenericBarFeed(freq_map[data_freq])
        self._load_datafeed()

        self.my_strategy = MyStrategy(self.datafeed, self.symbols, self.algo,
                                      self.initial_cash)
        self.returnsAnalyzer = returns.Returns()
        self.my_strategy.attachAnalyzer(self.returnsAnalyzer)

    def _load_datafeed(self):
        # loading all data
        self.data.get_data(symbols=self.symbols,
                           freq=self.data_freq,
                           start_date=self.start_datetime,
                           end_date=self.end_datetime,
                           datasource=self.datasource,
                           use_cache=True,
                           fill_nan_method="ffill")

        data_files = {}
        for symbol in self.symbols:

            data_key = self.data.get_data_key(
                symbol=symbol,
                freq=self.data_freq,
                start_date=self.start_datetime,
                end_date=self.end_datetime,
            )
            file_path = self.data.get_data_file_path(data_key)
            data_files[symbol] = file_path

            logger.debug("add csv file {} into data feed".format(file_path))
            self.datafeed.addBarsFromCSV(symbol,
                                         file_path,
                                         skipMalformedBars=True)

    def run(self, plot=True):
        if plot:
            backtest_plt = plotter.StrategyPlotter(self.my_strategy)
            backtest_plt.getOrCreateSubplot("returns").addDataSeries(
                "Simple returns", self.returnsAnalyzer.getReturns())
            tmp = self.returnsAnalyzer.getReturns()
            print(tmp)

        self.my_strategy.run()
        logger.info("Final portfolio value: $%.2f" %
                    self.my_strategy.getBroker().getEquity())

        if plot:
            if len(self.algo.metrics) > 0:
                for k in self.algo.metrics:
                    ds, fig_idx = self.algo.metrics.get(k)
                    plt.figure(fig_idx)
                    ds.plot(legend=True)
            backtest_plt.plot()
Beispiel #7
0
    parser.add_argument("--debug",
                        action='store_true',
                        help="Set to debug mode. Example --debug'")

    args = parser.parse_args()
    print("input args: {}".format(args))

    if args.debug is not None:
        logging.basicConfig(level=logging.DEBUG)
        logger = logging.getLogger(__name__)
        logger.debug('Debug mode on')

    universe = []
    with open(args.universe_file, 'r') as f:
        reader = csv.reader(f, delimiter=',')
        universe = list(reader)
    if len(universe) != 1:
        raise Exception(
            "universe file should contain 1 line, current results: {}".format(
                universe))
    universe = universe[0]
    print("universe: {}".format(universe))

    gqdata = GQData()
    df = gqdata.get_data(universe,
                         args.freq,
                         args.startdate,
                         end_date=args.enddate,
                         datasource=args.source,
                         data_type=DATATYPE_TICKER)
Beispiel #8
0
class GQAlgo(object):
    def __init__(self, trading_platform, datasource):
        self.trading_platform = trading_platform
        self.datasource = datasource
        self.account = get_account_class(trading_platform)
        self.data = GQData()
        self.t = None  # current time in UTC

        self.backtest_strategy = None
        self.metrics = {}

        self.init()

    def init(self):
        pass

    def run(self) -> [list]:
        raise NotImplementedError

    def get_trading_platform(self):
        return self.trading_platform

    def get_time(self):
        return self.t

    def get_cash(self):
        """
        get current cash in USD
        :return:
        """
        return self.account.get_cash()

    def get_positions(self):
        """
        get current positions
        :return: dict
            symbol->position
        """
        return self.account.get_positions()

    def algo_get_data(self, symbols, interval_timedelta, freq, fill_nan_method=None, remove_nan_rows=True):
        """
        get data until now (time t, get from get_time())
        :param symbols: list
            list of symbols
        :param interval_timedelta: deltatime
            used to calculate start time
        :param freq: string
            day, minute data level
        :param fill_nan_method: string
            fill nan method, default not fill, see more parameters here:
            https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html
        :param remove_nan_rows: bool
            remove nan rows after fill nan
        :return:
        """
        end_datetime = datetime.now(timezone.utc)
        if self.trading_platform == TRADING_BACKTEST:
            end_datetime = self.get_time()
            if end_datetime is None:
                raise ValueError("please run prerun() function first")
        start_datetime = end_datetime - interval_timedelta
        data = self.data.get_data(symbols=symbols,
                                  freq=freq,
                                  start_date=start_datetime,
                                  end_date=end_datetime,
                                  datasource=self.datasource,
                                  dict_output=True,
                                  fill_nan_method=fill_nan_method,
                                  remove_nan_rows=remove_nan_rows
                                  )
        return data

    def init_backtest(self, strategy: strategy.BacktestingStrategy):
        self.backtest_strategy = strategy
        self.account.set_backtest_strategy(strategy)

    def prerun(self, t, verbose=True):
        if verbose:
            msg = "=============\nAlgorithm Time: {}\nCash: {}\nPositions: {}\n".format(
                t, self.get_cash(), self.get_positions()
            )
            logger.info(msg)
        self.t = t

    def record_metric(self, key, value, figure_group=1):
        if figure_group < 0:
            raise ValueError("figure_grouup only can be positive, get figure_group {}".format(figure_group))
        cur_data_serise, _ = self.metrics.get(key, (pd.Series([], name=key), figure_group))
        cur_data_serise = cur_data_serise.append(pd.Series([value], index=[self.t], name=key))
        self.metrics[key] = (cur_data_serise, figure_group)
import logging
import argparse
import csv
from datetime import datetime, timezone

from controller.data.data import GQData, DATATYPE_TICKER, DATASOURCE_POLYGON

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Download data')
    parser.add_argument("--debug", action='store_true', help="Set to debug mode. Example --debug'")

    args = parser.parse_args()
    print("input args: {}".format(args))

    if args.debug is not None:
        logging.basicConfig(level=logging.DEBUG)
        logger = logging.getLogger(__name__)
        logger.debug('Debug mode on')

    gqdata = GQData()
    df = gqdata.get_universe_data(datasource=DATASOURCE_POLYGON)