mirror of
https://github.com/cmallwitz/Financials-Extension.git
synced 2026-08-27 10:04:17 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06d9b91793 | ||
|
|
60d5d7b764 | ||
|
|
345f57420c |
@@ -57,7 +57,6 @@ cp -f "${PWD}"/src/jsonParser.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/naivehtmlparser.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/tz.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/financials_ft.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/financials_google.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/financials_yahoo.py "${PWD}"/build/
|
||||
cp -f "${PWD}"/src/financials_coinbase.py "${PWD}"/build/
|
||||
|
||||
|
||||
Binary file not shown.
@@ -54,7 +54,6 @@ import pyparsing
|
||||
import six
|
||||
|
||||
from datacode import Datacode
|
||||
import financials_google as google
|
||||
import financials_yahoo as yahoo
|
||||
import financials_coinbase as coinbase
|
||||
import financials_ft as ft
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
# financials_google.py
|
||||
#
|
||||
# license: GNU LGPL
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 3 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
import html
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import dateutil
|
||||
|
||||
from baseclient import BaseClient, RedirectException
|
||||
from datacode import Datacode
|
||||
from naivehtmlparser import NaiveHTMLParser
|
||||
from tz import whois_timezone_info
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
def handle_abbreviations(s):
|
||||
s = str(s).strip()
|
||||
if s.endswith('M'):
|
||||
return float(s[:-1]) * 1000000
|
||||
elif s.endswith('B'):
|
||||
return float(s[:-1]) * 1000000000
|
||||
elif s.endswith('T'):
|
||||
return float(s[:-1]) * 1000000000000
|
||||
return float(s)
|
||||
|
||||
|
||||
def un_span(s):
|
||||
return re.sub(r'<span [^>]*>', '', s).replace('</span>', '')
|
||||
|
||||
|
||||
class Google(BaseClient):
|
||||
def __init__(self, ctx):
|
||||
super().__init__()
|
||||
|
||||
self.realtime = {}
|
||||
self.location = None
|
||||
|
||||
def getRealtime(self, ticker: str, datacode: int):
|
||||
|
||||
"""
|
||||
Retrieve realtime data for ticker from Google Finance and cache it for further lookups
|
||||
|
||||
:param ticker: the ticker symbol e.g. LON:VOD
|
||||
:param datacode: the requested datacode
|
||||
:return:
|
||||
"""
|
||||
|
||||
# remove white space
|
||||
ticker = "".join(ticker.split())
|
||||
|
||||
# use cached value for up to 60 seconds
|
||||
if ticker in self.realtime:
|
||||
tick = self.realtime[ticker]
|
||||
if Datacode.TIMESTAMP in tick and type(tick[Datacode.TIMESTAMP]) == float and time.time() - 60 < tick[Datacode.TIMESTAMP]:
|
||||
return self._return_value(tick, datacode)
|
||||
else:
|
||||
del self.realtime[ticker]
|
||||
|
||||
q_param = 'q=' + ticker
|
||||
|
||||
if not self.location:
|
||||
url = 'https://www.google.com/search?hl=en&tbm=fin&' + q_param
|
||||
|
||||
try:
|
||||
self.urlopen(url, redirect=False)
|
||||
except RedirectException as e:
|
||||
self.location = e.location.replace('&' + q_param, '')
|
||||
except BaseException as e:
|
||||
logger.exception("BaseException ticker=%s datacode=%s", ticker, datacode)
|
||||
return 'Google.getRealtime(\'{}\', {}) - location: {}'.format(ticker, datacode, e)
|
||||
|
||||
if not self.location:
|
||||
url = 'https://www.google.com/search?tbm=fin&' + q_param
|
||||
else:
|
||||
url = self.location + '&' + q_param
|
||||
|
||||
try:
|
||||
text = self.urlopen(url)
|
||||
except BaseException as e:
|
||||
logger.exception("BaseException ticker=%s datacode=%s", ticker, datacode)
|
||||
return 'Google.getRealtime(\'{}\', {}) - urlopen: {} {}'.format(ticker, datacode, e, url)
|
||||
|
||||
try:
|
||||
temp = ticker.replace(':', '_') # Windows can't have ':' in file names
|
||||
with open(os.path.join(self.basedir, 'google-{}.html'.format(temp)), "w", encoding="utf-8") as text_file:
|
||||
print(f"<!-- '{url}' -->\r\n\r\n{text}", file=text_file)
|
||||
except BaseException as e:
|
||||
logger.exception("BaseException ticker=%s datacode=%s", ticker, datacode)
|
||||
|
||||
if ticker not in self.realtime:
|
||||
self.realtime[ticker] = self.get_ticker()
|
||||
|
||||
tick = self.realtime[ticker]
|
||||
|
||||
tick[Datacode.TIMESTAMP] = time.time()
|
||||
|
||||
try:
|
||||
r = '<span[^>]+role="heading"[^>]+>(.*?)</span>'
|
||||
pattern = re.compile(r)
|
||||
|
||||
match = pattern.search(text)
|
||||
if not match:
|
||||
return None
|
||||
start = match.span(0)[1]
|
||||
|
||||
tick[Datacode.NAME] = self.save_wrapper(
|
||||
lambda: html.unescape(un_span(match.group(1)).strip()))
|
||||
|
||||
# next div is TICKER
|
||||
r = '<div [^>]*><div [^>]*>(.*?)</div></div>'
|
||||
pattern = re.compile(r)
|
||||
|
||||
match = pattern.search(text, start)
|
||||
if not match:
|
||||
return 'Google.getRealtime({}, {}) - no match'.format(ticker, datacode)
|
||||
|
||||
ticker = self.save_wrapper(
|
||||
lambda: html.unescape(match.group(1)).replace(' ', ''))
|
||||
|
||||
tick[Datacode.EXCHANGE] = self.save_wrapper(lambda: ticker.split(':')[0])
|
||||
tick[Datacode.TICKER] = self.save_wrapper(lambda: ticker.split(':')[1])
|
||||
|
||||
except BaseException as e:
|
||||
return 'Google.getRealtime({}, {}) - process: {}'.format(ticker, datacode, e)
|
||||
|
||||
try:
|
||||
r = '<sticky-header [^>]*>(.*?)</sticky-header>'
|
||||
pattern = re.compile(r, flags=re.DOTALL)
|
||||
match = re.search(pattern, text)
|
||||
|
||||
if match:
|
||||
text = match.group(1)
|
||||
else:
|
||||
return 'Data for \'{}\' not found'.format(ticker)
|
||||
|
||||
parser = NaiveHTMLParser()
|
||||
root = parser.feed(text)
|
||||
parser.close()
|
||||
|
||||
cards = root.findall('.//g-card-section')
|
||||
|
||||
if len(cards) < 4:
|
||||
return 'Data for \'{}\' not found'.format(ticker)
|
||||
|
||||
header = cards[1]
|
||||
|
||||
tick[Datacode.LAST_PRICE] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(header.find('./span[1]/span[1]/span[1]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.CURRENCY] = self.save_wrapper(
|
||||
lambda: html.unescape(header.find('./span[1]/span[1]/span[2]').text).strip())
|
||||
|
||||
tick[Datacode.CHANGE] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(header.find('./span[2]/span[1]').text).replace('−', '-').replace(',', '').strip()))
|
||||
|
||||
# percentage is always wrapped in (...) and always positive even if there is a price drop
|
||||
tick[Datacode.CHANGE_IN_PERCENT] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(header.find('./span[2]/span[2]/span[1]').text).strip()
|
||||
.replace('(', '').replace(')', '').replace('%', '')))
|
||||
|
||||
try:
|
||||
value = html.unescape(header.find('./div[1]/span[1]/span[2]').text).replace('·', '').strip()
|
||||
logger.debug(value)
|
||||
dt = dateutil.parser.parse(value, yearfirst=True, dayfirst=False, tzinfos=whois_timezone_info)
|
||||
tick[Datacode.LAST_PRICE_DATE] = dt.date()
|
||||
tick[Datacode.LAST_PRICE_TIME] = dt.time()
|
||||
|
||||
time_bits = value.split(' ')
|
||||
if len(time_bits) >= 4:
|
||||
tick[Datacode.TIMEZONE] = time_bits[-1]
|
||||
|
||||
except BaseException as e:
|
||||
pass
|
||||
|
||||
footer = cards[3]
|
||||
logger.debug(ET.tostring(footer))
|
||||
|
||||
# parse 'footer' for remaining fields
|
||||
table = footer.find('./div[1]/div[1]/div[1]/table[1]')
|
||||
|
||||
tick[Datacode.OPEN] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[1]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.HIGH] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[2]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.LOW] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[3]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.MARKET_CAP] = self.save_wrapper(
|
||||
lambda: handle_abbreviations(
|
||||
html.unescape(table.find('./tr[4]/td[2]').text).replace(',', '').replace('-', '').strip()))
|
||||
|
||||
table = footer.find('./div[1]/div[1]/div[2]/table[1]')
|
||||
|
||||
# for indices: first item on right side is LOW
|
||||
if html.unescape(table.find('./tr[1]/td[1]').text).strip() == 'Low':
|
||||
tick[Datacode.LOW] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[1]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.PREV_CLOSE] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[2]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.HIGH_52_WEEK] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[3]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
tick[Datacode.LOW_52_WEEK] = self.save_wrapper(
|
||||
lambda: float(
|
||||
html.unescape(table.find('./tr[4]/td[2]').text).replace(',', '').strip()))
|
||||
|
||||
logger.info(tick)
|
||||
|
||||
except BaseException as e:
|
||||
logger.exception("BaseException ticker=%s datacode=%s", ticker, datacode)
|
||||
return 'Google.getRealtime({}, {}) - process: {}'.format(ticker, datacode, e)
|
||||
|
||||
return self._return_value(self.realtime[ticker], datacode)
|
||||
|
||||
def getHistoric(self, ticker, datacode, date):
|
||||
return 'Google.getHistoric: Historic Data not implemented.'
|
||||
|
||||
|
||||
def createInstance(ctx):
|
||||
return Google(ctx)
|
||||
@@ -225,14 +225,16 @@ class Yahoo(BaseClient):
|
||||
found = root.findall(f".//fin-streamer[@data-symbol='{ticker}']")
|
||||
for d in found:
|
||||
if hasattr(d, 'attrib') and 'data-field' in d.attrib:
|
||||
parsed[d.attrib['data-field']] = default(d.attrib, 'value').replace('−', '-').replace(',', '').strip()
|
||||
value = default(d.attrib, 'value') or default(d.attrib, 'data-value')
|
||||
parsed[d.attrib['data-field']] = value.replace('−', '-').replace(',', '').strip()
|
||||
|
||||
# for futures "regularMarketVolume" is from actual future ticker (potentially different to requested one)
|
||||
if 'regularMarketVolume' not in parsed:
|
||||
found = root.findall(f".//fin-streamer[@data-field='regularMarketVolume']")
|
||||
for d in found:
|
||||
if hasattr(d, 'attrib') and 'data-field' in d.attrib and 'data-symbol' in d.attrib:
|
||||
parsed[d.attrib['data-field']] = default(d.attrib, 'value').replace('−', '-').replace(',', '').strip()
|
||||
value = default(d.attrib, 'value') or default(d.attrib, 'data-value')
|
||||
parsed[d.attrib['data-field']] = value.replace('−', '-').replace(',', '').strip()
|
||||
tick[Datacode.TICKER] = default(d.attrib, 'data-symbol').strip()
|
||||
|
||||
found = root.findall(f".//td[@data-test]")
|
||||
|
||||
@@ -14,7 +14,7 @@ import os
|
||||
cur_dir = os.getcwd()
|
||||
|
||||
addin_id = "com.financials.getinfo"
|
||||
addin_version = "3.4.0"
|
||||
addin_version = "3.5.0"
|
||||
addin_displayname = "Financial Market Extension"
|
||||
addin_publisher_link = "https://github.com/cmallwitz/Financials-Extension"
|
||||
addin_publisher_name = "The Publisher"
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
# test_google.py
|
||||
#
|
||||
# license: GNU LGPL
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 3 of the License, or (at your option) any later version.
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
logging.basicConfig(level=logging.ERROR, format="%(asctime)s %(name)s %(levelname)s %(message)s")
|
||||
|
||||
import financials
|
||||
from datacode import Datacode
|
||||
|
||||
financials = financials.createInstance(None)
|
||||
|
||||
|
||||
# class Test(unittest.TestCase):
|
||||
class Test:
|
||||
|
||||
def test_currency(self):
|
||||
s = financials.getRealtime('EURGBP', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertIsNone(s, 'test_currency LAST_PRICE')
|
||||
|
||||
def test_UK_equity(self):
|
||||
s = financials.getRealtime('LON:VOD', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_UK_equity LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('LON:VOD', Datacode.TICKER.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'VOD', 'test_UK_equity TICKER')
|
||||
|
||||
s = financials.getRealtime('LON:VOD', Datacode.NAME.value, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_UK_equity NAME')
|
||||
|
||||
s = financials.getRealtime('LON:VOD', Datacode.EXCHANGE.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'LON', 'test_UK_equity EXCHANGE')
|
||||
|
||||
s = financials.getRealtime('LON:VOD', Datacode.PREV_CLOSE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_UK_equity PREV_CLOSE {}'.format(s))
|
||||
|
||||
# MARKET_CAP missing for UK stock but available for German stock - weekend issue (FX) ?
|
||||
s = financials.getRealtime('LON:VOD', Datacode.MARKET_CAP.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_UK_equity MARKET_CAP {}'.format(s))
|
||||
|
||||
def test_UK_ETF(self):
|
||||
s = financials.getRealtime('LON:CSP1', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_UK_ETF LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('LON:CSP1', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'GBX', 'test_UK_ETF CURRENCY')
|
||||
|
||||
s = financials.getRealtime('LON:FTAL', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_UK_ETF LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('LON:FTAL', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'GBP', 'test_UK_ETF CURRENCY')
|
||||
|
||||
s = financials.getRealtime('LON:FTAL', Datacode.NAME.value, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_UK_ETF NAME')
|
||||
|
||||
def test_DE_equity(self):
|
||||
s = financials.getRealtime('FRA:SAP', 7, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_DE_equity 7')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', '7', 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_DE_equity \'7\'')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', 8, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_DE_equity 8')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', 8.1, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_DE_equity 8.1')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', '8.1', 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_DE_equity \'8.1\'')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', 10, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_DE_equity 10')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', '11', 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_DE_equity \'11\'')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', '21', 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_DE_equity \'21\'')
|
||||
|
||||
s = financials.getRealtime('FRA:SAP', Datacode.TIMEZONE.value, 'GOOGLE')
|
||||
# self.assertEqual(s, 'Europe/Berlin', 'test_DE_equity TIMEZONE')
|
||||
self.assertTrue(s == 'CET' or s == 'CEST', 'test_DE_equity TIMEZONE: {}'.format(s))
|
||||
|
||||
def test_DE_ETF(self):
|
||||
s = financials.getRealtime('FRA:C060', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_DE_ETF LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('FRA:C060', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual('EUR', s, 'test_DE_ETF CURRENCY')
|
||||
|
||||
s = financials.getRealtime('FRA:C060', Datacode.TICKER.value, 'GOOGLE')
|
||||
self.assertEqual('C060', s, 'test_DE_ETF TICKER')
|
||||
|
||||
s = financials.getRealtime('FRA:C060', Datacode.EXCHANGE.value, 'GOOGLE')
|
||||
self.assertEqual('FRA', s, 'test_DE_ETF EXCHANGE')
|
||||
|
||||
s = financials.getRealtime('FRA:C060', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual('EUR', s, 'test_DE_ETF CURRENCY')
|
||||
|
||||
s = financials.getRealtime('FRA:C060', Datacode.MARKET_CAP.value, 'GOOGLE')
|
||||
self.assertIsNone(s, 'test_DE_ETF MARKET_CAP {}'.format(s))
|
||||
|
||||
def test_TY_equity(self):
|
||||
s = financials.getRealtime('TYO:6503', Datacode.OPEN.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity OPEN {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.LOW.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity LOW {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.HIGH.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity HIGH {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.LOW_52_WEEK.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity LOW_52_WEEK {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.HIGH_52_WEEK.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity HIGH_52_WEEK {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.MARKET_CAP.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_TY_equity MARKET_CAP {}'.format(s))
|
||||
|
||||
# s = financials.getRealtime('TYO:6503', Datacode.VOLUME.value, 'GOOGLE')
|
||||
# self.assertEqual(float, type(s), 'test_TY_equity VOLUME {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('TYO:6503', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'JPY', 'test_TY_equity CURRENCY')
|
||||
|
||||
def test_US_equity(self):
|
||||
s = financials.getRealtime(' NASDAQ : AAPL ', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime(' NASDAQ : AAPL ', Datacode.TICKER.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'AAPL', 'test_US_equity TICKER')
|
||||
|
||||
s = financials.getRealtime(' NASDAQ : AAPL ', Datacode.EXCHANGE.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'NASDAQ', 'test_US_equity EXCHANGE')
|
||||
|
||||
s = financials.getRealtime(' NASDAQ : AAPL ', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'USD', 'test_US_equity CURRENCY')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.TICKER.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'IBM', 'test_US_equity TICKER')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.EXCHANGE.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'NYSE', 'test_US_equity EXCHANGE')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'USD', 'test_US_equity CURRENCY')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.NAME.value, 'GOOGLE')
|
||||
self.assertEqual(type(s), str, 'test_US_equity NAME')
|
||||
self.assertEqual(s, 'IBM Common Stock', 'test_US_equity NAME')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.LOW.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity LOW {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.HIGH.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity HIGH {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.LOW_52_WEEK.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity LOW_52_WEEK {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.HIGH_52_WEEK.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity HIGH_52_WEEK {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.MARKET_CAP.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_equity MARKET_CAP {}'.format(s))
|
||||
|
||||
# s = financials.getRealtime('NYSE:IBM', Datacode.VOLUME.value, 'GOOGLE')
|
||||
# self.assertEqual(float, type(s), 'test_US_equity VOLUME {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.TIMESTAMP.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'Data doesn\'t exist - 999', 'test_US_equity TIMESTAMP')
|
||||
|
||||
s = financials.getRealtime('NYSE:IBM', Datacode.TIMEZONE.value, 'GOOGLE')
|
||||
# self.assertEqual('America/New_York', s, 'test_US_equity TIMEZONE')
|
||||
# self.assertEqual('GMT-4', s, 'test_US_equity TIMEZONE')
|
||||
self.assertEqual('GMT-5', s, 'test_US_equity TIMEZONE')
|
||||
|
||||
def test_US_mutuals(self):
|
||||
s = financials.getRealtime('MUTF:VFIAX', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_US_mutuals LAST_PRICE - {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('MUTF:VFIAX', Datacode.CURRENCY.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'USD', 'test_US_mutuals CURRENCY')
|
||||
|
||||
s = financials.getRealtime('MUTF:VFIAX', Datacode.TIMEZONE.value, 'GOOGLE')
|
||||
self.assertIsNone(s, 'test_US_mutuals TIMEZONE')
|
||||
|
||||
def test_index(self):
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index LAST_PRICE {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.CHANGE_IN_PERCENT.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index CHANGE_IN_PERCENT')
|
||||
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.CHANGE.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index CHANGE')
|
||||
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.OPEN.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index OPEN')
|
||||
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.LOW.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index LOW')
|
||||
|
||||
s = financials.getRealtime('INDEXDB:DAX', Datacode.HIGH.value, 'GOOGLE')
|
||||
self.assertEqual(float, type(s), 'test_index HIGH')
|
||||
|
||||
def test_errors(self):
|
||||
s = financials.getRealtime(None, Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'Ticker is empty', 'test_errors')
|
||||
|
||||
s = financials.getRealtime('NYS:IBM', None, 'GOOGLE')
|
||||
self.assertEqual(s, 'Datacode is empty', 'test_errors')
|
||||
|
||||
s = financials.getRealtime('DOES_NOT_EXISTS', Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertIsNone(s, 'test_errors')
|
||||
|
||||
s = financials.getRealtime('NYS:IBM', 'Foo', 'GOOGLE')
|
||||
self.assertEqual(s, 'Datacode is invalid', 'test_errors')
|
||||
|
||||
# Historic data not supported on GOOGLE
|
||||
|
||||
s = financials.getHistoric('NYS:IBM', Datacode.LAST_PRICE.value, '2017-01-01', 'GOOGLE')
|
||||
self.assertEqual(s, 'Source \'GOOGLE\' not supported', 'test_errors')
|
||||
|
||||
def test_errors_cell_range_passed(self):
|
||||
cell_range = ((1, 2), ('3', '4'), (5.0, 6.0))
|
||||
|
||||
s = financials.getRealtime(cell_range, Datacode.LAST_PRICE.value, 'GOOGLE')
|
||||
self.assertEqual(s, 'Cell range not allowed for ticker', 'test_errors')
|
||||
|
||||
s = financials.getRealtime('NYS:IBM', cell_range, 'GOOGLE')
|
||||
self.assertEqual(s, 'Cell range not allowed for datacode', 'test_errors')
|
||||
|
||||
s = financials.getRealtime('NYS:IBM', Datacode.LAST_PRICE.value, cell_range)
|
||||
self.assertEqual(s, 'Cell range not allowed for source', 'test_errors')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('unittest_args', nargs='*')
|
||||
args = parser.parse_args()
|
||||
unit_argv = [sys.argv[0]] + args.unittest_args
|
||||
unittest.main(argv=unit_argv)
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# test_google.py
|
||||
# test_support.py
|
||||
#
|
||||
# license: GNU LGPL
|
||||
#
|
||||
|
||||
+4
-1
@@ -140,12 +140,15 @@ class Test(unittest.TestCase):
|
||||
|
||||
s = financials.getRealtime('IBM', 'PAYOUT_RATIO', 'YAHOO')
|
||||
self.assertTrue(testutils.is_positive_float(s), 'test_realtime_US_equity PAYOUT_RATIO {}'.format(s))
|
||||
# self.assertEqual(None, s, 'test_realtime_US_equity PAYOUT_RATIO {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('IBM', 'SHARES_OUT', 'YAHOO')
|
||||
self.assertTrue(testutils.is_positive_float(s), 'test_realtime_US_equity SHARES_OUT {}'.format(s))
|
||||
# self.assertEqual(None, s, 'test_realtime_US_equity SHARES_OUT {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('IBM', 'FREE_FLOAT', 'YAHOO')
|
||||
self.assertTrue(testutils.is_positive_float(s), 'test_realtime_US_equity FREE_FLOAT {}'.format(s))
|
||||
# self.assertEqual(None, s, 'test_realtime_US_equity FREE_FLOAT {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('IBM', Datacode.EXCHANGE.value, 'YAHOO')
|
||||
self.assertEqual(s, 'NYSE', 'test_realtime_US_equity EXCHANGE')
|
||||
@@ -268,7 +271,7 @@ class Test(unittest.TestCase):
|
||||
|
||||
s = financials.getRealtime('CSP1.L', Datacode.NAME.value, 'YAHOO')
|
||||
self.assertEqual(str, type(s), 'test_realtime_UK_ETF NAME {}'.format(s))
|
||||
self.assertEqual('iShares VII PLC - iShares Core S&P 500 UCITS ETF (CSP1.L)', s, 'test_realtime_UK_ETF NAME {}'.format(s))
|
||||
self.assertEqual('iShares Core S&P 500 UCITS ETF USD (Acc) (CSP1.L)', s, 'test_realtime_UK_ETF NAME {}'.format(s))
|
||||
|
||||
s = financials.getRealtime('VERX.L', 'SECTOR', 'YAHOO')
|
||||
self.assertIsNone(s, 'test_realtime_UK_ETF SECTOR {}'.format(s))
|
||||
|
||||
Reference in New Issue
Block a user