GMapsFX 2.0.6 Released

A new version of GMapsFX has been released to bintray and Maven Central which contains

  • additional bug fixes related to hiding/showing the directions pane at runtime.
  • Ability to pass the map/directions language to the Google map at runtime, eliminating the need to hardcode it.

Screen Shot 2016-05-20 at 2.25.33 PM.png

<dependency> 
  <groupId>com.lynden</groupId> 
  <artifactId>GMapsFX</artifactId> 
  <version>2.0.6</version> 
</dependency>

 

GMapsFX Home: http://rterp.github.io/GMapsFX/
twitter: @RobTerpilowski

GMapsFX 2.0.5 Released

GMapsFX 2.0.5 has been released and is now available via bintray and maven central.

This version contains a major bugfix where the directions pane was always enabled.  The framework has been updated to make the direction pane an option that can be toggled on or off at runtime as it is needed.

GMapsFX is a Java library that makes it extremely easy to add a Google Map to a JavaFX application.

 

<dependency> 
  <groupId>com.lynden</groupId> 
  <artifactId>GMapsFX</artifactId> 
  <version>2.0.5</version> 
  <type>pom</type> 
</dependency>

 

GMaps Home: http://rterp.github.io/GMapsFX/
twitter: @RobTerpilowski

Automatically Cloning a Wildfly Instance Using Chef

As we have started moving to a service based architecture, we have been developing processes to create and configure our infrastructure in a predictable and repeatable way using Vagrant and Chef.  One challenge that we have faced is trying to replicate a production Wildfly server on a dev box, including the applications are installed on it and their correct versions.

Ideally, we’d like the developer to be able to specify which server they want to clone when kicking off the Chef process.  Chef would then create a new Wildfly instance and download and install all the web applications running on the specified instance.

The first question Chef will need to know, is “what what Wildfly servers are running on the network?”  The next question is then, “which applications, and what versions are installed on those servers?”

In order to answer these questions, we developed a “WildflyMonitor” web application which is installed on each of our Wildfly instances.  The application will collect information about the local Wildfly instance that it’s running on, including the names and versions of the hosted apps, and publish that information to our messaging system.  This information eventually makes it into our Wildfly Registry DB, where it is collected and organized by Wildfly instance.

A rough diagram of the architecture appears below.

WildflyRegistry

In the example, there are 3 Wildfly instances, lisprod01, 02, and 03, which are reporting their applications to the registry. The table below the DB illustrates how the data is organized by server, and then by applications, with each Wildfly instance is running 2 applications.    The WildflyRegistry REST service then makes this information available to any client on the network, including Chef recipes.

 

The next step is then to modify the Chef script


require 'net/http'
require 'json'
url = 'http://lweb.lynden.com/WildflyRegistry/registry/services&#39;
webapps = []
resp = Net::HTTP.get_response(URI.parse(url))
resp_text = resp.body
data =JSON.parse(resp_text)
servers = data
# Loop through each Wildfly server that was found
servers.each do |server|
serverName = server["serverName"]
#Is this the server we want to clone?
if serverName == cloneServer then
wildFlyApps = server["wildflyApp"]
#Loop through app on the server
wildFlyApps.each do |app|
#Create a hash of app name to app version
if app["appRuntimeName"].end_with? ".war" then
appTokens = app["appName"].split("-")
myHash = Hash[ :name, appTokens[0], :version, appTokens[1]]
webapps.push(myHash)
end
end
end

view raw

getAppNames.rb

hosted with ❤ by GitHub

The snippet above shows the script contacting the REST service, looping through all the servers that were returned until the desired server to clone is found.  Once the server is found, the script loops through that server’s list of applications and creates a list of hashes with the app name mapped to its version number.

Next, the script loops through each of the apps which were discovered in the previous snippet.


webapps.each do |app|
url = "http://nexus.lynden.com/repo/com/lynden/&quot; + app[:name] + "/" + app[:version] + "/" + app[:name] + "-" + app[:version] + ".war"
puts "deploying " + app[:name] + "-" + app[:version]
fullFileNameNew = app[:name] + "-" + app[:version]
fullPath = "/tmp/" + app[:name] + "-" + app[:version]
fullPath = fullPath + ".war"
puts "Full path to apps " + fullPath
remote_file fullPath do
source url
action :create_if_missing
end
bash 'deploy_app' do
cwd '/usr/local/wildfly/bin'
command = '/tmp/deployWildfly.sh ' + fullPath
code <<-EOH
echo COMMAND #{command}
#{command}
EOH
end
end

view raw

