AlgoTraderAlgoTrader Documentation

Development Guide

AlgoTrader


Preface
1. Document Conventions
1.1. Typographic Conventions
1.2. Pull-quote Conventions
1.3. Notes and Warnings
1. Introduction
2. Building AlgoTrader
2.1. Command Line
2.1.1. Git Checkout
2.1.2. Maven Build
2.1.3. Docker Build
2.2. Eclipse
2.2.1. Git Checkout
2.2.2. Maven Build
2.2.3. Docker Build
3. Domain Model
3.1. Security Visitors
3.2. Data access objects (DAOs)
3.3. Services
3.3.1. Private Services
3.3.2. Order Services
3.3.3. Market Data Services
3.3.4. Historical Data Services
3.3.5. Reference Data Services
4. Java Environment
4.1. AlgoTrader Project Structure
4.1.1. common project
4.1.2. core project
4.1.3. conf project
4.1.4. launch project
4.1.5. strategy projects
4.2. Java Packages & Classes
4.3. Maven Environment
4.3.1. Maven assemblies
5. Code Generation
6. Database
6.1. Database scripts
6.2. Transaction Handling
7. Market Data
8. Adapters
8.1. Fix Interface
8.2. Bloomberg
8.3. IB Native Interface
8.4. QuantHouse
8.5. Binance
8.6. Bitfinex
8.7. Bitflyer
8.8. BitMEX
8.9. Bitstamp
8.10. CoinAPI
8.11. Coinigy
8.12. CoinMarketCap
9. Execution Algos
9.1. Development of Execution Algos
10. Spring Services
10.1. Wiring Factories
10.2. ApplicationContext
10.3. Abstract Services
10.4. Service initialization order
11. Events and Messaging
11.1. Embedded ActiveMQ message broker
11.2. STOMP messaging over WebSockets transport
11.3. Embedded Jetty HTTP server
11.4. RESTful interface
11.5. JSON data binding
11.6. EventDispatcher
11.7. Event listeners
11.8. JMS Destinations
12. Configuration and Preferences API
12.1. Config Providers
12.2. Config Beans
12.3. Config Locator
13. Processes and Networking
13.1. Processes
13.2. Sockets
13.3. RMI
14. Hibernate Sessions and Caching
14.1. Hibernate Caching
14.1.1. Level-Zero Cache
15. Logging
15.1. Custom UI LogEventAppender

This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information.

In PDF and paper editions, this manual uses typefaces drawn from the Liberation Fonts set. The Liberation Fonts set is also used in HTML editions. If not, alternative but equivalent typefaces are displayed.

The following typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows.

System input, including shell commands, file names and paths, and key caps and key-combinations are presented as follows.

The above includes a file name, a shell command and a key cap, all distinguishable thanks to context.

Key-combinations can be distinguished from key caps by the symbol connecting each part of a key-combination. For example:

The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously.

If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph are presented as follows.

Words or phrases encountered on a system, including application names; dialog box text; labeled buttons; check-box and radio button labels; menu titles and sub-menu titles are presented as follows.

The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all distinguishable by context.

Note the shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select Mouse from the Preferences sub-menu in the System menu of the main menu bar' approach.

Italics denotes text that does not need to be imputed literally or displayed text that changes depending on circumstance. Replaceable or variable text is presented as follows.

Note the words in italics above — username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text entered when issuing a command or for text displayed by the system.

AlgoTrader can be built from its source either via command line or via Eclipse

Note

AlgoTrader based trading strategies can be developed and started without building AlgoTrader first

To build AlgoTrader from within Eclipse please follow this process.

This will result in the following Eclipse projects:

  • algotrader-common

  • algotrader-core

  • algotrader-conf

  • algotrader-launch

Note

The compilation will show errors, which should go away after the next section has been completed.

The Visitor Pattern is a way of separating an algorithm from an object structure on which it operates. Using this pattern it is possible to implement custom Logic per Entity without polluting the Entity code itself.

AlgoTrader provides the interface ch.algotrader.visitor.EntityVisitor which must be implemented by all Entity Visitors. Each Entity Visitor has two generic type parameters R and P. R is the return type (or java.lang.Void) returned by all visit methods and P is an arbitrary parameter object that can be added to the visit methods.

