Forecasting

The longer you look back, the farther you can look forward. (Winston Churchill)

Forecastig of the development of stocks is quite a challangning task with uncertain outcome. We currently support the following approaches:
– Forecast based on History
– Arima

Setup

%classpath config resolver maven-public http://pschatzmann.ch:8081/repository/maven-public/
%classpath add mvn ch.pschatzmann:investor:0.9-SNAPSHOT
%classpath add mvn ch.pschatzmann:jupyter-jdk-extensions:0.0.1-SNAPSHOT

Added new repo: maven-public




Added jars: [websocket-common-9.2.20.v20161216.jar, commons-cli-1.3.1.jar, htmlunit-2.24.jar, qdox-1.5.jar, investor-0.9-SNAPSHOT.jar, httpclient-4.5.3.jar, hamcrest-core-1.1.jar, slf4j-api-1.7.25.jar, commons-codec-1.10.jar, jetty-io-9.2.20.v20161216.jar, timeseries-forecast-1.1.1.jar, commons-lang3-3.5.jar, jackson-databind-2.9.4.jar, commons-io-2.5.jar, htmlunit-core-js-2.23.jar, jackson-annotations-2.9.4.jar, jetty-util-9.2.20.v20161216.jar, YahooFinanceAPI-3.12.3.jar, sevenzipjbinding-all-platforms-9.20-2.00beta.jar, sevenzipjbinding-9.20-2.00beta.jar, sojo-1.0.5.jar, commons-jcs-core-2.0.jar, websocket-client-9.2.20.v20161216.jar, jfreechart-1.5.0.jar, ant-1.5.jar, combinatoradix-0.8.2.jar, cssparser-0.9.21.jar, jackson-core-2.9.4.jar, httpcore-4.4.6.jar, xercesImpl-2.11.0.jar, neko-htmlunit-2.24.jar, httpmime-4.5.2.jar, log4j-1.2.17.jar, sac-1.3.jar, ta4j-core-0.10.jar, websocket-api-9.2.20.v20161216.jar, jcl-over-slf4j-1.7.25.jar, xalan-2.7.2.jar, slf4j-log4j12-1.7.25.jar, junit-4.10.jar, commons-attributes-api-2.2.jar, xml-apis-1.4.01.jar, serializer-2.7.2.jar]




Added jars: [concurrent-1.3.4.jar, jcs-1.3.jar, avalon-framework-4.1.3.jar, commons-logging-1.1.jar, in-memory-stardb-0.0.1-SNAPSHOT.jar, logkit-1.0.1.jar, common-0.0.1-SNAPSHOT.jar, jupyter-jdk-extensions-0.0.1-SNAPSHOT.jar, servlet-api-2.3.jar]
// our stock evaluation framwork
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._;
import ch.pschatzmann.stocks.strategy.allocation._;
import ch.pschatzmann.stocks.strategy.selection._;
import ch.pschatzmann.stocks.integration._;
import ch.pschatzmann.stocks.forecasting._;
import ch.pschatzmann.stocks.integration.ChartData.FieldName._;
import ch.pschatzmann.stocks.strategy.OptimizedStrategy.Schedule._;


// java
import java.util.stream.Collectors;
import java.util._;
import java.lang._;
import java.util.function.Consumer;

// jupyter custom displayer
import ch.pschatzmann.display.Displayers
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._
import ch.pschatzmann.stocks.strategy.allocation._
import ch.pschatzmann.stocks.strategy.selection._
import ch.pschatzmann.stocks.integration._
import ch.pschatzmann.stocks.forecasting._
import ch.pschatzmann.stocks.integration.ChartData.FieldName._
import ch.pschatzmann.stocks.strategy.Optimized...
Displayers.setup("WARN")

Context.setCachingActive(false);
Context.isCachingActive();

false

Forecasting for AAPL

First we determine the history.

var aapl = new StockData(new StockID("AAPL", "NASDAQ"), new MarketArchiveHttpReader());

var history = aapl.getHistory(Context.date("1995-01-01"))
Displayers.display(Context.tail(history,10));
index date low high open closing adjustmentFactor volume
9345 2018-01-04 172.08 173.47 172.54 173.03 1 22434600
9346 2018-01-05 173.05 175.37 173.44 175 1 23660000
9347 2018-01-08 173.93 175.61 174.35 174.35 1 20567800
9348 2018-01-09 173.41 175.06 174.55 174.33 1 21584000
9349 2018-01-10 173 174.3 173.16 174.29 1 23959900
9350 2018-01-11 174.49 175.49 174.59 175.28 1 18667700
9351 2018-01-12 175.65 177.36 176.18 177.09 1 25418100
9352 2018-01-16 176.14 179.39 177.9 176.19 1 29565900
9353 2018-01-17 175.07 179.25 176.15 179.1 1 34386800
9354 2018-01-18 178.25 180.1 179.37 179.26 1 31035300
Displayers.display(new TimeSeriesChart().add(aapl).displayChart())