deploy.rb

hosted with ❤ by GitHub

 

First the script constructs the URL to the web app in our Nexus repository. The script then downloads each web app to the tmp folder on the server.  The script then calls a shell script which deploys the applications to Wildfly utilizing the Wildfly command line interface.

The shell script which is called by Chef to perform the actual deployment to Wildfly is fairly straightforward and appears below.


!/bin/sh
FILENAME=$1
PATH=$PATH:/usr/local/java/bin
cd /usr/local/wildfly/bin
./jboss-cli.sh -c –user=myUser –password=myPassword –command="deploy $FILENAME"

 

That’s it, based on the data in our WildflyRegistry we are able to use this Chef script and shell script to create a clone of an existing Wildfly instance running on our network.

 

 

GMapsFX 2.0.4 Released

A minor update of GMapsFX has been released this week which provides a bugfix for an issue that was preventing the GMapsFX GoogleMapView component from being loaded into Scene Builder under certain circumstances.

The release number is 2.0.4 and is currently available from BinTray, and hopefully should be available via Maven Central in the next couple of days.

twitter: @RobTerpilowski
LinkedIn: RobTerpilowski

 

Screen Shot 2016-03-18 at 3.40.46 PM

 

 

GMapsFX 2.0.3 Released With Support for Directions, Elevation, and Geocoding APIs

I have just released version 2.0.3 which includes support for the following major new features:

Directions API
Elevation API
Geocoding API

http://rterp.github.io/GMapsFX/

Below is an example of a JavaFX application displaying a Google map with directions, utilizing the Directions API.

Screen Shot 2016-03-18 at 3.40.46 PM.png

This release has been uploaded to bintray, and should hopefully be available on maven central by next week.

Blog posts to follow this one with tutorials on how to use each one of these new APIs.

https://bintray.com/artifact/download/rterp/maven/com/lynden/GMapsFX/2.0.3/GMapsFX-2.0.3.jar

twitter: @RobTerpilowski
LinkedIn: RobTerpilowski

 

Placing Trades with Interactive Brokers using the SumZero Trading API

Placing trades through Interactive Brokers using the SumZero Trading API is a relatively straightforward task, with support for Equity, Futures, and Foreign Exchange orders.  A few examples are below that illustrate how to place orders for the various markets as well as screenshots of Interactive Brokers Trader Workstation (TWS), which is their desktop trading client.  The API interacts with Trader Workstation, and when a trade is placed via the API, the trade will then appear in Trader Workstation where it is routed to Interactive Brokers, and then on to its specified exchange.

 

Equity Order

In the equity order example below, a connection to the Interactive Brokers client is obtained, which is running on the localhost at port 7999.

A StockTicker object is constructed for Amazon (ticker AMZN), the SumZero library initializes default properties for the ticker such as which exchange to route to.

The next order ID is obtained from the broker, and a TradeOrder object is constructed, specifying the orderId, the ticker symbol for the order, the number of shares, and whether this is a buy or sell order.

The order is then placed with the Interactive Brokers client.

If no other parameters are specified on the order, it is assumed to be a market order which will be placed in the market immediately after it is passed to the broker.

In the example below, we are placing a market order to sell 500 shares of Amazon.


public void placeEquityOrder() {
InteractiveBrokersClientInterface ibClient = InteractiveBrokersClient.getInstance("localhost", 7999, 1);
ibClient.connect();
StockTicker amazonTicker = new StockTicker("AMZN");
String orderId = ibClient.getNextOrderId();
int shares = 500;
TradeOrder order = new TradeOrder(orderId, amazonTicker, shares, TradeDirection.SELL);
ibClient.placeOrder(order);
}

view raw

StockTrade.java

hosted with ❤ by GitHub

 

Below is a screen shot of Interactive Brokers Trader Workstation.  There is a line with price information for Amazon stock (AMZN), showing a bid price of $559.02 and an ask of $559.80.  In the line immediately below, the order is visible which was placed by the code above.  A market order to sell 500 shares of Amazon.

 

AMZN

 

Futures Order

Submitting orders for the futures markets is very similar to the equity markets, except a few more parameters need to be specified when building a ticker, such as what month and year that desired futures contract is expiring.

In the example below, we build a new FuturesTicker object for crude oil, specifying the symbol “CL”, and a contract expiration of April 2016.  Also, the exchange needs to be specified for futures, which in this case is NYMEX.

From this point on, the order process is exactly the same as the previous example.  This time however, we’ll place a limit order to buy 5 contracts at $32.50, meaning that the price needs to come down to at least $32.50 for the trade to be executed.


