Search in sources :

Example 1 with RateLimitExceededException

use of name.abuchen.portfolio.util.RateLimitExceededException in project portfolio by buchen.

the class AlphavantageQuoteFeed method updateLatestQuotes.

@Override
public boolean updateLatestQuotes(Security security, List<Exception> errors) {
    if (security.getTickerSymbol() == null) {
        errors.add(new IOException(MessageFormat.format(Messages.MsgMissingTickerSymbol, security.getName())));
        return false;
    }
    if (apiKey == null)
        throw new IllegalArgumentException(Messages.MsgAlphaVantageAPIKeyMissing);
    if (rateLimiter != null && !rateLimiter.tryAcquire())
        throw new RateLimitExceededException(Messages.MsgAlphaVantageRateLimitExceeded);
    String wknUrl = MessageFormat.format(// $NON-NLS-1$
    "https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY" + // $NON-NLS-1$
    "&symbol={0}&interval=1min&apikey={1}&datatype=csv&outputsize=compact", security.getTickerSymbol(), apiKey);
    try {
        URL obj = new URL(wknUrl);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setConnectTimeout(1000);
        con.setReadTimeout(20000);
        int responseCode = con.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK)
            // $NON-NLS-1$
            throw new IOException(wknUrl + " --> " + responseCode);
        try (Scanner scanner = new Scanner(con.getInputStream(), StandardCharsets.UTF_8.name())) {
            // $NON-NLS-1$
            String body = scanner.useDelimiter("\\A").next();
            // $NON-NLS-1$
            String[] lines = body.split("\\r?\\n");
            if (lines.length <= 2)
                return false;
            // poor man's check
            if (// $NON-NLS-1$
            !"timestamp,open,high,low,close,volume".equals(lines[0])) {
                errors.add(new IOException(MessageFormat.format(Messages.MsgUnexpectedHeader, body)));
                return false;
            }
            String line = lines[1];
            // $NON-NLS-1$
            String[] values = line.split(",");
            if (values.length != 6)
                throw new IOException(MessageFormat.format(Messages.MsgUnexpectedValue, line));
            // $NON-NLS-1$
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LatestSecurityPrice price = new LatestSecurityPrice();
            price.setDate(LocalDate.parse(values[0], formatter));
            price.setValue(asPrice(values[4]));
            price.setHigh(asPrice(values[2]));
            price.setLow(asPrice(values[3]));
            price.setVolume(Long.parseLong(values[5]));
            price.setPreviousClose(LatestSecurityPrice.NOT_AVAILABLE);
            if (price.getValue() != 0)
                security.setLatest(price);
            return true;
        }
    } catch (IOException | ParseException e) {
        errors.add(e);
        return false;
    }
}
Also used : LatestSecurityPrice(name.abuchen.portfolio.model.LatestSecurityPrice) Scanner(java.util.Scanner) RateLimitExceededException(name.abuchen.portfolio.util.RateLimitExceededException) IOException(java.io.IOException) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) ParseException(java.text.ParseException) DateTimeFormatter(java.time.format.DateTimeFormatter)

Example 2 with RateLimitExceededException

use of name.abuchen.portfolio.util.RateLimitExceededException in project portfolio by buchen.

the class AlphavantageQuoteFeed method getHistoricalQuotes.

