106 lines
3.4 KiB
Java
106 lines
3.4 KiB
Java
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 org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
|
import com.espertech.esper.client.time.CurrentTimeEvent;
|
|
|
|
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 {
|
|
final Logger log = LoggerFactory.getLogger(OANDAReader.class);
|
|
ObjectMapper mapper;
|
|
AccountInfo accountInfo;
|
|
String[] instruments;
|
|
|
|
|
|
public OANDAReader(AccountInfo accountInfo, String[] instruments) {
|
|
this.accountInfo = accountInfo;
|
|
this.instruments = instruments;
|
|
|
|
mapper = new ObjectMapper();
|
|
mapper.registerModule(new JodaModule());
|
|
}
|
|
|
|
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) {
|
|
log.error("Creating stream URL", e);
|
|
}
|
|
|
|
return String.format("https://stream-%s.oanda.com/v3/accounts/%s/pricing/stream?%s",
|
|
type, accountInfo.accountID(), query);
|
|
}
|
|
|
|
private 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 (IOException e) {
|
|
log.error("Reading OANDA stream", e);
|
|
} finally {
|
|
httpConn.disconnect();
|
|
}
|
|
}
|
|
|
|
private void processLine(String line, TickProcessor processor) {
|
|
if (line.indexOf ("PRICE") > -1) {
|
|
OANDATickEvent tick;
|
|
try {
|
|
tick = mapper.readValue(line, OANDATickEvent.class);
|
|
processor.process(tick);
|
|
} catch (JsonParseException | JsonMappingException e) {
|
|
log.error("Parsing OANDA tick", e);
|
|
} catch (IOException e) {
|
|
log.error("Parsing OANDA tick", e);
|
|
}
|
|
} else if (line.indexOf ("HEARTBEAT") > -1) {
|
|
try {
|
|
OANDAHeartbeatEvent beat = mapper.readValue(line, OANDAHeartbeatEvent.class);
|
|
processor.process(new CurrentTimeEvent(beat.getTime().getMillis()));
|
|
} catch (IOException e) {
|
|
log.error("Parsing OANDA heartbeat", e);
|
|
}
|
|
} else {
|
|
log.warn("Unknown type: {}", line);
|
|
}
|
|
}
|
|
}
|