public void placeFuturesOrder() {
InteractiveBrokersClientInterface ibClient = InteractiveBrokersClient.getInstance("localhost", 7999, 1);
ibClient.connect();
//Create a crude oil futures ticker
FuturesTicker futuresTicker = new FuturesTicker();
futuresTicker.setSymbol("CL");
futuresTicker.setExpiryMonth(4);
futuresTicker.setExpiryYear(2016);
futuresTicker.setExchange(Exchange.NYMEX);
String orderId = ibClient.getNextOrderId();
int contracts = 5;
//Create the order and send to Interactive Brokers
TradeOrder order = new TradeOrder(orderId, futuresTicker, contracts, TradeDirection.BUY);
order.setType(TradeOrder.Type.LIMIT);
order.setLimitPrice(32.50);
ibClient.placeOrder(order);
}

 

The result of the example is illustrated in the screenshot of TWS below.  There is a line corresponding to April 2016 Crude Oil, (CL Apr’16 @NYMEX), which shows a bid price of $33.22 and ask of $33.23.  On the line immediately below, the order that was submitted by the program above is shown.  Buy 5 contracts at a limit price of $32.50.

CL

 

Foreign Exchange Order

Finally, in the last example I’ll show how to place an order for foreign currencies through the API.

Again, the general process is the same as above, in this example we’ll construct an order to buy 50,000 Euros.

The symbol for the currency ticker is “EUR”, and the underlying currency needs to be set to “USD”.  The exchange where currency trades are executed at Interactive Brokers is “IDEALPRO”.  The amount of the order is set to 50000, and the TradeOrder object is constructed to buy at the market price.


public void placeCurrencyOrder() {
InteractiveBrokersClientInterface ibClient = InteractiveBrokersClient.getInstance("localhost", 7999, 1);
ibClient.connect();
CurrencyTicker eurTicker = new CurrencyTicker();
eurTicker.setSymbol("EUR");
eurTicker.setCurrency("USD");
eurTicker.setExchange(Exchange.IDEALPRO);
String orderId = ibClient.getNextOrderId();
int amount = 50000;
TradeOrder order = new TradeOrder(orderId, eurTicker, amount, TradeDirection.BUY);
ibClient.placeOrder(order);
}

view raw

FxOrder.java

hosted with ❤ by GitHub

 

 

The TWS screenshot below shows the EUR row denoted by “EUR.USD”, with a bid and ask price of $1.08695.  The row immediately below shows our order to buy 50,000 EUR at the market price, routed to IDEALPRO

EUR

 

These were some simple examples of various order types that can be submitted to buy/sell equities, futures, and currencies at Interactive Brokers.  More complex order types such as OCO, OSO, FOK, MOC, etc. are possible with the SumZero API, and will be shown in future posts.

twitter: @RobTerpilowski
twitter: @SumZeroTrading
LinkedIn: Rob Terpilowski

 

 

 

JavaFX vs. Swing vs. HTML5, Who Wins? – My Interview with Alexander Casall

In November 2015 Dirk Lemmermann (Freelancer) and Alexander Casall of Saxonia Systems had a JavaOne session about JavaFX Real World Applications. The article 20 JavaFX real-world applications summarizes the presentation by showing the applications that they’ve talked about. In addition to providing example applications for the article, I was interviewed by Alexander to get my thoughts on JavaFX and desktop development in general. The interview appears below.

Can you tell us about the highlights when you used JavaFX?

The animated transitions and effects such as blurring or drop shadows make a huge difference in the user experience of the application when implemented properly. These are small details that sometimes get glossed over, but when introduced to an application can create a very polished UI.  The effects and transitions were something that were possible to do with Swing, but it was so painful.  I don’t remember how many times I had to override the paintComponent() method to customize the look of a particular component, but all of this is baked into the JavaFX framework, allowing you to do these things in literally a few lines of code.

What is your general opinion about JavaFX?

Overall I am pleased with JavaFX as a successor to Swing.  The addition of property bindings, which eliminate the need for event listeners in many circumstances helps cut down on some of the code complexity.  I also like the fact that there is a very clear seperation between the model, view, and controller, where the view is FXML, the model can be a collection of JavaFX properties, and the controller utilizes dependency injection to have the UI components passed in.  There are some nice tools for doing JavaFX development, including NetBeans for coding, SceneBuilder as a WYSIWYG design tool and ScenicView to help visual provide information about the application while it is running.

JavaFX, Swing, SWT, HTML5 – Who wins – or better, when to use what?