In addition there is the ch.algotrader.visitor.PolymorphicEntityVisitor which reflects the entire inheritance tree of all Securities. For example if there is no visitFuture method the PolymorphicEntityVisitor will automatically invoke the visitSecurity method.

The accept method of each Entity can be used to process an arbitrary Visitor like this:

entity.accept(MyVisitor.INSTANCE);

In AlgoTrader there are two Visitors available which are used by the AlgoTrader Server

InitializingVisitor

Is used to make sure certain Hibernate Entity References are initialized / loaded.

ScalingVisitor

is used to scale quantities and prices

SecurityVolumeVisitor

Is used to determine if a particular Security is supposed to report volumes

TickValidationVisitor

Used to validate a Tick by rules defined per Security

The AlgoTrader DAO framework of consists of several main components

It is possible to add custom DAOs to the platform. To accomplish this one needs to create a DAO interface extending either ReadOnlyDao or ReadWriteDao, add custom operations such as entity specific finders and then create a custom DAO class extending AbstractDao and implementing the custom DAO interface.

public class MyEntity implements BaseEntityI {


    private long id;
    private String name;
    @Override
    public long getId() {
        return this.id;
    }
    protected void setId(final long id) {
        this.id = id;
    }
    @Override
    public boolean isInitialized() {
        return true;
    }
    public String getName() {
        return this.name;
    }
    public void setName(final String name) {
        this.name = name;
    }
}
public interface MyEntityDao extends ReadWriteDao<MyEntity> {


    public MyEntity findByName(String name);
}
@Repository

public class MyEntityDaoImpl extends AbstractDao<MyEntity> implements MyEntityDao {
    public MyEntityDaoImpl(final SessionFactory sessionFactory) {
        super(MyEntity.class, sessionFactory);
    }
    @Override
    public Strategy findByName(final String name) {
        return findUniqueCaching(
            "from MyEntity where name = :name", QueryType.HQL, new NamedParam("name", name));
    }
}

HQL and SQL queries used by AlgoTrader DAO components are externalized and stored in Hibernate.hbm.xml file. This allows for better management and for easier re-use of queries.



<query name='Strategy.findByName'>
<![CDATA[
    from StrategyImpl
    where name = :name
]]>
</query>
            

Queries can be accessed from DAO classes or custom components by their names



public class StrategyDaoImpl extends AbstractDao<Strategy> implements StrategyDao {
    ...
    @Override
    public Strategy findByName(final String name) {
        return findUniqueCaching(
            "Strategy.findByName", QueryType.BY_NAME, new NamedParam("name", name));
    }
            

Table 3.1. Private Services

ServiceDescription
AlgoOrderServiceOrder Services responsible for handling of AlgoOrders (delegates to AlgoOrderExecServices)
AlgoOrderExecServiceAbstract Base Class for all Algo Execution Order Services
ExternalAccountServiceAbstract Base Class for all external Account Interfaces
ExternalMarketDataServiceAbstract Base Class for all external Market Data Interfaces
FixSessionServiceExposes properties of FIX sessions
ForexServiceResponsible for the FX Hedging functionality
GenericOrderServiceParent Class for all Order Services
MarketDataPersistenceServiceResponsible for persisting Market Data to the database
OrderExecutionServiceResponsible for handling of persistence and propagation various trading events such as order status update and order fills as well as maintaining order execution status in the order book.
OrderPersistenceServiceResponsible for persisting Orders and OrderStatus to the database
ReconciliationServiceResponsible for reconciliation of reports provided by the broker
ResetServiceResponsible for resetting the DB state (e.g. before the start of a simulation)
ServerLookupServiceProvides internal data lookup operations to other server side services
SimpleOrderServiceOrder Service responsible for handling of Simple Orders (delegates to SimpleOrderExecServices)
SimpleOrderExecServiceAbstract Base Class for all Simple Order Execution Services
StrategyPersistenceServiceHandles persistence of Strategy Entities
TransactionPersistenceServiceResponsible for the persistence of Transactions, Positions updates and Cash Balance updates to the database
TransactionServiceResponsible for handling of incoming Fills

The Framework AlgoTrader consists of the following Sub-Projects:

Java Entities, Entity Interfaces and Value Objects are created by the means of the Hibernate Tools project using the hbm2java code exporter.

The Hibernate Tools project provides the code generator as an Eclipse plugin as well as a set of Ant tasks. AlgoTrader provides a custom maven plugin called maven-codegen-plugin which wraps the code generator.


<groupId>algotrader</groupId>
<artifactId>model-codegen-plugin</artifactId>
<name>Model code generator plugin</name>
<version>0.1.5</version>

The maven-codegen-plugin has been added to the file /algotrader/common/pom.xml


<plugin>
    <groupId>algotrader</groupId>
    <artifactId>model-codegen-plugin</artifactId>
    <version>0.1.5</version>
    <executions>
        <execution>
            <id>generate-model</id>
            <goals>
                <goal>codegen</goal>
            </goals>
            <configuration>
                <templates>
                    <template>
                        <file>pojo/Pojo.ftl</file>
                        <pattern>{package-name}/{class-name}.java</pattern>
                    </template>
                    <template>
                        <file>pojo/Interface.ftl</file>
                        <pattern>{package-name}/{class-name}I.java</pattern>
                    </template>
                    <template>
                        <file>pojo/ValueObject.ftl</file>
                        <pattern>{package-name}/{class-name}VO.java</pattern>
                    </template>
                    <template>
                        <file>pojo/ValueObjectBuilder.ftl</file>
                        <pattern>{package-name}/{class-name}VOBuilder.java</pattern>
                    </template>
                </templates>
            </configuration>
        </execution>
    </executions>
</plugin>

The above configuration generates the following artifacts for each Java Entity defined in the Hibernate mapping files:

