use of name.abuchen.portfolio.model.LatestSecurityPrice in project portfolio by buchen.
the class HTMLTableQuoteFeed method extractPrice.
private LatestSecurityPrice extractPrice(Element row, List<Spec> specs, String languageHint) throws ParseException {
// $NON-NLS-1$
Elements cells = row.select("> td");
// row can be empty if it contains only 'th' elements
if (cells.size() <= 1)
return null;
LatestSecurityPrice price = new LatestSecurityPrice();
for (Spec spec : specs) spec.column.setValue(cells.get(spec.index), price, languageHint);
return price;
}
use of name.abuchen.portfolio.model.LatestSecurityPrice in project portfolio by buchen.
the class HTMLTableQuoteFeed method internalGetQuotes.
private List<LatestSecurityPrice> internalGetQuotes(Security security, String feedURL, List<Exception> errors) {
if (feedURL == null || feedURL.length() == 0) {
errors.add(new IOException(MessageFormat.format(Messages.MsgMissingFeedURL, security.getName())));
return Collections.emptyList();
}
List<LatestSecurityPrice> answer = cache.lookup(feedURL);
if (answer != null)
return answer;
answer = parseFromURL(feedURL, errors);
if (!answer.isEmpty())
cache.put(feedURL, answer);
return answer;
}
use of name.abuchen.portfolio.model.LatestSecurityPrice in project portfolio by buchen.
the class HTMLTableQuoteFeed method parse.
private List<LatestSecurityPrice> parse(Document document, List<Exception> errors) {
// check if language is provided
// $NON-NLS-1$ //$NON-NLS-2$
String language = document.select("html").attr("lang");
List<LatestSecurityPrice> prices = new ArrayList<>();
// first: find tables
// $NON-NLS-1$
Elements tables = document.getElementsByTag("table");
for (Element table : tables) {
List<Spec> specs = new ArrayList<>();
int rowIndex = buildSpecFromTable(table, specs);
if (isSpecValid(specs)) {
// $NON-NLS-1$
Elements rows = table.select("> tbody > tr");
int size = rows.size();
for (; rowIndex < size; rowIndex++) {
Element row = rows.get(rowIndex);
try {
LatestSecurityPrice price = extractPrice(row, specs, language);
if (price != null)
prices.add(price);
} catch (Exception e) {
errors.add(e);
}
}
// skip all other tables
break;
}
}
// if no quotes could be extract, log HTML for further analysis
if (prices.isEmpty())
errors.add(new IOException(MessageFormat.format(Messages.MsgNoQuotesFoundInHTML, document.html())));
return prices;
}
use of name.abuchen.portfolio.model.LatestSecurityPrice in project portfolio by buchen.
the class HTMLTableQuoteFeed method doLoad.
@SuppressWarnings("nls")
private static void doLoad(String source, PrintWriter writer) throws IOException {
writer.println("--------");
writer.println(source);
writer.println("--------");
List<LatestSecurityPrice> prices;
List<Exception> errors = new ArrayList<>();
if (source.startsWith("http")) {
prices = new HTMLTableQuoteFeed().parseFromURL(source, errors);
} else {
try (Scanner scanner = new Scanner(new File(source), StandardCharsets.UTF_8.name())) {
String html = scanner.useDelimiter("\\A").next();
prices = new HTMLTableQuoteFeed().parseFromHTML(html, errors);
}
}
for (Exception error : errors) // NOSONAR
error.printStackTrace(writer);
for (LatestSecurityPrice p : prices) {
writer.print(Values.Date.format(p.getDate()));
writer.print("\t");
writer.print(Values.Quote.format(p.getValue()));
writer.print("\t");
writer.print(Values.Quote.format(p.getLow()));
writer.print("\t");
writer.println(Values.Quote.format(p.getHigh()));
}
}
use of name.abuchen.portfolio.model.LatestSecurityPrice in project portfolio by buchen.
the class YahooFinanceQuoteFeed method updateLatestQuotes.
@Override
public final boolean updateLatestQuotes(Security security, List<Exception> errors) {
String wknUrl = // $NON-NLS-1$
MessageFormat.format(// $NON-NLS-1$
"https://de.finance.yahoo.com/quote/{0}?ltr=1", security.getTickerSymbol());
try {
Response response = //
Jsoup.connect(wknUrl).userAgent(//
OnlineHelper.getUserAgent()).timeout(30000).execute();
String body = response.body();
// some quick and dirty extraction. This scraping code will anyway
// not last long.
// $NON-NLS-1$
int startIndex = body.indexOf("QuoteSummaryStore");
if (startIndex < 0)
return false;
LatestSecurityPrice price = new LatestSecurityPrice();
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> time = extract(body, startIndex, "\"regularMarketTime\":", ",");
if (time.isPresent()) {
long epoch = Long.parseLong(time.get());
price.setDate(Instant.ofEpochSecond(epoch).atZone(ZoneId.systemDefault()).toLocalDate());
}
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> value = extract(body, startIndex, "\"regularMarketPrice\":{\"raw\":", ",");
if (value.isPresent())
price.setValue(asPrice(value.get()));
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> previousClose = extract(body, startIndex, "\"regularMarketPreviousClose\":{\"raw\":", ",");
if (previousClose.isPresent())
price.setPreviousClose(asPrice(previousClose.get()));
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> high = extract(body, startIndex, "\"regularMarketDayHigh\":{\"raw\":", ",");
if (high.isPresent())
price.setHigh(asPrice(high.get()));
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> low = extract(body, startIndex, "\"regularMarketDayLow\":{\"raw\":", ",");
if (low.isPresent())
price.setLow(asPrice(low.get()));
// $NON-NLS-1$ //$NON-NLS-2$
Optional<String> volume = extract(body, startIndex, "\"regularMarketVolume\":{\"raw\":", ",");
if (volume.isPresent())
price.setVolume(asNumber(volume.get()));
if (price.getDate() == null || price.getValue() <= 0) {
errors.add(new IOException(body));
return false;
}
security.setLatest(price);
return true;
} catch (IOException | ParseException e) {
errors.add(e);
return false;
}
}
Aggregations