requirements, default parameters, new Test for varianceRatioTest

This commit is contained in:
mrFendel 2023-04-19 01:36:54 +03:00
parent 98781c83ad
commit 0193349f94
3 changed files with 19 additions and 16 deletions

View File

@ -19,9 +19,9 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC
import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.FloatField

View File

@ -9,11 +9,10 @@ import space.kscience.kmath.operations.DoubleField.pow
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.fold
import space.kscience.kmath.structures.slice
// TODO: add p-value with formula: 2*(1 - cdf(|zScore|))
public data class VarianceRatioTestResult(val varianceRatio: Double, val zScore: Double)
public data class VarianceRatioTestResult(val varianceRatio: Double=1.0, val zScore: Double=0.0)
/**
* Container class for Variance Ratio Test result:
* ratio itself, corresponding Z-score, also it's p-value
@ -27,12 +26,15 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
* https://ssrn.com/abstract=346975
* **/
require(shift > 1) {"Shift must be greater than one"}
require(shift < series.size) {"Shift must be smaller than sample size"}
val sum = { x: Double, y: Double -> x + y }
//TODO: catch if shift is too large
with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val mean = series.fold(0.0, sum) / series.size
val demeanedSquares = series.map { power(it - mean, 2) }
val variance = demeanedSquares.fold(0.0, sum) // TODO: catch if variance is zero
val variance = demeanedSquares.fold(0.0, sum)
if (variance == 0.0) return VarianceRatioTestResult()
var seriesAgg = series
@ -53,7 +55,7 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
} else { // under heteroscedastic null hypothesis
var accumulator = 0.0
for (j in 1..<shift) {
var temp = demeanedSquares
val temp = demeanedSquares
val delta = series.size * temp.zipWithShift(j) { v1, v2 -> v1 * v2 }.fold(0.0, sum) / variance.pow(2)
accumulator += delta * 4 * (shift - j).toDouble().pow(2) / shift.toDouble().pow(2)
}

View File

@ -31,7 +31,7 @@ class TestVarianceRatioTest {
fun volatileData() {
with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val volatileData = series(10) { sin(PI * it + PI/2) + 1.0}
val resultHomo = varianceRatioTest(volatileData, 2, homoscedastic = true)
val resultHomo = varianceRatioTest(volatileData, 2)
assertEquals(0.0, resultHomo.varianceRatio, 1e-6)
// homoscedastic zScore
assertEquals(-3.162277, resultHomo.zScore, 1e-6)
@ -45,7 +45,7 @@ class TestVarianceRatioTest {
fun negativeData() {
with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val negativeData = series(10) { sin(it * 1.2)}
val resultHomo = varianceRatioTest(negativeData, 3, homoscedastic = true)
val resultHomo = varianceRatioTest(negativeData, 3)
assertEquals(1.240031, resultHomo.varianceRatio, 1e-6)
// homoscedastic zScore
assertEquals(0.509183, resultHomo.zScore, 1e-6)
@ -55,12 +55,13 @@ class TestVarianceRatioTest {
}
}
//TODO: add zero volatility Test, logReturns test, big shift Test
// @Test
// fun zeroVolatility() {
// with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
// val zeroVolData = series(10) { 1.0 }
// val result = varianceRatioTest(zeroVolData, 2, homoscedastic = true)
// }
// }
@Test
fun zeroVolatility() {
with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val zeroVolData = series(10) { 0.0 }
val result = varianceRatioTest(zeroVolData, 4)
assertEquals(1.0, result.varianceRatio, 1e-6)
assertEquals(0.0, result.zScore, 1e-6)
}
}
}