Simulation of Future using the Past

One possiblity is to simulate the future based on the development of the past: Looking at the chart we can e.g.
investigate how our strategy would behave if we would be in a simialr position like on March 2015.

We simulate the future develpment based on the development starting from
– 2012-09-01 of the AAPL stock
– 2015-03-01 of the AAPL stock
– 2017-03-01 of the NYSE Composite Index

var nya = new StockData(new StockID("^NYA", "INDEX"), new MarketArchiveHttpReader());

var aapl = new StockData(new StockID("AAPL", "NASDAQ"), new MarketArchiveHttpReader());
var aaplWithFuture1 = new ForecasterFromSimulationOnHistory(Context.date("2012-09-01")).forecast(aapl, 200)
var aaplWithFuture2 = new ForecasterFromSimulationOnHistory(Context.date("2015-03-01")).forecast(aapl, 200)
var aaplWithFuture3 = new ForecasterFromSimulationOnHistory(Context.date("2017-03-01"),nya).forecast(aapl, 200)

// display chart
var chart = new TimeSeriesChart()
var startDisplayDate = Context.date("2012-01-01")
chart.add(aaplWithFuture1.getHistory(startDisplayDate),"1)2012-09-01")
chart.add(aaplWithFuture2.getHistory(startDisplayDate),"2)2015-03-01")
chart.add(aaplWithFuture3.getHistory(startDisplayDate),"3)2017-03-01 nya")

Displayers.display(chart.displayChart())

Result for Worst Case Option 1

var dates = Context.getDateRanges("2018-01-01","2019-01-01");

var account1 = new Account("Simulation","USD", 100000.00, dates.get(0).getStart(), new PerTradeFees(10.0));
var aapl = new StockData(new StockID("AAPL", "NASDAQ"), new MarketArchiveHttpReader());
var aaplWithFuture1 = new ForecasterFromSimulationOnHistory(Context.date("2012-09-01")).forecast(aapl, 200)
var strategy1 = new RSI2Strategy(aaplWithFuture1);
var trader1 = new PaperTrader(account1);
var state = new Fitness(trader1).getFitness(strategy1, dates.get(0));

state.result()
ReturnPercent:-14; NumberOfCashTransfers:1; TotalFees:20; MaxDrawDownPercent:26331; MaxDrawDownNumberOfDays:189; SharpeRatio:-1; NumberOfTradedStocks:1; MaxDrawDownHighValue:106269; Cash:86022; ReturnPercentAnualized:-16; NumberOfBuys:1; AbsoluteReturn:-13978; ActualValue:86022; ReturnPurcentStdDev:0; PurchasedValue:86022; AbsoluteReturnAvaragePerDay:-65; AbsoluteReturnStdDev:884; NumberOfTrades:2; UnrealizedGains:0; NumberOfSells:1; RealizedGains:-13958; MaxDrawDownLowValue:79938; 
Displayers.display(account1.getTransactions().collect(Collectors.toList()));

active stockID date quantity requestedPrice filledPrice fees comment id buyOrSell requestedPriceType impactOnCash
true
Key Value
ticker Cash
exchange Account
2018-01-01 0 0 0 0 69617c78-c2b2-4845-8752-caed9c8d147e NA CashTransfer 100000
true
Key Value
ticker AAPL
exchange NASDAQ
2018-01-29 564 0 177.1629 10 d0e2e074-f212-4d2b-b851-55713526d637 Buy Market -99929.898
true
Key Value
ticker AAPL
exchange NASDAQ
2018-04-05 -564 0 152.4155 10 f6bf2e77-b143-42e6-9918-4f48bd56229a Sell Market 85952.3228

Result for Option 2

var dates = Context.getDateRanges("2018-01-01","2019-01-01");

var account2 = new Account("Simulation","USD", 100000.00, dates.get(0).getStart(), new PerTradeFees(10.0));
var aapl = new StockData(new StockID("AAPL", "NASDAQ"), new MarketArchiveHttpReader());
var aaplWithFuture2 = new ForecasterFromSimulationOnHistory(Context.date("2015-03-01")).forecast(aapl, 200)
var strategy2 = new RSI2Strategy(aaplWithFuture2);
var trader2 = new PaperTrader(account2);
var state2 = new Fitness(trader2).getFitness(strategy2, dates.get(0));

