Skip to content

Commit

Permalink
Merge Repos (#21)
Browse files Browse the repository at this point in the history
* initial move

* merge configs for docker

* Scaffolding for app in place.

Needs calculator implementations for the methods and valid api urls to fetch dividend yield and risk free interest rate.

* Add attributes we'll need to fill in.

* add greek sample app

* fill in urls for api calls, working without calcs

* risk interest url to be single data point

* group sub

* don't depend on specific contract for example

* Remove not implemented method for now.

* more setup for calc

* method casing

* flip to print all greeks

* order of operations

* calcs

* add one day refresh period

* Start decoupling greeks from current value storage

* Start use of OnUpdated methods

* purge and burninate key

* pass the used value

* No notes on this checkin

* pass the used value

* copy dependencies to target lib

* refactor progress - no compile

* add refresh to cache

* Needs tested. Compiles

* consolidate logging in classes

* switch to only composite example

* removed import

* firehose example

* options delayed

* refresh token every time

* equities always get token

* no delay default

* comment out excessive

* readme update

* version bump

* pom version
  • Loading branch information
ssnyder-intrinio authored Jul 11, 2024
1 parent 8de3684 commit 16a15ce
Show file tree
Hide file tree
Showing 64 changed files with 3,591 additions and 302 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:

jobs:
notify:
if: github.event.pull_request.merged == true && github.ref == 'refs/heads/production'
if: github.event.pull_request.merged == true && github.ref == 'refs/heads/master'

runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ COPY . /intrinio
WORKDIR /intrinio

RUN mvn clean compile package install
RUN cp src/intrinio/config.json target/classes/intrinio/
RUN cp src/intrinio/realtime/equities/config.json target/classes/intrinio/equities_config.json
RUN cp src/intrinio/realtime/options/config.json target/classes/intrinio/options_config.json
RUN apt-get update && apt-get install -y jq
RUN jq -s 'reduce .[] as $item ({}; . * $item)' target/classes/intrinio/equities_config.json target/classes/intrinio/options_config.json > target/classes/intrinio/config.json

CMD mvn exec:java -Dexec.mainClass="SampleApp.SampleApp"
285 changes: 249 additions & 36 deletions README.md

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.intrinio</groupId>
<artifactId>IntrinioRealtimeJavaSDK</artifactId>
<version>6.1.0</version>
<version>7.0.0</version>
<packaging>jar</packaging>
<name>IntrinioRealtimeJavaSDK</name>
<build>
Expand Down Expand Up @@ -44,6 +44,20 @@
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
Expand Down
88 changes: 88 additions & 0 deletions src/SampleApp/CompositeSampleApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package SampleApp;

import intrinio.realtime.composite.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;

public class CompositeSampleApp {
public static void run(String[] args){
String apiKey = "API_KEY_HERE";

intrinio.realtime.options.Config optionsConfig = null;
try{
optionsConfig = new intrinio.realtime.options.Config(apiKey, intrinio.realtime.options.Provider.OPRA, null, new String[]{"MSFT", "NVDA", "AAPL"}, 8, false);
}catch (Exception e){
System.out.println("Error parsing options config: " + e.getMessage());
return;
}

intrinio.realtime.equities.Config equitiesConfig = null;
try{
equitiesConfig = new intrinio.realtime.equities.Config(apiKey, intrinio.realtime.equities.Provider.NASDAQ_BASIC, null, new String[]{"MSFT", "NVDA", "AAPL"}, true, 4);
}catch (Exception e){
System.out.println("Error parsing equities config: " + e.getMessage());
return;
}

//store the most recent values in a simple non-transactional cache that gives contextual information with the event.
intrinio.realtime.composite.DataCache currentDataCache = new CurrentDataCache();

//Initialize Options Client and wire it to the cache
//intrinio.realtime.options.OnUnusualActivity optionsUnusualActivityHandler = null;
intrinio.realtime.options.Client optionsClient = new intrinio.realtime.options.Client(optionsConfig);
optionsClient.setOnTrade(currentDataCache::setOptionsTrade);
optionsClient.setOnQuote(currentDataCache::setOptionsQuote);
optionsClient.setOnRefresh(currentDataCache::setOptionsRefresh);
//optionsClient.setOnUnusualActivity(optionsUnusualActivityHandler);

//Initialize Equities Client and wire it to the cache
intrinio.realtime.equities.OnTrade equitiesTradeHandler = currentDataCache::setEquityTrade;
intrinio.realtime.equities.OnQuote equitiesQuoteHandler = currentDataCache::setEquityQuote;
intrinio.realtime.equities.Client equitiesClient = new intrinio.realtime.equities.Client(equitiesTradeHandler, equitiesQuoteHandler, equitiesConfig);

//Display trade events with context
currentDataCache.setOnEquitiesTradeUpdated((SecurityData securityData, DataCache dataCache) -> {
intrinio.realtime.equities.Client.Log(securityData.getTickerSymbol() + " had a trade and also has " + securityData.getAllOptionsContractData().size() + " active contracts");
});

Runtime.getRuntime().addShutdownHook(new Thread( new Runnable() {
public void run() {
intrinio.realtime.equities.Client.Log("Stopping sample app");
optionsClient.leave();
optionsClient.stop();
equitiesClient.leave();
equitiesClient.stop();
}
}));

try{
equitiesClient.start();
//equitiesClient.joinLobby();
equitiesClient.join();
optionsClient.start();
//optionsClient.joinLobby();
optionsClient.join();
}catch (Exception e) {
e.printStackTrace();
}

Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
try{
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
String date = dtf.format(now);
intrinio.realtime.options.Client.Log(date + " " + optionsClient.getStats());
intrinio.realtime.equities.Client.Log(date + " " + equitiesClient.getStats());
}catch (Exception e){
System.out.println("Error in summary timer: " + e.getMessage());
}
}
};
timer.schedule(task, 30000, 30000);
}
}
46 changes: 46 additions & 0 deletions src/SampleApp/EquitiesQuoteHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package SampleApp;