private <T extends SecurityPrice> List<T> getHistoricalQuotes(Class<T> klass, Security security, OutputSize outputSize, List<Exception> errors) {
    if (security.getTickerSymbol() == null) {
        errors.add(new IOException(MessageFormat.format(Messages.MsgMissingTickerSymbol, security.getName())));
        return Collections.emptyList();
    }
    if (apiKey == null)
        throw new IllegalArgumentException(Messages.MsgAlphaVantageAPIKeyMissing);
    if (rateLimiter != null && !rateLimiter.tryAcquire())
        throw new RateLimitExceededException(Messages.MsgAlphaVantageRateLimitExceeded);
    String wknUrl = MessageFormat.format(// $NON-NLS-1$
    "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY" + // $NON-NLS-1$
    "&symbol={0}&apikey={1}&datatype=csv&outputsize={2}", security.getTickerSymbol(), apiKey, outputSize.name().toLowerCase(Locale.US));
    try {
        URL obj = new URL(wknUrl);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setConnectTimeout(1000);
        con.setReadTimeout(20000);
        int responseCode = con.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK)
            // $NON-NLS-1$
            throw new IOException(wknUrl + " --> " + responseCode);
        try (Scanner scanner = new Scanner(con.getInputStream(), StandardCharsets.UTF_8.name())) {
            // $NON-NLS-1$
            String body = scanner.useDelimiter("\\A").next();
            // $NON-NLS-1$
            String[] lines = body.split("\\r?\\n");
            if (lines.length <= 2)
                return Collections.emptyList();
            // poor man's check
            if (// $NON-NLS-1$
            !"timestamp,open,high,low,close,volume".equals(lines[0])) {
                errors.add(new IOException(MessageFormat.format(Messages.MsgUnexpectedHeader, lines[0])));
                return Collections.emptyList();
            }
            // $NON-NLS-1$
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            List<T> prices = new ArrayList<>();
            for (int ii = 1; ii < lines.length; ii++) {
                String line = lines[ii];
                // $NON-NLS-1$
                String[] values = line.split(",");
                if (values.length != 6)
                    throw new IOException(MessageFormat.format(Messages.MsgUnexpectedValue, line));
                T price = klass.newInstance();
                if (values[0].length() > 10)
                    values[0] = values[0].substring(0, 10);
                price.setDate(LocalDate.parse(values[0], formatter));
                price.setValue(asPrice(values[4]));
                if (price instanceof LatestSecurityPrice) {
                    LatestSecurityPrice lsp = (LatestSecurityPrice) price;
                    lsp.setHigh(asPrice(values[2]));
                    lsp.setLow(asPrice(values[3]));
                    lsp.setVolume(Long.parseLong(values[5]));
                    lsp.setPreviousClose(LatestSecurityPrice.NOT_AVAILABLE);
                }
                if (price.getValue() != 0)
                    prices.add(price);
            }
            return prices;
        }
    } catch (IOException | ParseException | InstantiationException | IllegalAccessException e) {
        errors.add(e);
        return Collections.emptyList();
    }
}
Also used : LatestSecurityPrice(name.abuchen.portfolio.model.LatestSecurityPrice) Scanner(java.util.Scanner) ArrayList(java.util.ArrayList) RateLimitExceededException(name.abuchen.portfolio.util.RateLimitExceededException) IOException(java.io.IOException) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) ParseException(java.text.ParseException) DateTimeFormatter(java.time.format.DateTimeFormatter)

Example 3 with RateLimitExceededException

use of name.abuchen.portfolio.util.RateLimitExceededException in project portfolio by buchen.

the class UpdateQuotesJob method addHistoricalQuotesJobs.

private void addHistoricalQuotesJobs(Dirtyable dirtyable, List<Job> jobs) {
    // randomize list in case LRU cache size of HTMLTableQuote feed is too
    // small; otherwise entries would be evicted in order
    Collections.shuffle(securities);
    for (Security security : securities) {
        Job job = new Job(security.getName()) {

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                try {
                    QuoteFeed feed = Factory.getQuoteFeedProvider(security.getFeed());
                    if (feed == null)
                        return Status.OK_STATUS;
                    ArrayList<Exception> exceptions = new ArrayList<>();
                    if (feed.updateHistoricalQuotes(security, exceptions))
                        dirtyable.markDirty();
                    if (!exceptions.isEmpty())
                        PortfolioPlugin.log(createErrorStatus(security.getName(), exceptions));
                    return Status.OK_STATUS;
                } catch (RateLimitExceededException e) {
                    schedule(2000);
                    return Status.OK_STATUS;
                }
            }
        };
        if (HTMLTableQuoteFeed.ID.equals(security.getFeed()))
            job.setRule(HostSchedulingRule.createFor(security.getFeedURL()));
        jobs.add(job);
    }
}
Also used : IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) ArrayList(java.util.ArrayList) RateLimitExceededException(name.abuchen.portfolio.util.RateLimitExceededException) Security(name.abuchen.portfolio.model.Security) Job(org.eclipse.core.runtime.jobs.Job) HTMLTableQuoteFeed(name.abuchen.portfolio.online.impl.HTMLTableQuoteFeed) QuoteFeed(name.abuchen.portfolio.online.QuoteFeed) URISyntaxException(java.net.URISyntaxException) RateLimitExceededException(name.abuchen.portfolio.util.RateLimitExceededException)

Aggregations

RateLimitExceededException (name.abuchen.portfolio.util.RateLimitExceededException)3 IOException (java.io.IOException)2 HttpURLConnection (java.net.HttpURLConnection)2 URL (java.net.URL)2 ParseException (java.text.ParseException)2 DateTimeFormatter (java.time.format.DateTimeFormatter)2 ArrayList (java.util.ArrayList)2 Scanner (java.util.Scanner)2 LatestSecurityPrice (name.abuchen.portfolio.model.LatestSecurityPrice)2 URISyntaxException (java.net.URISyntaxException)1 Security (name.abuchen.portfolio.model.Security)1 QuoteFeed (name.abuchen.portfolio.online.QuoteFeed)1 HTMLTableQuoteFeed (name.abuchen.portfolio.online.impl.HTMLTableQuoteFeed)1 IProgressMonitor (org.eclipse.core.runtime.IProgressMonitor)1 Job (org.eclipse.core.runtime.jobs.Job)1