Photon Scripting

Photon has a built-in scripting support for Ruby language, and is intended as a fast prototyping framework for developing algorithms.

Scripts inside Photon have full access to incoming market data, and through a set of APIs have access to a lot of Photon functionality, such as sending orders, listening for execution reports, canceling orders, etc. As a result, Photon provides a sophisticated environment for rapid prototyping of trading algorithms that, if desired, can then be implemented other languages while still sending orders through the Marketcetera Platform.

Stragegy class API

All of Ruby scripts in Photon should derive from the Marketcetera::Strategy class, which provides the following API:

Function NameBehaviour
on_market_data_snapshot(message)Function for listening to incoming market data
on_execution_report(message)Called when Photon receives an Execution Report
sendFIXMessage(message)Sends the passed-in message to the OMS
registerTimedCallback(delay, TimeUnit unit, clientData)Registers a callback function that is called after a specified delay time, passing in the clientData object during callback
timeout_callback(Object clientData)Call-back function that is called with the clientData object after the delay specified in the reigsterTimedCallback function
getLatestExecutionReport(clOrdID)Returns the latest execution report for the specified clOrdID that is in Photon history, or nil
cancelAllOpenOrdersThe "panic button" call that cancels all open orders in Photon

Scripting UI Overview

The Photon application includes an integrated Ruby development environment and scripting engine. Choose "Open Perspective" from the "Window" menu, and choose the Ruby perspective. You should be presented with something like this. The script will not be there, but read on.

http://repo.marketcetera.org/images/screenshots/ruby-perspective.png

This window consists of four sub-windows. At the top left the "Ruby Resources" view allows you to view all of your Ruby scripts, grouped by project and sub-folder. The "Outline" view at the bottom left shows you a representation of the parse of the current Ruby file, showing modules, classes, methods and variables. At the bottom of the screen is the Problems view, which will indicate compile errors in your ruby scripts.

Creating a script and the ActiveScripts project

There is one project that has special status among your Ruby projects: the ActiveScripts project is the only one that will be recognized by the interpreter. Feel free to organize your scripts into other projects, but when it comes time to run a script, it needs to be in the ActiveScripts project, along with any files that it refers to.

To create a script to run, right click on the ActiveScripts project in the "Ruby Resources" view, and choose New->Ruby Class. This will bring up a dialog like this:

http://repo.marketcetera.org/images/screenshots/new-ruby-class.png

In this example, we have replaced the default "Class name" with "MarketWidth". Note that this needs to be a valid Ruby identifier. Clicking finish will create a new file, MarketWidth.rb, in the ActiveScripts folder. To get started, change the default code to look like this, by adding an on_market_data_snapshot(message) method:

require 'java'
module Marketcetera
  include_class "org.marketcetera.photon.scripting.Strategy"
end

class MarketWidth < Marketcetera::Strategy
  def on_market_data_snapshot(message)
    puts "Got a message!"
  end
end

This simple script will simply print a message to the Console view for every message that it receives. The next section describes how to send market data to it.

Registering the script

In order to receive market data, a script must satisfy all of the following, most of which are standard Ruby conventions:

  • Must contain a class definition with an on_message(message) method.
  • The name of the file must be an underscore version of the class name. For example market_width.rb must contain MarketWidth
  • The file must be in the ActiveScripts project, and if it is in a subfolder of ActiveScripts, its module defintion must match the folder hierarchy. For example, !ActiveScripts/sub/a_class.rb must contain a class definition for "Sub::AClass".
  • Any files that the script depends on must also be in the ActiveScripts project.

To register the file, click on Edit->Preferences->Script Registry. Then clicking on the "New..." button will bring up a dialog that will let you choose a script to register for market data.

http://repo.marketcetera.org/images/screenshots/register-script.png

Click the "Browse..." button to bring up a dialog that will let you choose your script from a representation of the ActiveScripts project

http://repo.marketcetera.org/images/screenshots/script-selection.png

Click "Ok" in that dialog, and "Ok" in the "Register Script" dialog. You now should see your script listed in the list. Click OK to save the preferences.

Bring in market data

Now that your script has been registered, any market data that comes into the application will be fed to it. The easiest way to bring in some market data is to put an entry into the "Market Data" view.

http://repo.marketcetera.org/images/screenshots/market-data-view.png

Click in the text area at the top of the Market Data View, type a stock symbol, and hit return. You should see output from the script in the Console View, like this:

http://repo.marketcetera.org/images/screenshots/simple-script-in-action.png

Sample Scripts

You can see a fairly simple and more complicated example scripts. This script looks for a bid/ask spread below a certain threshold and alerts the user like this:

http://repo.marketcetera.org/images/screenshots/script-in-action.png

Where to go from here

If you are new to Ruby, there is lots of great information on the web, you might start at the official Ruby documentation page.

We are using JRuby as the underlying scripting technology, so that you may use Ruby classes and Java classes almost interchangably. More information about JRuby can be found at the JRuby website.

And of course feel free to drop us a line if you have any questions.