ojAlgo v47.1.1, ojAlgo-finance v2.1 & Financial Time Series Data
ojAlgo v47.1.1
- Primarily this release has improvements to the optimisation code:
- Extensive work on tuning the solvers (primarily the ConvexSolver)
- Major refactoring of test cases (mainly for LinearSolver and IntegerSolver).
- The presolve functionality has been improved, affecting all solvers.
- MPS file parser improved to handle more cases
- A couple of bugs fixed…
- Refactoring/restructuring of the org.ojalgo.function (sub)packages. You will most likely need to update some import statements.
- Fixed a couple of minor bugs related to eigenvalue decompositions.
- New functionality that enable data “transformations” via functional interfaces.
Check the ojAlgo change-log for a more complete list of what’s new!
ojAlgo-finance v2.1.0
- Adjustments for ojAlgo v47.1
- Improvements to code that fetches historical data from Yahoo, IEX Trading or Alpha Vantage. It is now very easy to fetch data from different sources and have it automatically coordinated – same start and end dates, same frequency – so that computing things like covariance matrices becomes straight forward.
Example Code – Historical Financial Data
FinancialData.javaimport java.time.LocalDate;
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.data.domain.finance.series.DataSource;
import org.ojalgo.data.domain.finance.series.YahooSession;
import org.ojalgo.netio.BasicLogger;
import org.ojalgo.random.SampleSet;
import org.ojalgo.random.process.GeometricBrownianMotion;
import org.ojalgo.random.process.RandomProcess.SimulationResults;
import org.ojalgo.series.BasicSeries;
import org.ojalgo.series.primitive.CoordinatedSet;
import org.ojalgo.series.primitive.PrimitiveSeries;
import org.ojalgo.type.CalendarDateUnit;
import org.ojalgo.type.PrimitiveNumber;
/**
* An example demonstrating how to download historical financial time series data, and how you can continue
* working with it.
*
* @see https://www.ojalgo.org/2019/04/ojalgo-v47-1-ojalgo-finance-v2-1-financial-time-series-data/
* @see https://github.com/optimatika/ojAlgo/wiki/Financial-Data
*/
public abstract class FinancialData {
public static void main(final String[] args) {
BasicLogger.debug();
BasicLogger.debug(FinancialData.class);
BasicLogger.debug(OjAlgoUtils.getTitle());
BasicLogger.debug(OjAlgoUtils.getDate());
BasicLogger.debug();
// First create the data sources
DataSource sourceMSFT = DataSource.newAlphaVantage("MSFT", CalendarDateUnit.DAY, "demo");
// Different Yahoo data sources should share a common session
YahooSession yahooSession = new YahooSession();
DataSource sourceAAPL = DataSource.newYahoo(yahooSession, "AAPL", CalendarDateUnit.DAY);
DataSource sourceIBM = DataSource.newYahoo(yahooSession, "IBM", CalendarDateUnit.DAY);
DataSource sourceORCL = DataSource.newYahoo(yahooSession, "ORCL", CalendarDateUnit.DAY);
// Fetch the data
BasicSeries<LocalDate, PrimitiveNumber> seriesIBM = sourceIBM.getLocalDateSeries(CalendarDateUnit.MONTH);
BasicSeries<LocalDate, PrimitiveNumber> seriesORCL = sourceORCL.getLocalDateSeries(CalendarDateUnit.MONTH);
BasicSeries<LocalDate, PrimitiveNumber> seriesMSFT = sourceMSFT.getLocalDateSeries(CalendarDateUnit.MONTH);
BasicSeries<LocalDate, PrimitiveNumber> seriesAAPL = sourceAAPL.getLocalDateSeries(CalendarDateUnit.MONTH);
BasicLogger.debug("Range for {} is from {} to {}", seriesMSFT.getName(), seriesMSFT.firstKey(), seriesMSFT.lastKey());
BasicLogger.debug("Range for {} is from {} to {}", seriesAAPL.getName(), seriesAAPL.firstKey(), seriesAAPL.lastKey());
BasicLogger.debug("Range for {} is from {} to {}", seriesIBM.getName(), seriesIBM.firstKey(), seriesIBM.lastKey());
BasicLogger.debug("Range for {} is from {} to {}", seriesORCL.getName(), seriesORCL.firstKey(), seriesORCL.lastKey());
// Coordinate the series - common start, end and frequency
CoordinatedSet<LocalDate> coordinationSet = CoordinatedSet.from(seriesMSFT, seriesAAPL, seriesIBM, seriesORCL);
BasicLogger.debug();
BasicLogger.debug("Common range is from {} to {}", coordinationSet.getFirstKey(), coordinationSet.getLastKey());
PrimitiveSeries primitiveMSFT = coordinationSet.getSeries(0);
PrimitiveSeries primitiveAAPL = coordinationSet.getSeries(1);
PrimitiveSeries primitiveIBM = coordinationSet.getSeries(2);
PrimitiveSeries primitiveORCL = coordinationSet.getSeries(3);
// Create sample sets of log differences
SampleSet sampleSetMSFT = SampleSet.wrap(primitiveMSFT.log().differences());
SampleSet sampleSetIBM = SampleSet.wrap(primitiveIBM.log().differences());
BasicLogger.debug();
BasicLogger.debug("Sample statistics (logarithmic differences on monthly data)");
BasicLogger.debug("MSFT: {}", sampleSetMSFT);
BasicLogger.debug("IBM: {}", sampleSetIBM);
BasicLogger.debug("Correlation: {}", sampleSetIBM.getCorrelation(sampleSetMSFT));
// Estimate stochastic process parameters based on historical data
GeometricBrownianMotion monthlyProcAAPL = GeometricBrownianMotion.estimate(primitiveAAPL, 1.0);
GeometricBrownianMotion monthlyProcORCL = GeometricBrownianMotion.estimate(primitiveORCL, 1.0);
monthlyProcAAPL.setValue(1.0); // To normalize the current value
monthlyProcORCL.setValue(1.0);
double yearsPerMonth = CalendarDateUnit.YEAR.convert(CalendarDateUnit.MONTH);
// The same thing, but annualised
GeometricBrownianMotion annualProcAAPL = GeometricBrownianMotion.estimate(primitiveAAPL, yearsPerMonth);
GeometricBrownianMotion annualProcORCL = GeometricBrownianMotion.estimate(primitiveORCL, yearsPerMonth);
annualProcAAPL.setValue(1.0); // To normalize the current value
annualProcORCL.setValue(1.0);
// Comparing the monthly and annual stochastic processes for AAPL
BasicLogger.debug();
BasicLogger.debug(" Apple Monthly proc Annual proc (6 months from now)");
BasicLogger.debug("Expected: {} {}", monthlyProcAAPL.getDistribution(6.0).getExpected(), annualProcAAPL.getDistribution(0.5).getExpected());
BasicLogger.debug("StdDev: {} {}", monthlyProcAAPL.getDistribution(6.0).getStandardDeviation(),
annualProcAAPL.getDistribution(0.5).getStandardDeviation());
BasicLogger.debug("Var: {} {}", monthlyProcAAPL.getDistribution(6.0).getVariance(), annualProcAAPL.getDistribution(0.5).getVariance());
// Comparing the annualized stochastic processes for AAPL and ORCL
BasicLogger.debug();
BasicLogger.debug(" Apple Oracle (1 year from now)");
BasicLogger.debug("Current: {} {}", annualProcAAPL.getValue(), annualProcORCL.getValue());
// getExpected() is a shortcut to getDistribution(1.0).getExpected()
BasicLogger.debug("Expected: {} {}", annualProcAAPL.getExpected(), annualProcORCL.getExpected());
// getStandardDeviation() is a shortcut to getDistribution(1.0).getStandardDeviation()
BasicLogger.debug("StdDev: {} {}", annualProcAAPL.getStandardDeviation(), annualProcORCL.getStandardDeviation());
// getVariance() is a shortcut to getDistribution(1.0).getVariance()
BasicLogger.debug("Var: {} {}", annualProcAAPL.getVariance(), annualProcORCL.getVariance());
// Simulate future scenarios for ORCL
SimulationResults simulationResults = annualProcORCL.simulate(1000, 12, yearsPerMonth);
BasicLogger.debug();
BasicLogger.debug("Simulate future Oracle: 1000 scenarios, take 12 incremental steps of size 'yearsPerMonth' (1/12)");
// There are 12 sample sets indexed 0 to 11
BasicLogger.debug("Simulated sample set: {}", simulationResults.getSampleSet(11));
// There are 1000 scenarios indexed 0 to 999
BasicLogger.debug("Simulated scenario: {}", simulationResults.getScenario(999));
// There is a shortcut to get a coordinated set
DataSource.Coordinated coordinated = DataSource.coordinated(CalendarDateUnit.DAY);
coordinated.addAlphaVantage("MSFT", "demo");
coordinated.addYahoo("AAPL");
coordinated.addYahoo("IBM");
coordinated.addYahoo("ORCL");
CoordinatedSet<LocalDate> coordinationSet2 = coordinated.get();
}
}
Console Output
class FinancialData
ojAlgo
2019-04-11
Range for MSFT is from 2018-11-30 to 2019-04-30
Range for AAPL is from 2014-04-30 to 2019-04-30
Range for IBM is from 1989-04-30 to 2019-04-30
Range for ORCL is from 1989-04-30 to 2019-04-30
Common range is from 2018-11-30 to 2019-04-30
Sample statistics (logarithmic differences on monthly data)
MSFT: Sample set Size=5, Mean=0.016963754617290227, Var=0.003898700343476474, StdDev=0.0624395735369523, Min=-0.08779088268545898, Max=0.0745334981716903
IBM: Sample set Size=5, Mean=0.030422355449287154, Var=0.008393992685262789, StdDev=0.09161873544893964, Min=-0.08915711966527695, Max=0.16766968378644798
Correlation: 0.6181368931750267
Apple Monthly proc Annual proc (6 months from now)
Expected: 1.1810740629349612 1.1810740629349612
StdDev: 0.24837454053493682 0.24837454053493682
Var: 0.06168991238594097 0.06168991238594097
Apple Oracle (1 year from now)
Current: 1.0 1.0
Expected: 1.3949359421376966 1.337730471536396
StdDev: 0.4194193574444725 0.31584482401600694
Var: 0.17591259739913417 0.09975795285770238
Simulate future Oracle: 1000 scenarios, take 12 incremental steps of size 'yearsPerMonth' (1/12)
Simulated sample set: Sample set Size=1000, Mean=1.3368173052144632, Var=0.09925845188383686, StdDev=0.3150530937537939, Min=0.504248921172877, Max=3.6405224252854183
Simulated scenario: { 1.0, 0.987953283856134, 0.9803778218751452, 1.0275292151500863, 0.9806568759600218, 1.0407422677990135, 1.2023135797767084, 1.2971232117765163, 1.308873281212413, 1.3496369871350853, 1.3994778062888376, 1.3165433881275048, 1.3702583762345444 }
- ← Previous
StatQuest PCA Example - Next →
AdoptOpenJDK v12