import 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(); } }