import java.util.concurrent.ConcurrentHashMap;

class EquitiesQuoteHandler implements intrinio.realtime.equities.OnQuote {
private final ConcurrentHashMap<String, Integer> symbols = new ConcurrentHashMap<String, Integer>();
private int maxQuoteCount = 0;
private intrinio.realtime.equities.Quote maxQuote;

public int getMaxQuoteCount() {
return maxQuoteCount;
}

public intrinio.realtime.equities.Quote getMaxQuote() {
return maxQuote;
}

public void onQuote(intrinio.realtime.equities.Quote quote) {
symbols.compute(quote.symbol() + ":" + quote.type(), (String key, Integer value) -> {
if (value == null) {
if (maxQuoteCount == 0) {
maxQuoteCount = 1;
maxQuote = quote;
}
return 1;
} else {
if (value + 1 > maxQuoteCount) {
maxQuoteCount = value + 1;
maxQuote = quote;
}
return value + 1;
}
});
}

public void tryLog() {
if (maxQuoteCount > 0) {
intrinio.realtime.equities.Client.Log("Most active quote symbol: %s:%s (%d updates)", maxQuote.symbol(), maxQuote.type(), maxQuoteCount);
intrinio.realtime.equities.Client.Log("%s - Quote (type = %s, price = %f, size = %d)",
maxQuote.symbol(),
maxQuote.type(),
maxQuote.price(),
maxQuote.size());
}
}
}
43 changes: 43 additions & 0 deletions src/SampleApp/EquitiesSampleApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package SampleApp;

import java.util.Timer;
import java.util.TimerTask;

public class EquitiesSampleApp {
public static void run(String[] args)
{
intrinio.realtime.equities.Client.Log("Starting sample app");
EquitiesTradeHandler equitiesTradeHandler = new EquitiesTradeHandler();
EquitiesQuoteHandler equitiesQuoteHandler = new EquitiesQuoteHandler();
//intrinio.realtime.equities.Config config = null; //You can either create a config class, or load it from the intrinio/config.json file
//try { config = new Config("apiKeyHere", intrinio.realtime.equities.Provider.REALTIME, null, null, false, 2); } catch (Exception e) {e.printStackTrace();}
//intrinio.realtime.equities.Client client = new Client(equitiesTradeHandler, equitiesQuoteHandler, config);
intrinio.realtime.equities.Client client = new intrinio.realtime.equities.Client(equitiesTradeHandler, equitiesQuoteHandler);

Runtime.getRuntime().addShutdownHook(new Thread( new Runnable() {
public void run() {
client.leave();
intrinio.realtime.equities.Client.Log("Stopping sample app");
client.stop();
}
}));

try{
client.start();
client.join(); //Loads symbols from config
//client.join(new String[] {"AAPL", "GOOG", "MSFT"}, false); //specify symbols at runtime
}catch (Exception e) {
e.printStackTrace();
}

Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
intrinio.realtime.equities.Client.Log(client.getStats());
equitiesTradeHandler.tryLog();
equitiesQuoteHandler.tryLog();
}
};
timer.schedule(task, 30000, 30000);
}
}
46 changes: 46 additions & 0 deletions src/SampleApp/EquitiesTradeHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package SampleApp;

import java.util.concurrent.ConcurrentHashMap;

