def __add_stock_to_index(self, index, stock_info): stock_in_db = Stock.get(name=stock_info['name']) if stock_in_db: self.logger.info('Add stock {}:{} to index.'.format( index.name, stock_in_db.name)) index.stocks.add(stock_in_db) else: self.logger.info('Add stock {}:{} to db'.format( index.name, stock_info[Type.SYM])) # create stock stock = Stock(name=stock_info['name'], price_item=PriceItem(item=Item())) # add symbols yao = Tag.get(name=Tag.YAO) gog = Tag.get(name=Tag.GOG) usd = Tag.get(name=Tag.USD) eur = Tag.get(name=Tag.EUR) for symbol in stock_info['symbols']: if Tag.GOG in symbol and symbol[Tag.GOG] != '-': self.__create_symbol(stock, Tag.GOG, gog, symbol, eur, usd) if Tag.YAO in symbol and symbol[Tag.YAO] != '-': self.__create_symbol(stock, Tag.YAO, yao, symbol, eur, usd) index.stocks.add(stock) # connect stock with industry and country # country name = stock_info['country'] country = Tag.select( lambda t: t.name == name and t.type.name == Type.REG).first() country.items.add(stock.price_item.item) # industry indus = stock_info['industries'] industries = Tag.select( lambda t: t.name in indus and t.type.name == Type.IND) for industry in industries: industry.items.add(stock.price_item.item)
def __filter_test(self, filter_class, args, result): logger = logging.getLogger('test') fil = filter_class(args, logger) if fil.lookback and fil.need_bars: fil.set_bars(self.get_bars('IFX.F', fil)) if fil.lookback and fil.need_index_bars: fil.set_index_bars(self.get_index_bars('IFX.F', fil)) stock = Stock.select( (lambda s: 'IFX.F' in s.price_item.symbols.name)).first() fil.set_stock(stock) strategy_status = fil.analyse() strategy_value = fil.get_calculation() self.assertEqual(strategy_status, result[0]) self.assertAlmostEqual(strategy_value, result[1], 2)
def test_1_create(self): """ Test database client :return: """ config = { 'max_history': 1, 'indices': [], 'currencies': ['EUR'], 'create': True, 'db_args': { 'provider': 'sqlite', 'filename': 'database_create.sqlite', 'create_db': True }, } logger = logging.getLogger('test') create = CreateAndFillDataBase(config, logger) self.assertEqual(create.build(), 0) config['indices'] = ['DAX'] config['currencies'] = ['CAD'] create = CreateAndFillDataBase(config, logger) self.assertEqual(create.build(), -1) config['currencies'] = ['EUR', 'USD'] # check setup with multiple currencies with freeze_time('2019-01-14'): create = CreateAndFillDataBase(config, logger) self.assertEqual(create.build(), 0) with db_session: # check euro prices_ctx = Price.select( lambda p: p.symbol.name == 'IFX.F').count() self.assertGreater(prices_ctx, 1) # check usd prices_ctx = Price.select( lambda p: p.symbol.name == 'IFNNF').count() self.assertGreater(prices_ctx, 1) with freeze_time('2019-01-14'): config['currencies'] = ['EUR'] create = CreateAndFillDataBase(config, logger) self.assertEqual(create.build(), 0) with db_session: stocks = Stock.select().count() self.assertEqual(stocks, 30) prices = list(select(max(p.date) for p in Price)) self.assertEqual(len(prices), 1) self.assertEqual(prices[0].strftime('%Y-%m-%d'), '2019-01-11')
def test_5_query_data(self): ifx = Stock.select( lambda s: 'IFX.F' in s.price_item.symbols.name).first() dataNone = ifx.get_data_attr('incomNone', 'netIncome') self.assertIsNone(dataNone) data = ifx.get_data_attr('income', 'netIncome') self.assertIsInstance(data, float) data2 = ifx.get_data_attr('income', 'netIncome', quarter_diff=4) self.assertIsInstance(data2, float) data3 = ifx.get_data_attr('income', 'netIncome', quarter_diff=1) self.assertIsInstance(data3, float) data4 = ifx.get_data_attr('income', 'netIncome', annual=True) self.assertIsInstance(data4, float) rat = ifx.get_data_attr('recommendation', 'rating') mea = ifx.get_data_attr('recommendation', 'measures') eps = ifx.get_data_attr('recommendation', 'eps') self.assertEqual(mea, -1) self.assertIsInstance(rat, float) self.assertIsInstance(eps, float)
def test_4_sync(self): """Tests sync tool """ logger = logging.getLogger('test') config = { 'max_history': 1, 'indices': ['DAX', 'CAC 40'], 'currencies': ['EUR'], 'db_args': { 'provider': 'sqlite', 'filename': 'database_create.sqlite', 'create_db': True # should set to false }, } sync = SyncDataBaseStocks(config, logger) sync.build() with db_session: stocks = Stock.select().count() self.assertEqual(stocks, 70)
def test_2_dbbase(self): config = { 'db_args': { 'provider': 'sqlite', 'filename': 'database_create.sqlite', 'create_db': False } } logger = logging.getLogger('test') dbbase = DBBase(config, logger) ind = Index.get(name='test123') if ind: ind.delete() sym = Symbol.get(name='test123') if sym: sym.delete() self.assertRaises(NotImplementedError, dbbase.build) self.assertFalse(dbbase.download_historicals(None, None, None)) # override pytickersymbols def get_stocks_by_index(name): stock = { 'name': 'adidas AG', 'symbol': 'ADS', 'country': 'Germany', 'indices': ['DAX', 'test123'], 'industries': [], 'symbols': [] } return [stock] def index_to_yahoo_symbol(name): return 'test123' dbbase.ticker_symbols.get_stocks_by_index = get_stocks_by_index dbbase.ticker_symbols.index_to_yahoo_symbol = index_to_yahoo_symbol dbbase.add_indices_and_stocks(['test123']) ads = Stock.select(lambda s: 'test123' in s.indexs.name).first() self.assertNotEqual(ads, None) Index.get(name='test123').delete() Symbol.get(name='test123').delete()
def build(self): """ Starts the build process for given filters :return: nothing """ if self.symbols is None or self.filters is None: return 1 rc = 0 # select all symbols with price connection if 'ALL' in self.symbols: # without index symbols symbols = list( select(p.symbol.name for p in Price if Tag.IDX not in p.symbol.item.tags.name) ) self.symbols = symbols for symbol_str in self.symbols: self.logger.info('Create filters for {}.'.format(symbol_str)) # get stock of symbol stock = Stock.select( (lambda s: symbol_str in s.price_item.symbols.name) ).first() symbol = Symbol.get(name=symbol_str) for my_filter in self.filters: try: self.logger.info( 'Execute filter {}.'.format(my_filter.name) ) self.__build(my_filter, stock, symbol) except (TypeError, RuntimeError, KeyError, ZeroDivisionError, IndexError, ValueError): self.logger.exception( 'Filter {} causes exceptions.'.format(my_filter.name) ) rc += 1 commit() return rc