import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import javax.net.ssl.HttpsURLConnection; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class OANDAReader implements TickStreamReader { AccountInfo accountInfo; String[] instruments; public OANDAReader(AccountInfo accountInfo, String[] instruments) { this.accountInfo = accountInfo; this.instruments = instruments; } public void run(TickProcessor processor) { readConnection(streamURL(), processor); } private String streamURL() { String type = accountInfo.isLiveAccount() ? "fxlive" : "fxpractice"; String instrList = String.join(",", instruments); String query = ""; try { query = String.format("instruments=%s", URLEncoder.encode(instrList, "UTF-8")); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return String.format("https://stream-%s.oanda.com/v3/accounts/%s/pricing/stream?%s", type, accountInfo.accountID(), query); } private static void readConnection(String urlStr, TickProcessor processor) { HttpsURLConnection httpConn = null; String line = null; try { URL url = new URL(urlStr); URLConnection urlConn = url.openConnection(); if (!(urlConn instanceof HttpsURLConnection)) { throw new IOException ("URL is not an https URL"); } httpConn = (HttpsURLConnection)urlConn; httpConn.setAllowUserInteraction(false); //httpConn.setInstanceFollowRedirects(true); httpConn.setRequestMethod("GET"); //httpConn.setReadTimeout(50 * 1000); httpConn.setRequestProperty("Authorization", "Bearer 9a480f0b83e987f4015cf0846790c7d9-695ced635526744abd61bdf0e2ae8b71"); BufferedReader is = new BufferedReader(new InputStreamReader(httpConn.getInputStream())); while ((line = is.readLine( )) != null) { processLine(line, processor); } } catch (MalformedURLException e) { e.printStackTrace(); } catch(SocketTimeoutException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { httpConn.disconnect(); } } static ObjectMapper mapper = new ObjectMapper(); // create once, reuse private static void processLine(String line, TickProcessor processor) { if (line.indexOf ("PRICE") > -1) { OANDATick tick; try { tick = mapper.readValue(line, OANDATick.class); processor.process(tick); } catch (JsonParseException | JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } else if (line.indexOf ("HEARTBEAT") > -1) { // ignore } else { System.out.println("Unknown type: " + line); } } }