For a new application I would not consider Swing or SWT, which leaves either JavaFX or HTML5 as the remaining options.  In this case there is not a clear winner, but a set of tradeoffs one needs to consider when making a decision.  With HTML5 you have the advantage of being able to deploy your application across many different platforms (phones, tablets, and Desktops), as well as multiple OSs (Windows, Mac, Linux).  There is also the benefit of a huge development community and large selection of open source tools and frameworks.  The ease of deployment across platforms comes at a cost however, in that you must operate within the constraints that are placed on you by the browser. The amount of time debugging issues across different browsers or OSs is often overlooked or underestimated by teams when deciding whether or not to go the desktop or web app route.  We recently worked on a project where a very large chunk of time had been consumed in order to get a piece of functionality working correctly in IE 9 on Windows.With JavaFX the drawback is that the user has to download and install something to their desktop, which is becoming very old fashioned.  But if this is not an issue, then you are free to develop outside the constraints of the browser and use the full power of the Java language and the eco system that backs it.For applications that are used internally within the company I feel that it makes a lot of sense to deploy these at desktop applications for this reason.  Deployments are not an issue in this case as we can automatically push out new installations or updates to PCs in our network automatically.  We also bundle a private JRE with the application so we don’t need to worry about which version(s) of Java the user has installed on their PC.

How satisfied are you with the work of Oracle on JavaFX?

Jonathan Giles and his team have been doing great work at Oracle adding improving and enhancing the JavaFX libraries.  That being said, it would be nice if Oracle officially stated what their long term plans are with JavaFX.  When Oracle let go of some of their evangelists (who were big proponents of JavaFX), just before JavaOne it started a rumor mill of what may have been behind the move.  The uncertainty this has created, and lack of official communication from Oracle will likely deter some development teams who may be on the fence about whether they should port legacy Swing application to JavaFX or HTML5. Over time this will potentially affect how large the JavaFX community eventually becomes.

What do you miss in the work with JavaFX?

The amount of 3rd party component libraries (both open source and commercial) that are available for JavaFX is still somewhat limited at this point, but that should change as the JavaFX community continues to grow.

 

twitter: @RobTerpilowski
LinkedIn: Rob Terpilowski

Subscribing to Real-Time Market Data With Interactive Brokers Using the SumZero Trading API

Connecting to Interactive Brokers to receive streaming real-time market data is easy with the SumZero Trading API.  This example will illustrate how to connect to an Interactive Brokers TraderWorkstation (TWS) or IB Gateway instance in order to obtain quotes for Amazon.


import com.sumzerotrading.data.StockTicker;
import com.zerosumtrading.interactive.brokers.client.InteractiveBrokersClient;
import com.sumzerotrading.marketdata.ILevel1Quote;
import com.sumzerotrading.marketdata.QuoteType;
public class MarketDataStocksExample {
public void start() {
InteractiveBrokersClient ibClient = new InteractiveBrokersClient("localhost", 6468, 1);
ibClient.connect();
StockTicker stockTicker= new StockTicker("AMZN");
ibClient.subscribeLevel1(stockTicker, (ILevel1Quote quote) -> {
if( quote.getType().equals(QuoteType.LAST) ){
System.out.println("Received Quote: " + quote.getValue() );
}
});
}
public static void main(String[] args) {
new MarketDataStocksExample().start();
}
}

The first step is to create a new InteractiveBrokersClient object passing in the hostname that TWS or IB Gateway is running on, the port that is listening on, as well as a client ID for the connection.  All connections to Interactive Brokers require a client ID which must be unique for each application that connects via the API.

Once the connection is established a new StockTicker object is created which will be used to subscribe to market data for Amazon (AMZN).  In order to subscribe to market data the subscribeLevel1() method needs to be called on the client object and passed a Level1Listener object.  In this case a lambda expression is passed in which will check the type of Level1Quote that was received, and if the quote was a ‘Last’ price, as opposed to a bid or ask, then print the value of that price to the console.

For this example I’ve connected to the special Interactive Brokers “edemo” account which is free to use, but provides fictitious data for its data feed.  It is a good account to test with to make sure that an application is connecting and receiving data as expected.

The output of the example application which was running within NetBeans IDE appears below.

Screen Shot 2016-02-08 at 7.22.31 AM

SumZero API Github project page

twitter: @RobTerpilowski
twitter: @ZeroSumTrading

Developing Trading Applications with the SumZero Trading API

