MarketAnalysisRequest.java
package com.morphiqlabs.wavelet.cwt.finance;
import java.util.Optional;
/**
* Parameter object for comprehensive market analysis requests.
*
* <p>This record encapsulates all parameters needed for market analysis,
* replacing methods with many parameters and providing a fluent API.</p>
*
* @param priceData price time series
* @param volumeData optional volume time series
* @param samplingRate samples per unit time (e.g., Hz)
* @param options analysis options
*/
public record MarketAnalysisRequest(
double[] priceData,
double[] volumeData,
double samplingRate,
AnalysisOptions options
) {
/**
* Analysis options with sensible defaults.
*
* @param detectCrashes enable crash detection
* @param analyzeVolatility enable volatility analysis
* @param findCycles enable cycle detection
* @param generateSignals enable trading signal generation
* @param crashThreshold asymmetry threshold for crash detection
* @param volatilityWindow volatility window length (samples)
* @param maxCycles maximum cycles to analyze
* @param signalConfidence minimum confidence for signals
*/
public record AnalysisOptions(
boolean detectCrashes,
boolean analyzeVolatility,
boolean findCycles,
boolean generateSignals,
double crashThreshold,
double volatilityWindow,
int maxCycles,
double signalConfidence
) {
/**
* Creates options with default values.
*/
public static AnalysisOptions defaults() {
return new AnalysisOptions(
true, // detectCrashes
true, // analyzeVolatility
true, // findCycles
true, // generateSignals
10.0, // crashThreshold (default asymmetry threshold)
30.0, // volatilityWindow (days)
5, // maxCycles
0.8 // signalConfidence
);
}
/**
* Builder for custom analysis options.
*/
public static class Builder {
private boolean detectCrashes = true;
private boolean analyzeVolatility = true;
private boolean findCycles = true;
private boolean generateSignals = true;
private double crashThreshold = 10.0;
private double volatilityWindow = 30.0;
private int maxCycles = 5;
private double signalConfidence = 0.8;
public Builder detectCrashes(boolean detect) {
this.detectCrashes = detect;
return this;
}
public Builder analyzeVolatility(boolean analyze) {
this.analyzeVolatility = analyze;
return this;
}
public Builder findCycles(boolean find) {
this.findCycles = find;
return this;
}
public Builder generateSignals(boolean generate) {
this.generateSignals = generate;
return this;
}
public Builder crashThreshold(double threshold) {
this.crashThreshold = threshold;
return this;
}
public Builder volatilityWindow(double window) {
this.volatilityWindow = window;
return this;
}
public Builder maxCycles(int max) {
this.maxCycles = max;
return this;
}
public Builder signalConfidence(double confidence) {
this.signalConfidence = confidence;
return this;
}
public AnalysisOptions build() {
return new AnalysisOptions(
detectCrashes, analyzeVolatility, findCycles, generateSignals,
crashThreshold, volatilityWindow, maxCycles, signalConfidence
);
}
}
public static Builder builder() {
return new Builder();
}
}
/**
* Creates a market analysis request with default options.
*/
public static MarketAnalysisRequest of(double[] priceData, double samplingRate) {
return new MarketAnalysisRequest(
priceData,
null,
samplingRate,
AnalysisOptions.defaults()
);
}
/**
* Creates a market analysis request with price and volume data.
*/
public static MarketAnalysisRequest of(double[] priceData, double[] volumeData, double samplingRate) {
return new MarketAnalysisRequest(
priceData,
volumeData,
samplingRate,
AnalysisOptions.defaults()
);
}
/**
* Builder for creating custom analysis requests.
*/
public static class Builder {
private double[] priceData;
private double[] volumeData;
private double samplingRate = 1.0; // Default daily sampling
private AnalysisOptions options = AnalysisOptions.defaults();
public Builder priceData(double[] data) {
this.priceData = data;
return this;
}
public Builder volumeData(double[] data) {
this.volumeData = data;
return this;
}
public Builder samplingRate(double rate) {
this.samplingRate = rate;
return this;
}
public Builder options(AnalysisOptions opts) {
this.options = opts;
return this;
}
public Builder configureOptions(java.util.function.Consumer<AnalysisOptions.Builder> configurator) {
var builder = AnalysisOptions.builder();
configurator.accept(builder);
this.options = builder.build();
return this;
}
public MarketAnalysisRequest build() {
if (priceData == null || priceData.length == 0) {
throw new IllegalStateException("Price data is required");
}
if (samplingRate <= 0) {
throw new IllegalStateException("Sampling rate must be positive");
}
return new MarketAnalysisRequest(priceData, volumeData, samplingRate, options);
}
}
public static Builder builder() {
return new Builder();
}
/**
* Convenience methods for checking options.
*/
public boolean hasVolumeData() {
return volumeData != null && volumeData.length > 0;
}
public Optional<double[]> getVolumeData() {
return Optional.ofNullable(volumeData);
}
}