class EquitiesTradeHandler implements intrinio.realtime.equities.OnTrade {
private final ConcurrentHashMap<String, Integer> symbols = new ConcurrentHashMap<String, Integer>();
private int maxTradeCount = 0;
private intrinio.realtime.equities.Trade maxTrade;

public int getMaxTradeCount() {
return maxTradeCount;
}

public intrinio.realtime.equities.Trade getMaxTrade() {
return maxTrade;
}

public void onTrade(intrinio.realtime.equities.Trade trade) {
symbols.compute(trade.symbol(), (String key, Integer value) -> {
if (value == null) {
if (maxTradeCount == 0) {
maxTradeCount = 1;
maxTrade = trade;
}
return 1;
} else {
if (value + 1 > maxTradeCount) {
maxTradeCount = value + 1;
maxTrade = trade;
}
return value + 1;
}
});
}

public void tryLog() {
if (maxTradeCount > 0) {
intrinio.realtime.equities.Client.Log("Most active trade symbol: %s (%d updates)", maxTrade.symbol(), maxTradeCount);
intrinio.realtime.equities.Client.Log("%s - Trade (price = %f, size = %d, time = %s)",
maxTrade.symbol(),
maxTrade.price(),
maxTrade.size(),
maxTrade.timestamp());
}
}
}
11 changes: 11 additions & 0 deletions src/SampleApp/OptionsQuoteHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package SampleApp;

import java.util.concurrent.atomic.AtomicInteger;

class OptionsQuoteHandler implements intrinio.realtime.options.OnQuote {
public AtomicInteger quoteCount = new AtomicInteger(0);

public void onQuote(intrinio.realtime.options.Quote quote) {
quoteCount.incrementAndGet();
}
}
11 changes: 11 additions & 0 deletions src/SampleApp/OptionsRefreshHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package SampleApp;

import java.util.concurrent.atomic.AtomicInteger;

class OptionsRefreshHandler implements intrinio.realtime.options.OnRefresh {
public AtomicInteger rCount = new AtomicInteger(0);

public void onRefresh(intrinio.realtime.options.Refresh r) {
rCount.incrementAndGet();
}
}
87 changes: 87 additions & 0 deletions src/SampleApp/OptionsSampleApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package SampleApp;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;

public class OptionsSampleApp {
public static void run(String[] args)
{
intrinio.realtime.options.Client.Log("Starting sample app");

// Create only the handlers/callbacks that you need
// These will get registered below
OptionsTradeHandler optionsTradeHandler = new OptionsTradeHandler();
OptionsQuoteHandler optionsQuoteHandler = new OptionsQuoteHandler();
OptionsRefreshHandler optionsRefreshHandler = new OptionsRefreshHandler();
OptionsUnusualActivityHandler optionsUnusualActivityHandler = new OptionsUnusualActivityHandler();

// You can either create a config class or default to using the intrinio/config.json file
//intrinio.realtime.options.Config config = null;
//try {config = new intrinio.realtime.options.Config("apiKeyHere", intrinio.realtime.options.Provider.OPRA, null, null, 8);} catch (Exception e) {e.printStackTrace();}
//intrinio.realtime.options.Client client = new intrinio.realtime.options.Client(config);
intrinio.realtime.options.Client client = new intrinio.realtime.options.Client();

// Register a callback for a graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread( new Runnable() {
public void run() {
client.leave();
intrinio.realtime.options.Client.Log("Stopping sample app");
client.stop();
}
}));

try {
// Register only the callbacks that you want.
// Take special care when registering the 'OnQuote' handler as it will increase throughput by ~10x
client.setOnTrade(optionsTradeHandler);
client.setOnQuote(optionsQuoteHandler);
client.setOnRefresh(optionsRefreshHandler);
client.setOnUnusualActivity(optionsUnusualActivityHandler);

// Start the client
client.start();

// Use this to subscribe to a static list of symbols (option contracts) provided in config.json
client.join();

// Use this to subscribe to the entire univers of symbols (option contracts). This requires special permission.
//client.joinLobby();

// Use this to subscribe, dynamically, to an option chain (all option contracts for a given underlying symbol).
//client.join("AAPL");

// Use this to subscribe, dynamically, to a specific option contract.
//client.join("AAP___230616P00250000");

// Use this to subscribe, dynamically, a list of specific option contracts or option chains.
//client.join(new String[] {"GOOG__210917C01040000", "MSFT__210917C00180000", "AAPL__210917C00130000", "TSLA"});

} catch (Exception e) {
e.printStackTrace();
}

Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
String date = dtf.format(now);
intrinio.realtime.options.Client.Log(date + " " + client.getStats());
String appStats = String.format(
"%s Messages (Trades = %d, Quotes = %d, Refreshes = %d, Blocks = %d, Sweeps = %d, Larges = %d, UnusualSweeps = %d)",
date,
optionsTradeHandler.tradeCount.get(),
optionsQuoteHandler.quoteCount.get(),
optionsRefreshHandler.rCount.get(),
optionsUnusualActivityHandler.blockCount.get(),
optionsUnusualActivityHandler.sweepCount.get(),
optionsUnusualActivityHandler.largeTradeCount.get(),
optionsUnusualActivityHandler.unusualSweepCount.get());
intrinio.realtime.options.Client.Log(appStats);
}
};
timer.schedule(task, 10000, 10000);
}
}
Loading

0 comments on commit 16a15ce

Please sign in to comment.