  • Entity

  • Entity interface

  • Value Object

  • Value Object Builder

The code generator uses Hibernate mapping files which are located in /algotrader/common/src/main/resources in combination with Freemarker templates which are located in /algotrader/common/pojo . These templates are based on the original version supplied with the Hibernate Tools project but have been augmented to produces Java code needed by AlgoTrader. For this purpose several custom attributes have been added to Hibernate mapping files:


Generated code is placed under the directory /algotrader/common//target/generated-sources/main/java.

All Market Data Interfaces have a set of unique artifacts:

Processing of Market Data is handled through the MarketDataService, which calls the market data provider specific ExternalMarketDataService implementations. Every market data service has to provide implementation of this interface e.g. (e.g. IBMarketDataServiceImpl or BBMarketDataServiceImpl).

The most important methods provided by the MarketDataService are subscribe and unsubscribe. Through the use of these methods new Market Data can be subscribed and unsubscribed. Subscribed securities are persisted within the DB-table subscription. The actual subscription of securities to the external broker is done through the market data provider specific MarketDataService.

Market data provider interfaces are responsible for receiving market data provider specific Market Data and sending them into the Esper Service Instance of the AlgoTrader Server. The Esper Service Instance will then convert these Events into generic MarketDataEvents (i.e. Ticks or Bars) which will be propagated to subscribed Strategies.

The Fix infrastructure consists of the following classes:

Table 8.1. Fix Infrastructure

Class / InterfaceDescription
SessionA Session represents a connection to a broker / exchange / market data provider
ApplicationFor each Session an Application object is created. It will forward incoming messages to the corresponding MessageHandlers
DefaultFixApplication
FixApplicationFactoryIs responsible for the creation of Applications
DefaultFixApplicationFactory
FixMultiApplicationSessionFactory

Creates a Session and Application using the specified FixApplicationFactory according to the following steps:

  • lookup the FixApplicationFactory by its name

  • create an Application

  • create a DefaultSessionFactory

