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.DecompositionFactory_FSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.FloatField 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.algebra
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.fold import space.kscience.kmath.operations.fold
import space.kscience.kmath.structures.slice
// TODO: add p-value with formula: 2*(1 - cdf(|zScore|)) // 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: * Container class for Variance Ratio Test result:
* ratio itself, corresponding Z-score, also it's p-value * 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 * 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 } val sum = { x: Double, y: Double -> x + y }
//TODO: catch if shift is too large
with(Double.algebra.bufferAlgebra.seriesAlgebra()) { with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val mean = series.fold(0.0, sum) / series.size val mean = series.fold(0.0, sum) / series.size
val demeanedSquares = series.map { power(it - mean, 2) } 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 var seriesAgg = series
@ -53,7 +55,7 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
} else { // under heteroscedastic null hypothesis } else { // under heteroscedastic null hypothesis
var accumulator = 0.0 var accumulator = 0.0
for (j in 1..<shift) { 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) 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) accumulator += delta * 4 * (shift - j).toDouble().pow(2) / shift.toDouble().pow(2)
} }

View File

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