Skip to content

Commit

Permalink
Added resolution to sampling to avoid duplicate draws
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaron committed Dec 26, 2023
1 parent 7c22009 commit 8dacef1
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ class TimeSeriesChart(
val xAxis = if (useTime) TimeAxis() else ValueAxis()
val yAxis = ValueAxis().setScale(true)

val tooltip = if (data.size > 5) "item" else "axis"
// Deal with many series on a single chart
val showSymbol = data.size > 5
val tooltip = if (showSymbol) "item" else "axis"

val chart = Line()
.setTitle(title)
.addXAxis(xAxis)
Expand All @@ -118,7 +121,7 @@ class TimeSeriesChart(
val d = reduce(entries.toSeriesData())
val lineSeries = LineSeries()
.setData(d)
.setShowSymbol(false)
.setShowSymbol(showSymbol)
.setName(name.removeSuffix(suffix))
.setLineStyle(LineStyle().setWidth(1))

Expand Down
2 changes: 1 addition & 1 deletion roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class TimeSpan internal constructor(internal val period: Period, internal val du
override fun hashCode(): Int {
return period.hashCode() + duration.hashCode()
}

}

/*********************************************************************************************
Expand Down
13 changes: 10 additions & 3 deletions roboquant/src/main/kotlin/org/roboquant/common/Timeframe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.io.Serializable
import java.time.*
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.time.temporal.TemporalUnit
import kotlin.math.pow
import kotlin.random.Random

Expand Down Expand Up @@ -319,19 +320,25 @@ data class Timeframe(val start: Instant, val end: Instant, val inclusive: Boolea

/**
* Sample one or more timeframes each of a [period] length. Common use case is a Monte Carlo simulation. It uses
* millisecond resolution for the start of timeframes.
* [resolution] for the start of timeframes, default being [ChronoUnit.DAYS].
* The minimum resolution is milliseconds.
*
* The returned list will not contain duplicate timeframes (sampling without replacement).
*/
fun sample(period: TimeSpan, samples: Int = 1, random: Random = Config.random): List<Timeframe> {
fun sample(
period: TimeSpan,
samples: Int = 1,
resolution: TemporalUnit = ChronoUnit.DAYS,
random: Random = Config.random,
): List<Timeframe> {
require(samples >= 1) { "samples need to be >= 1" }
require(end - period > start) { "period=$period to large for timeframe=$this" }
val duration = Timeframe(start, end - period).duration.toMillis()
require(duration > samples) { "not enough data to sample $samples" }
val result = mutableSetOf<Timeframe>()
while (result.size < samples) {
val offset = random.nextLong(duration)
val newStart = start.plusMillis(offset)
val newStart = start.plusMillis(offset).truncatedTo(resolution)
result.add(Timeframe(newStart, newStart + period))
}
return result.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

package org.roboquant.common

import kotlin.test.Test
import org.junit.jupiter.api.assertThrows
import java.time.Duration
import java.time.Instant
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import kotlin.math.absoluteValue
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
Expand Down Expand Up @@ -93,7 +94,7 @@ internal class TimeframeTest {
tf.sample(10.millis, 1200)
}

val tfs = tf.sample(10.millis, 700)
val tfs = tf.sample(10.millis, 700, resolution = ChronoUnit.MILLIS)
assertEquals(700, tfs.size)
assertEquals(700, tfs.toSet().size)
}
Expand Down
5 changes: 3 additions & 2 deletions roboquant/src/test/kotlin/org/roboquant/feeds/LiveFeedTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
package org.roboquant.feeds

import kotlinx.coroutines.*
import kotlin.test.Test
import org.junit.jupiter.api.assertDoesNotThrow
import org.roboquant.Roboquant
import org.roboquant.common.*
import org.roboquant.loggers.LastEntryLogger
import org.roboquant.metrics.ProgressMetric
import org.roboquant.strategies.EMAStrategy
import java.time.Instant
import java.time.temporal.ChronoUnit
import kotlin.test.Test
import kotlin.test.assertTrue

internal class LiveFeedTest {
Expand Down Expand Up @@ -87,7 +88,7 @@ internal class LiveFeedTest {
val jobs = ParallelJobs()

var run = 0
tf.sample(200.millis, 10).forEach {
tf.sample(200.millis, 10, resolution = ChronoUnit.MILLIS).forEach {
val name = "run-${run++}"
jobs.add {
val rq = Roboquant(EMAStrategy(), ProgressMetric(), logger = LastEntryLogger())
Expand Down

0 comments on commit 8dacef1

Please sign in to comment.