  • create a Session

ExternalSessionStateHolder Represents the current state of a Session (i.e. DISCONNECTED, CONNECTED, LOGGED_ON and SUBSCRIBED)
DefaultFixSessionStateHolder
MarketDataFixSessionStateHolderA ExternalSessionStateHolder for market data sessions that will subscribe to securities as soon as the session is logged on.
FixOrderIdGeneratorGenerator for Fix Order Ids. The default implementation reads the last Order Ids from the Fix log on start-up.
DefaultFixOrderIdGenerator
FixAdapter Management Adapter for the Fix environment. Allows the creation of dynamic sessions, sending Messages and managing Order Ids.
DefaultFixAdapter
ManagedFixAdapterManageable implementation of a FixAdapter (based on JMX)
FixEventSchedulerQuickFix/J currently supports daily sessions (with a daily session 7 times a week) and weekly sessions (with one weekly session). However some brokers (e.g. JP Morgan) use daily sessions during workdays. To accomplish this scenario, AlgoTrader allows creation of a weekly logon/logoff event (e.g. Mo 08:00:00 and Fr 18:00:00) using Esper Statements
DefaultFixEventScheduler
EventPattern
FixSocketInitiatorFactoryBeanA Spring Factory Bean that creates the SocketInitiator necessary for all Fix Sessions.
Fix42MarketDataMessageHandlerMessage Handler for incoming Fix market data messages. These classes need to be sub classed by the corresponding market data interface. Messages are propagated into the Esper Engine.
Fix44MarketDataMessageHandler
Fix42OrderMessageHandlerMessage Handler for incoming Fix Execution Reports. These classes need to be sub classed by the corresponding order interface. Messages are propagated into the Esper Engine.
Fix44OrderMessageHandler

Additional Execution Algos can be added to the system with minimal effort. Execution Algos consist of the following artifacts

The OrderService is aware of all AlgoOrderExecService instances declared in the Spring application context of the server process. Custom AlgoOrderExecService implementations also get automatically recognized as long as they are declared in the same application context. The OrderService delegates handling of individual orders to their respective algo service based on the order type. It is important for classes implementing AlgoOrderExecService to correctly implement its #getAlgoOrderType method.

AlgoTrader is built on top of the Spring Framework, which uses BeanFactory and ApplicationContext to locate Spring Beans (= AlgoTrader-Services).

The Spring web site provides documentation such as 'The IoC container' as an introduction.

AlgoTrader provides the class ch.algotrader.ServiceLocator which will instantiate the adequate BeanFactories & ApplicationContexts for a given operational mode depending on the specified BEAN_REFERENCE_LOCATION.

In Simulation mode the AlgoTrader Server as well as the Strategy run inside the same JVM.

In Live-Trading mode the AlgoTrader Server and strategies can be run in different JVMs. Through the use of RmiServiceExporters and RmiProxyFactoryBean, Strategies can call Services from the AlgoTrader Server. Behind the scenes this is handled transparently through RMI.

Please see Remoting and web services using Spring for further details.

AlgoTrader provides the following Wiring Classes and Application Context XML-Files :


The following table shows which Wiring Classes and ApplicationContext is referenced by which Wiring Factory:


AlgoTrader provides a sophisticated event dispatching and messaging sub system. In Simulation Mode as well as Embedded Mode Event Propagation takes places within the JVM. In Distributed Live Trading Mode Event Propagation from the AlgoTrader Server to the strategies (and between strategies) happens via JMS & ActiveMQ

AlgoTrader employs STOMP messaging protocol over WebSockets transport to implement multi-topic, multi-client message delivery based on the Publish-Subscribe pattern. AlgoTrader acts as a message producer that generates messages representing various system or trading related events and publishes them to predefined topics. Browsers running the HTML5 UI client (and potentially any external application supporting STOMP over WebSockets) act as message consumers that subscribe to message topics of interest such as market data, orders, order status updates, position changes, executed transactions and so on. Consumers express their interest in a particular type of event by subscribing to message topics. Consumers should no longer need to filter out unwanted messages. They are expected to subscribe only to a subset of messages they are interested in.

For further details on the STOMP protocol please visit the STOMP website.

AlgoTrader publishes events to multiple event topics.


Topics are organized by name spaces. A consumer wishing to receive market data for security with id 12 only can subscribe to the following topic:

tick.12

A consumer wishing to receive market data all securities can subscribe to the following wild card topic.

tick.*

Strategy specific events are organized by strategy name. A consumer wishing to receive order status updates for the order with internal id 10 issued by strategy MY_STRATEGY can subscribe to the following topic

order-status.MY_STRATEGY.10

A consumer wishing to receive order status updates for all orders issued by strategy MY_STRATEGY can subscribe to the following wild card topic

order-status.MY_STRATEGY.*

The * wild card selects all elements within the same namespace

A consumer wishing to receive order status updates for all orders of all strategies can subscribe to the following wild card topic

order-status.>

The > wild card selects all topics within the same namespace and their sub-namespaces.

In order to ensure optimal performance of HTML5 clients AlgoTrader can throttle market data event delivered by the WebSockets transport. The embedded message broker by default attempts to ensure that the total rate of events per connection does not exceed 50 per second. At the same time instruments with infrequent market data updates are not throttled if their total event rate is below 0.1 per second (less that one event every 10 seconds).

Throttling rates can be adjusted by changing the following configuration parameters:

activeMQ.maxRatePerConnection = 50

activeMQ.minRatePerConsumer = 0.1

In JavaScript STOMP messages can be consumed like this:


<html>
<head>
    <script src="https://unpkg.com/@stomp/stompjs@4.0.6/lib/stomp.min.js"></script>
    <script type="text/javascript">
        var ws = new WebSocket("ws://localhost:61614", "stomp");
        var stompClient = Stomp.over(ws);
        stompClient.connect({}, function(frame) {
            stompClient.subscribe('/topic/tick.*', function(message){
                console.log(JSON.parse(message.body));
            });
        });
    </script>
</head>
</html>

For further details please visit the STOMP JavaScript documentation.

RESTful endpoints largely expose the same interface as Spring services exposed via RMI. REST controllers must follow RESTful semantic and also use immutable value objects for input / output representation.

AlgoTrader RESTful controllers serve several purposes:

The following RESTful controller provides a list of all accounts available in the system:

@CrossOrigin

@RequestMapping(path = "/account", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<AccountVO> getAccounts() {
    return lookupService.getAllAccounts().stream()
            .map(Account::convertToVO)
            .collect(Collectors.toList());
}

In this example the @CrossOrigin annotation marks endpoint as permitting cross origin requests. The @RequestMapping annotation defines various aspects of request / response mapping: path attribute defines path element of the request URI, method attribute defines the request method (such as GET, POST, PUT or DELETE), produces attribute defines expected media type of response body. The endpoint method implementation performs conversion of Account Entity objects to AccountVO objects, which are then serialized to JSON data stream by the framework.

For more detailed explanation of REST controllers and Web annotations please refer to Spring documentation.

AlgoTrader uses SWAGGER to document the individual REST endpoints, see:

AlgoTrader uses a consistent message format based on JSON for the event topics described above as well for RESTful endpoints. The use of JSON as a message format and WebSockets / HTTP as transports enables interoperability with a wide variety of modern development platforms and languages.

Using the JSON messages in combination with the AlgoTrader RESTful endpoints and WebSocket/STOMP topics any popular development language can be used to build trading strategies making use of the AlgoTrader platform, for example:

HTTP GET endpoints can easily be queried via the Browser. To retrieve a JSON formatted list of all accounts open to the following URL in the Browser:

http://localhost:9090/rest/account

In addition one case use Curl, a popular utility for execution of HTTP requests. The following example shows how to retrieve a JSON formatted list of all accounts by executing HTTP GET request:

$ curl -X GET http://localhost:9090/rest/account -i
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.3.6.v20151106)

[{"id":100,"name":"IB_NATIVE_TEST","active":true,"broker":"IB",...},
{"id":101,"name":"IB_FIX_TEST","active":false,"broker":"IB",...},
{"id":103,"name":"DC_TEST","active":false,"broker":"DC",...},
{"id":104,"name":"JPM_TEST","active":false,"broker":"JPM",...},
{"id":105,"name":"RT_TEST","active":false,"broker":"RT",...},
{"id":106,"name":"LMAX_TEST","active":true,"broker":"LMAX",...},
{"id":107,"name":"FXCM_TEST","active":false,"broker":"FXCM",...},
{"id":108,"name":"CNX_TEST","active":false,"broker":"CNX",...}]

Similarly one can request AlgoTrader to subscribe to market data for security with id 11 by executing HTTP PUT request:

$ curl -X PUT -H "content-type: application/json"
  http://localhost:9090/rest/subscription/marketdata/subscribe \
  -d "{\"strategyName\":\"SERVER\",\"securityId\":11,\"subscribe\":true}" -i
HTTP/1.1 200 OK
Content-Length: 0
Server: Jetty(9.3.6.v20151106)

EventListener represents a generic communication interface to receive events from multiple event producers both in-process and remote. EventListenerRegistry interface represents a registry of event listeners used internally by the AlgoTrader Server process as well as individual strategy processes. One can register listeners for arbitrary event classes, which enables strategies to generate custom events either through Esper statements or in Java code and consume them internally or propagate them to other strategy processes.

The AlgoTrader platform provides a number of event listeners for common event types such as market data events, order events, external session events, life-cycle events, and a few others. Components that implement those event interfaces which are declared in the Spring application context get automatically registered with the platform upon initialization..

Table 11.3. Standard event listener classes

  
BarEventListenerreceives BarVO events generated from tick events by individual strategies or fed from an external source
EntityCacheEventListenerreceives EntityCacheEvictionEventVO generated by the cache manager
FillEventListenerreceives FillVO events generated by trading interface adapters
GenericEventListenerreceives GenericEventVO events generated by strategies
GenericTickEventListenerreceives GenericTickVO events generated by market data interface adapters or fed from an external source
LifecycleEventListenerreceives LifecycleEventVO generated by the life-cycle manager
OrderCompletionEventListenerreceives OrderCompletionVO events generated by the Server Engine
OrderEventListenerreceives OrderVO events generated by the order service
OrderStatusEventListenerreceives OrderStatusVO events generated by trading interface adapters
PositionEventListenerreceives PositionNutationVO events generated by the transaction service
QueryCacheEventListenerreceives QueryCacheEvictionEventVO generated by the cache manager
QuoteEventListenerreceives QuoteVO events (BidVO or AskVO) generated by market data interface adapters or fed from an external source
SessionEventListenerreceives SessionEventVO generated by market data and trading interface adapters
TickEventListenerreceives TickVO events generated by market data interface adapters or fed from an external source
TradeEventListenerreceives TradeVO events generated by market data interface adapters or fed from an external source
TransactionEventListenerreceives TransactionVO events generated by the transaction service


Events are delivered to strategies via JMS. The following JMS Destinations are defined by the system

Since market data events and generic events are pushed into two topics that are available to all strategies, strategies have to select appropriate messages on their own. This is the job of the SubscriptionService. It will modify the selectors on MessageListenerContainer accordingly and invoke the corresponding methods on the (server-side) MarketDataService (e.g. to request market data for additional securities).

AlgoTrader also provides commonly used parameters in a form of plain Java beans referred to as Config beans. Common configuration are represented by CommonConfig. Core platform parameters are represented by CoreConfig. Instances of these classes are immutable and can be shared by multiple components and multiple threads of execution.

ConfigBeanFactory class can be used to create instances of Config beans based on configuration parameters using @ConfigName constructor parameter annotations. This factory is used to build standard CommonConfig and CoreConfig but it can also be used to build arbitrary Config beans for a trading strategy using the following convention

public final class StratConfig {