I have open sourced a Java trading library which I have been using to develop automated trading applications for many years.  The SumZero Trading API provides the ability to develop trading applications for the equity, futures, and currency markets, by utilizing the following sub APIs

  • Market Data API – Request real time Level 1 (NBBO) and Level 2 (Market Depth) market data
  • Broker API – Submit, execute, and monitor orders
  • Historical Data API – Request intraday and end-of-day historical market data.
  • Strategy API – Develop trading strategies to automatically place buy/sell orders based on user defined algorithms.

The library includes implementation of all of these APIs for Interactive Brokers, except for the Broker API, which also has an implementation for Quantitative Brokers.

The libraries are licensed under the MIT open source license and source code is available at:
https://github.com/rterp/SumZeroTrading

In future posts I will show how easy it is to connect to Interactive Brokers to request real-time market data and place a trade using the API.

twitter: @RobTerpilowski
twitter: @SumZeroTrading

Using Apache Camel and ActiveMQ to Implement Synchronous Request/Response.

Implementing a synchronous request/response pattern with Apache Camel and ActiveMQ is quite a bit easier than you may expected, and has allowed us to leverage our current messaging infrastructure to facilitate synchronous exchanges between applications where we otherwise may have needed to create a new web service.

Below is an example of setting up two Camel endpoints which will demonstrate the request/response pattern.

First, configure the connection to the JMS message broker.  In this case, an ActiveMQ broker is created in-process.


public void startBroker() throws Exception {
context = new DefaultCamelContext();
context.addComponent("jms-broker", activeMQComponent("vm://localhost?broker.persistent=false"));
buildProducerRoute(context);
buildConsumerRoute(context);
context.start();
}

 

Next, set up the producer route.  First a processor is created, which will print the body of the message.  The route will be executed when a file is dropped into the /Users/RobTerpilowski/tmp/in directory, and routed to the robt.test.queue destination.  Once the route has completed, the processor will be executed.  What we are hoping to see is that the message has been modified by the consuming endpoint when this route has completed.  The important piece to note here is the url:
jms-broker:queue:robt.test.queue?exchangePattern=InOut
exchangePattern=InOut tells Camel that the route is a syncrhonous request/response


public void buildProducerRoute(CamelContext context) throws Exception {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
Processor processor = (Exchange exchange) -> {
System.out.println("PRODUCER Received response: " + exchange.getIn().getBody(String.class));
};
from("file:///Users/RobTerpilowski/tmp/in")
.to("jms-broker:queue:robt.test.queue?exchangePattern=InOut")
.process(processor);
}
});
}

 

Next, set up the consumer endpoint.  Again, a processor is created which will be run when the route has completed.  This processor will first print the message that the producer sent.  It will then replace the message with a new message saying that the original message was seen.  This endpoint will listen on the robt.test.queue and route the result to the directory /Users/RobTerpilowski/tmp/out.  When the route has completed, the processor will update the message.  If everything works correctly, the producer endpoint should be able to see the modified message.


public void buildConsumerRoute(CamelContext context) throws Exception {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
Processor processor = (Exchange exchange) -> {
System.out.println("CONSUMER received message: " + exchange.getIn().getBody(String.class));
exchange.getIn().setBody("I Saw it!!! It contained: " + exchange.getIn().getBody(String.class));
};
from("jms-broker:queue:robt.test.queue")
.to("file:///Users/RobTerpilowski/tmp/out")
.process(processor);
}
});
}

So now that the routes are set up, it’s time to send a message.  Saving a file in the specified input directory will kick things off.  The file will contain the text “HelloCamel”.

 

$ echo "HelloCamel" > /Users/RobTerpilowski/tmp/in/message.txt

The consumer listening on the robt.test.queue immediately sees the message arrives, and prints the message body.

CONSUMER received message: HelloCamel

 

The producer endpoint then receives the modified message back, with confirmation that the consumer endpoint did indeed see the message.

PRODUCER Received response: I Saw it!!! It contained: HelloCamel

 

Make Sure Your Server Clocks are in Sync!

As I finished my first test services that would utilize the Request/Response pattern I created an integration test where they connected to messaging broker that was running in-process.  Things looked great, and the services were communicating without any issues.  I deployed the services to a Wildfly instance running locally, which were pointing at a messaging broker on our staging server.  However, this time when I started my test, the requests were consistently timing out, and never making it back from the second service.  I literally spent the entire day deconstructing each service piece by piece to see what was going on.  I then remembered something about clock synchronization in the Camel JMS documentation.  I checked both the clock on the VM and the clock on the staging server and proceeded to do a face palm when I saw there was a four hour difference, lesson learned!

 

twitter: @RobTerpilowski