Because Investor has been implemented in Java and is available as jars from a Maven repository we can easily use the framework in all languages which are based on the the JVM.

Here is a quick demo using Jupyter Lab (using Beakerx) with:
– Scala
– Java
– Groovy
– Kotlin
– Clojure

Here is a screen shot of Jupyter Lab:

Scala

Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.

For our demo we just use a very simple example and implement it in the different JVM languages which are available in BeakerX

Here is the Scala example that I took from my Impact Analysis blog. We use this example as a base line:

%%scala
%classpath config resolver maven-public http://software.pschatzmann.ch/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT

import ch.pschatzmann.dates._
import ch.pschatzmann.stocks._
import ch.pschatzmann.stocks.data.universe._
import ch.pschatzmann.stocks.input._
import ch.pschatzmann.stocks.accounting._
import ch.pschatzmann.stocks.accounting.kpi._
import ch.pschatzmann.stocks.execution._
import ch.pschatzmann.stocks.execution.fees._
import ch.pschatzmann.stocks.parameters._
import ch.pschatzmann.stocks.strategy._
import ch.pschatzmann.stocks.strategy.optimization._

var account = new Account("Simulation","USD", 100000.00, Context.date("2015-01-01"), new PerTradeFees(10.0))
var df = new StockData(new StockID("AAPL", "NASDAQ"), new QuandlWIKIReader())
var strategy = new RSI2Strategy(df)
var trader = new PaperTrader(account)
var state = new Fitness(trader).getFitness(strategy, account.getDateRange())

"Return in USD: " + state.result().getValue(KPI.AbsoluteReturn)

Return in USD: 36996.0

Java

Java is the most popular general-purpose computer-programming language that is concurrent, class-based, object-oriented and specifically designed to have as few implementation dependencies as possible. It is intended to let application developers “write once, run anywhere” meaning that compiled Java code can run on all platforms that support Java without the need for recompilation.

This example is very similar to our scala one: The only differnece is that we use * instead of _ in the package definitions and that the varible definitions need to contain the data type (Class names):

%%java
%classpath config resolver maven-public http://software.pschatzmann.ch/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT

import ch.pschatzmann.dates.*;
import ch.pschatzmann.stocks.*;
import ch.pschatzmann.stocks.data.universe.*;
import ch.pschatzmann.stocks.input.*;
import ch.pschatzmann.stocks.accounting.*;
import ch.pschatzmann.stocks.accounting.kpi.*;
import ch.pschatzmann.stocks.execution.*;
import ch.pschatzmann.stocks.execution.fees.*;
import ch.pschatzmann.stocks.parameters.*;
import ch.pschatzmann.stocks.strategy.*;
import ch.pschatzmann.stocks.strategy.optimization.*;


IAccount account = new Account("Simulation","USD", 100000.00, Context.date("2015-01-01"), new PerTradeFees(10.0));
IStockData sd = new StockData(new StockID("AAPL", "NASDAQ"), new QuandlWIKIReader());
ITradingStrategy strategy = new RSI2Strategy(sd);
ITrader trader = new PaperTrader(account);
State state = new Fitness(trader).getFitness(strategy, account.getDateRange());

return "Return in USD: " + state.result().getValue(KPI.AbsoluteReturn);


Return in USD: 36996.0

Groovy

Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.

Our Groovy example is very simple as well: Like in Scala we do not need to indicate the type: we can just replace the var with a def.

%%groovy
%classpath config resolver maven-public http://software.pschatzmann.ch/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT

import ch.pschatzmann.dates.*
import ch.pschatzmann.stocks.*
import ch.pschatzmann.stocks.data.universe.*
import ch.pschatzmann.stocks.input.*
import ch.pschatzmann.stocks.accounting.*
import ch.pschatzmann.stocks.accounting.kpi.*
import ch.pschatzmann.stocks.execution.*
import ch.pschatzmann.stocks.execution.fees.*
import ch.pschatzmann.stocks.execution.price.*
import ch.pschatzmann.stocks.parameters.*
import ch.pschatzmann.stocks.strategy.*
import ch.pschatzmann.stocks.strategy.optimization.*