    private final String textParam;
    private final boolean boolParam;
    private final BigDecimal decimalParam;
    public StratConfig(
        @ConfigName(value = "my.text") final String textParam,
        @ConfigName(value = "my.bool") final boolean boolParam,
        @ConfigName(value = "my.decimal", optional = true) final BigDecimal decimalParam) {
        this.textParam = textParam;
        this.boolParam = boolParam;
        this.decimalParam = decimalParam;
    }
    public String getTextParam() {
        return textParam;
    }
    public boolean isBoolParam() {
        return boolParam;
    }
    public BigDecimal getDecimalParam() {
        return decimalParam;
    }
}

Each constructor parameter of a Config bean must be annotated with @ConfigName containing the parameter name. The config parameter type will be inferred from the constructor argument type. If a parameter is null able and might be undefined in the config property files it can be marked as optional.

Standard platform Config beans such as CommonConfig and CoreConfig are declared in the Spring application context and get automatically injected into all beans that require configuration. One can also add strategy specific Config beans using the following bean definition:


<bean id="stratConfig" class="ch.algotrader.config.spring.ConfigBeanFactoryBean">
    <constructor-arg index="0" ref="configLocator"/>
    <constructor-arg index="1" value="my.strategy.StratConfig"/>
</bean>

Standard as well as strategy specific Config beans can be conveniently accessed using Spring SPEL expressions to wire other beans in the same Spring application context.


<bean id="MyObject" class="...">
    <constructor-arg value="#{@stratConfig.requestUri}"/>
</bean>

In addition it is possible to reference individual beans (e.g. config beans) directly within Spring wired classes

private @Value("#{@configParams.accountId}") long accountId;

AlgoTrader uses Hibernate for accessing and persisting objects to the database.

In order to prevent having to access the database on every single request, Hibernate provides two types of caches:

Both First and Second Level Cache require a Hibernate Session. Creation of a Session is usually very quick (a few milliseconds). This mechanism is therefore fine for any request-response based system. However this approach is not feasible for a trading application. A trading application typically receives several thousand market data events per second. Ideally these market data events have to be matched to the latest data stored in the database (e.g. Security related information, current Positions, executed Trades, etc.). Opening a new Hibernate Session for every market data event, to synchronize related objects (like corresponding Security), is much too expensive!

For this purpose AlgoTrader introduces a Level-Zero Cache

AlgoTrader Level-Zero Cache is an additional Caching Level on top of Hibernate First and Second Level Cache which has the following features:

By using the Level-Zero Cache it is possible to work on fully up-to-date versions of Entities without introducing any latency penalties.

Access to the Level-Zero Cache is provided by the class ch.algotrader.cache.CacheManagerImpl which is exposed as a Spring Bean named cacheManager. The CacheManagerImpl provides these public methods to access the Level-Zero Cache:

Like Hibernate First and Second Level Cache the AlgoTrader Level-Zero Cache will first check if the requested object is available inside the Cache. If not, the object will be retrieved via the ch.algotrader.hibernate.GenericDao and stored in the Cache.

The class EntityCache is responsible for caching of Entities (handled by the EntityHandler) and Entity-Collections (handled by CollectionHandler). When adding a new Entity to the cache, the EntityHandler and CollectionHandler traverse the entire object graph of initialized Entities and Collections and store all of them in separate nodes of the internal Hash Map Cache. Java reflection is used for the object graph traversal (on new objects or object updates) .

The class QueryCache is responsible for caching of Hibernate Query Results. Query Results are cached in reference to all involved tables. So whenever one of those referenced tables is modified, the corresponding Query Cache Entry is removed (detached).

Through the class ch.algotrader.wiring.server.CacheWiring net.sf.ehcache.event.CacheEventListenerAdapter are registered with each Ehcache element. These are either EntityCacheEventListener for Entity caches or CollectionCacheEventListener for Collection Caches. These EventListeners emit CacheEvictionEvents via the AlgoTrader EventDispatcher to CacheManager of the Server and Strategies (running in remote JVMs) to get notified every time an Entity / Collection is updated or the UpdateTimestampsCache (related to the Hibernate StandardQueryCache) has been updated.

This is a special customized appender which allows to send log events to the UI. The log events are sent via JMS/STOMP and log levels and loggers are configurable. For example you could define a particular logger (e.g. some specific class) or use the Root logger configured for the desired log level, e.g. INFO or WARN. In order to have multiple loggers with multiple log levels, separate appenders must be created each with it's own filter. The sample configuration below will create two UI appenders - one with level WARN (and above), another with INFO. Loggers defined in "Loggers" section reference these appenders in such a way that INFO log entries from PortfolioServiceImpl as well as all the entries with level WARN and above will be sent to the UI

Log entries are wrapped inside JMS message and get propagated via WebSocket STOMP protocol to the UI. In order to consume the log message the client will have to be subscribed to specific JMS topic ("/topic/log-event."). See StompAPIUtils.js in the HTML client for the subscription logic example.


<Appenders>
    <LogEvent name="LogEventWARN">
        <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
    </LogEvent>
    <LogEvent name="LogEventINFO">
        <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
    </LogEvent>
</Appenders>
<Loggers>
    <Root level="debug">
        <AppenderRef ref="LogEventWARN"/>
    </Root>
    <Logger name="ch.algotrader.service.PortfolioServiceImpl">
        <AppenderRef ref="LogEventINFO" />
    </Logger>
<Loggers>