Optional Java Connector Library

The purpose of this project to offer an easy way to connect and communicate with the QST WebSocket API, using the JSON protocol.

Java Connector API

/**
 * To obtain an instance of this API you have to use the @ConnectorAccessor class. To receive all
 * the @STATUS events with the @IConnectorListener you have to add the listeners before calling the
 * init() method. The init() method should be called when the extension is started. When the
 * extension is stopped or closed you should call the release() method.
 * <p>
 * The getStatus() method will return the current connection status
 */
public interface IConnectorAPI {

  /**
   * Initialize the connector with the token received from the Application. This method must be
   * called to receive any data.
   *
   * @param token
   * @param log This can be a file or a folder where the connector log will be saved.If a folder is
   *        passed then a new folder will be created with the current time representation. If null
   *        is passed a folder will be created at the working folder and all the log will be printed
   *        out in the console.
   */
  void init(String token, File log);

  /**
   * This method should be called when the extension is closed
   */
  void release();

  /**
   * Send a request and wait for the response. The timeout for the response is 3 seconds. If there
   * is no response in 3 seconds null will be returned
   *
   * You don't have to specify the request id ("RQI" attribute) because that is handled by the
   * library
   *
   * @param requestNode
   * @return
   */
  JSNode request(JSNode requestNode);

  /**
   * Add listener to receive updates and events
   * <p>
   * To receive all the connect events you must register the listeners before calling the init()
   * method
   *
   * @param listener
   */
  void addListener(IConnectorListener listener);

  /**
   * Remove listener
   *
   * @param listener
   */
  void removeListener(IConnectorListener listener);

  /**
   * @return get the current connection @STATUS
   */
  STATUS getStatus();

}

Listener

All the updates are sent over this listener. To receive all the updates a listener has to be added before making the register request for Book, Accounts, Chart or Orders updates

/**
 * All the updates and connection updates can be received only with this listener. To receive all
 * the status updates this listener has to be added before calling the init() method in the
 * Connector API
 */
public interface IConnectorListener {

  /**
   * When an update is sent by the server. Some examples: Book,Accounts,Chart,Order and System To
   * receive updates it must be sent a register request
   * <p>
   * To receive all the updates this listener has to be added before making the register requests
   *
   * @param node
   */
  void eventDataUpdated(JSNode node);

  /**
   * When connection status has changed. To receive all the status updates this listener has to be
   * added before calling the init() method in the Connector API
   *
   * @param status
   */
  void eventStatusChanged(STATUS status);

  /**
   * This method is called when the "STOP" button is pressed in the Extension frame. After this
   * method is called the conection will be closed and the release method will be called in 3
   * seconds.
   */
  void eventShutdownSolicited();
}

How to use the library

After the library is added to the project and it has to be specified in the module-info.java file that it requires this library. requires cvs.connector;

1. Obtaining the token

The token is sent by the QST WebSocket API frame as an argument when the jar is started

java public static void main(String[] args) {
  String token = extractToken(args);
  if (token == null) {
   System.out.println("No token received.");
  } else {
   // Initialize the connector
  }
}

/*
* Extract the token from the arguments
* @param args
* @return
*/
public static String extractToken(String[] args) {
  String token = null;
  for (String arg : args) {
    if (arg.startsWith("TK:")) {
    token = arg.substring(3);
    }
  }
  return token;
}

2. Initializing the library

Using the token for the connector library initialization

IConnectorAPI connector = ConnectorAccessor.getInstance();
// Adding a listener to receive all the connection events
connector.addListener(...);
File logFile;
// Calling the init method with the received `Token` and
// specifing a location file or folder where the exceptions will be logged
connector.init(token, logFile);

If the logFile is a file then the exceptions will be logged to that file. If the logFile is a folder then a new folder will be created at that location with the current time 191201011111 and inside that folder a connector.log file will be created. If the logFile is null then a folder will be created at the current working folder same as when a folder is passed

3. Usage after intialization

After the library is initialized and the IConnectorListener is added. Now we can start making requests to the server using the JSON Protocol

Example

1. Snapshot request

Making a snapshot request for ESZ19 contract

// Making a snapshot request for "ESZ19"
IConnectorAPI connector = ConnectorAccessor.getInstance();
// The connector has to be initialized with the token and log file
connector.init(token, logFile);

// Creating the request
JSNode requestNode = new JSNode();
// Setting the request type to snapshot
requestNode.setValue("RQT", "snapshot");
// Specifign the contract for the snapshot
requestNode.setValue("INS", "ESZ19");

// Sending the request and waiting for the response
JSNode response = connector.request(requestNode);
// If the server does't respond then the value will be null
// Verifying if the response is successful
if(response != null) {
    String result = response.getValue("RES");
    if(result!=null && result.equals("OK")){
        // After the response is received an it is a successful request then
        // we can obtain the data with the keys definded in the JSON protocol
        //Examples:

        // Ask price
        String askPrice = response.getValue("AK");

        // Ask timestamp
        String askTimestamp = response.getValue("AT");
    } else {
        requestError();
    }
} else {
    requestError();
}

2. Receiving order entry events

Registering a listener for Order Entry events

IConnectorAPI connectorAPI = ConnectorAccessor.getInstance();
// Adding a listener to receive the updates this is a important
connectorAPI.addListener(new IConnectorListener() {
    @Override
    public void eventStatusChanged(STATUS status) {
      System.out.println("Status= " + status);
    }

     @Override
     public void eventShutdownSolicited() {
       // The extension should be closed
     }

     @Override
     public void eventDataUpdated(JSNode node) {
          // The order entry events will be received here
          if (node.getValue("UPD").equals("Accounts")) {
            System.out.println("Order entry update received: " + node);

          }
          // Other type of updates
          else {
            System.out.println("Update received: " + node);
          }
      }
 });
// Initalizaing the library with the token and the exception will be logged in the working folder      // because null is passed as parameter
connectorAPI.init(token, null);
// Creating the request
JSNode request = new JSNode();
request.setValue("RQT", "oe_register");
JSNode response = connectorAPI.request(request);
if (response != null) {
String result = response.getValue("RES");
if (result != null && result.equals("OK")) {
     // In this case the request was successful an the events will be received in the listener
  }
}