def account = new Account("Simulation","USD", 100000.00, Context.date("2015-01-01"), new PerTradeFees(10.0))
def sd = new StockData(new StockID("AAPL", "NASDAQ"), new QuandlWIKIReader())
def strategy = new RSI2Strategy(sd)
def trader = new PaperTrader(account)
def state = new Fitness(trader).getFitness(strategy, account.getDateRange())

"Return in USD: " + state.result().getValue(KPI.AbsoluteReturn)

Return in USD: 36996.0

Kotlin

Kotlin is a statically typed programming language for modern multiplatform applications 100% interoperable with Java and Android™

Our example is very similar as well: Like in Scala we do not need to indicate the type: we can just replace the var with a val and there is no new operator.

%%kotlin
%classpath config resolver maven-public http://software.pschatzmann.ch/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT

import ch.pschatzmann.dates.*
import ch.pschatzmann.stocks.*
import ch.pschatzmann.stocks.data.universe.*
import ch.pschatzmann.stocks.input.*
import ch.pschatzmann.stocks.accounting.*
import ch.pschatzmann.stocks.accounting.kpi.*
import ch.pschatzmann.stocks.execution.*
import ch.pschatzmann.stocks.execution.fees.*
import ch.pschatzmann.stocks.execution.price.*
import ch.pschatzmann.stocks.parameters.*
import ch.pschatzmann.stocks.strategy.*
import ch.pschatzmann.stocks.strategy.optimization.*

val account =  Account("Simulation","USD", 100000.00, Context.date("2015-01-01"),  PerTradeFees(10.0))
val sd = StockData(StockID("AAPL", "NASDAQ"), QuandlWIKIReader())
val strategy =  RSI2Strategy(sd)
val trader =  PaperTrader(account)
val state =  Fitness(trader).getFitness(strategy, account.getDateRange())

"Return in USD: " + state.result().getValue(KPI.AbsoluteReturn)


Return in USD: 36996.0

Clojure

Closure is a Lisp dialect and therefore it is very different from all the examples above.
All commands are in brackets: (). The imports of packages is done with (import (packageName Class1 Class2 …)) and
variable assignements are done with (let [variableName expression)].

In order to output the result we just concatenate the pieces as strings with (str expression1 epression2 …)

%%clojure 
%classpath config resolver maven-public http://software.pschatzmann.ch/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT

(import (ch.pschatzmann.stocks Context StockID StockData) 
    (ch.pschatzmann.stocks.accounting Account)
    (ch.pschatzmann.stocks.execution.fees PerTradeFees)
    (ch.pschatzmann.stocks.input QuandlWIKIReader)
    (ch.pschatzmann.stocks.strategy RSI2Strategy)
    (ch.pschatzmann.stocks.execution PaperTrader)
    (ch.pschatzmann.stocks.strategy.optimization Fitness)
    (ch.pschatzmann.stocks.accounting.kpi KPI))

(let [startDate (Context/date "2015-01-01")
    account (new Account "Simulation" "USD" 100000.00 startDate (new PerTradeFees 10.0))
    stockID (new StockID "AAPL" "NASDAQ")
    sd (new StockData stockID (new QuandlWIKIReader))
    strategy (new RSI2Strategy sd)
    trader  (new PaperTrader account)
    state (.getFitness (new Fitness trader) strategy (.getDateRange account))]

    (str "Return in USD: " (.getValue (.result state) (KPI/AbsoluteReturn))))

Return in USD: 36996.0

Outlook

I did not provide any examples in Python and Javascript because the stanrad implementations are not based on the JVM. However it should be possible to use Jython or Rhino or Nashorn e.g. with https://github.com/scijava/scijava-jupyter-kernel.


Leave a Reply

Your email address will not be published. Required fields are marked *