state2.result()
ReturnPercent:-7; NumberOfCashTransfers:1; TotalFees:20; MaxDrawDownPercent:14709; MaxDrawDownNumberOfDays:142; SharpeRatio:0; NumberOfTradedStocks:1; MaxDrawDownHighValue:105272; Cash:95; ReturnPercentAnualized:-8; NumberOfBuys:1; AbsoluteReturn:-6522; ActualValue:101610; ReturnPurcentStdDev:0; PurchasedValue:99990; AbsoluteReturnAvaragePerDay:-30; AbsoluteReturnStdDev:1023; NumberOfTrades:2; UnrealizedGains:1620; NumberOfSells:1; RealizedGains:0; MaxDrawDownLowValue:90562; 
Displayers.display(account2.getTransactions().collect(Collectors.toList()));

active stockID date quantity requestedPrice filledPrice fees comment id buyOrSell requestedPriceType impactOnCash
true
Key Value
ticker Cash
exchange Account
2018-01-01 0 0 0 0 91e8a043-174d-43e8-b172-0d70a8613ae7 NA CashTransfer 100000
true
Key Value
ticker AAPL
exchange NASDAQ
2018-01-25 569 0 175.5629 10 376a9292-d4d4-4ac5-be5f-12994520da3e Buy Market -99905.2801
true
Key Value
ticker AAPL
exchange NASDAQ
2018-07-09 -569 0 164.1354 10 bb10b925-f330-4105-bdca-82df18e86465 Sell Market 93383.0537

Result for Best Case – Option 3

var dates = Context.getDateRanges("2018-01-01","2019-01-01");

var account3 = new Account("Simulation","USD", 100000.00, dates.get(0).getStart(), new PerTradeFees(10.0));
var aapl = new StockData(new StockID("AAPL", "NASDAQ"), new MarketArchiveHttpReader());
var aaplWithFuture3 = new ForecasterFromSimulationOnHistory(Context.date("2017-03-01"),nya).forecast(aapl, 200)
var strategy3 = new RSI2Strategy(aaplWithFuture3);
var trader3 = new PaperTrader(account3);
var state3 = new Fitness(trader3).getFitness(strategy3, dates.get(0));

state3.result()
ReturnPercent:-13; NumberOfCashTransfers:1; TotalFees:20; MaxDrawDownPercent:18979; MaxDrawDownNumberOfDays:193; SharpeRatio:-2; NumberOfTradedStocks:1; MaxDrawDownHighValue:102109; Cash:87017; ReturnPercentAnualized:-15; NumberOfBuys:1; AbsoluteReturn:-12983; ActualValue:87017; ReturnPurcentStdDev:0; PurchasedValue:87017; AbsoluteReturnAvaragePerDay:-61; AbsoluteReturnStdDev:533; NumberOfTrades:2; UnrealizedGains:0; NumberOfSells:1; RealizedGains:-12963; MaxDrawDownLowValue:83129; 
Displayers.display(account3.getTransactions().collect(Collectors.toList()));

active stockID date quantity requestedPrice filledPrice fees comment id buyOrSell requestedPriceType impactOnCash
true
Key Value
ticker Cash
exchange Account
2018-01-01 0 0 0 0 b0d54243-5a94-4f4a-9101-cd248ccafc1b NA CashTransfer 100000
true
Key Value
ticker AAPL
exchange NASDAQ
2018-01-29 558 0 179.1682 10 8d5d9d4e-ca04-4995-8466-8f581146cbe0 Buy Market -99985.8511
true
Key Value
ticker AAPL
exchange NASDAQ
2018-03-28 -558 0 155.9368 10 ff119376-82bc-419b-a5a6-d2b8b228638e Sell Market 87002.7313

Arima

import ch.pschatzmann.stocks.forecasting._
import com.workday.insights.timeseries.arima.struct.ArimaParams

var aapl = new StockData(new StockID("^NYA", "INDEX"), new MarketArchiveHttpReader());
var params = new ArimaParams(1, 0, 0, 0, 0, 0, 0);
var arima = new ForecasterARIMA(params)
var aaplArima = arima.forecast(aapl, 800)

// display chart
var chart = new TimeSeriesChart()
chart.add(aaplArima.getHistory(Context.date("2016-01-01")),"AAPL")

chart

var result = arima.getClose()
println(result.getRMSE())
println(result.getMaxNormalizedVariance)
result.getLog()
2916.0361215978332
1097.4211097962977





{"Best ModelInterface Param" : "ModelInterface ParamsInterface:, p= 1, d= 0, q= 0, P= 0, D= 0, Q= 0, m= 0","Forecast Size" : "800","Input Size" : "13102"}
var result = arima.getOpen()
println(result.getRMSE())
println(result.getMaxNormalizedVariance)
result.getLog()
2915.742853883635
969.6583958825637





{"Best ModelInterface Param" : "ModelInterface ParamsInterface:, p= 1, d= 0, q= 0, P= 0, D= 0, Q= 0, m= 0","Forecast Size" : "800","Input Size" : "13102"}

Leave a Reply

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