diff --git a/roboquant-crypto/src/main/kotlin/org/roboquant/xchange/XChangeBroker.kt b/roboquant-crypto/src/main/kotlin/org/roboquant/xchange/XChangeBroker.kt index 9ac510ed4..06f04bd9b 100644 --- a/roboquant-crypto/src/main/kotlin/org/roboquant/xchange/XChangeBroker.kt +++ b/roboquant-crypto/src/main/kotlin/org/roboquant/xchange/XChangeBroker.kt @@ -79,7 +79,6 @@ class XChangeBroker(exchange: Exchange, baseCurrencyCode: String = "USD") : Brok updateAccount() } - /** * Place orders on a XChange supported exchange using the trade service. * diff --git a/roboquant-crypto/src/test/kotlin/org/roboquant/samples/main.kt b/roboquant-crypto/src/test/kotlin/org/roboquant/samples/main.kt index 4f00b7946..d4de4e6cc 100644 --- a/roboquant-crypto/src/test/kotlin/org/roboquant/samples/main.kt +++ b/roboquant-crypto/src/test/kotlin/org/roboquant/samples/main.kt @@ -111,7 +111,7 @@ suspend fun binanceWebServer() { val policy = FlexPolicy.singleAsset(enableMetrics = true) val rq = Roboquant(strategy, broker = broker, policy = policy, logger = ConsoleLogger()) - val server = WebServer(username= "test", password="secret") + val server = WebServer(username = "test", password = "secret") server.start() val tf = Timeframe.next(8.hours) server.runAsync(rq, feed, tf) diff --git a/roboquant-jupyter/src/main/kotlin/org/roboquant/jupyter/Chart.kt b/roboquant-jupyter/src/main/kotlin/org/roboquant/jupyter/Chart.kt index 2daec957f..42e5f4669 100644 --- a/roboquant-jupyter/src/main/kotlin/org/roboquant/jupyter/Chart.kt +++ b/roboquant-jupyter/src/main/kotlin/org/roboquant/jupyter/Chart.kt @@ -147,11 +147,10 @@ abstract class Chart : HTMLOutput() { var theme = "auto" get() = if (field == "auto") notebookTheme ?: field else field set(value) { - require(value in setOf("auto", "light", "dark")) { "valid options are auto, light and dark"} + require(value in setOf("auto", "light", "dark")) { "valid options are auto, light and dark" } field = value } - /** * Maximum number of samples to plot in a chart. Certain types of charts can become very large and as * a result make your browser unresponsive. By lowering this value (default is [Int.MAX_VALUE]) diff --git a/roboquant-jupyter/src/test/kotlin/org/roboquant/jupyter/CalendarChartTest.kt b/roboquant-jupyter/src/test/kotlin/org/roboquant/jupyter/CalendarChartTest.kt index 171c9a8b8..c48d76cdc 100644 --- a/roboquant-jupyter/src/test/kotlin/org/roboquant/jupyter/CalendarChartTest.kt +++ b/roboquant-jupyter/src/test/kotlin/org/roboquant/jupyter/CalendarChartTest.kt @@ -28,7 +28,7 @@ internal class CalendarChartTest { assertTrue(chart.asHTML().isNotBlank()) Chart.counter = 0 - TestData.testFile(chart,"calendarchart.txt") + TestData.testFile(chart, "calendarchart.txt") } } \ No newline at end of file diff --git a/roboquant/src/main/kotlin/org/roboquant/Roboquant.kt b/roboquant/src/main/kotlin/org/roboquant/Roboquant.kt index 87498ff64..450d4d1c6 100644 --- a/roboquant/src/main/kotlin/org/roboquant/Roboquant.kt +++ b/roboquant/src/main/kotlin/org/roboquant/Roboquant.kt @@ -83,9 +83,8 @@ data class Roboquant( kotlinLogger.debug { "Created new roboquant instance" } } - /** - * Inform components of the start of a new [run]. + * Inform components of the start of a new [run] with the provided [timeframe]. */ private fun start(run: String, timeframe: Timeframe) { kotlinLogger.debug { "starting run=$run timeframe=$timeframe" } @@ -93,7 +92,7 @@ data class Roboquant( } /** - * Inform components of the end of a new [run]. + * Inform components of the end of a [run]. */ private fun end(run: String) { kotlinLogger.debug { "Finished run=$run" } @@ -102,7 +101,9 @@ data class Roboquant( /** * Reset the state including that of the used underlying components. This allows starting a fresh run with the same - * configuration as the original instance. This will also reset the run counter in this roboquant instance. + * configuration as the original instance. + * + * By default, also the [logger] will be reset. If you don't want this, set [includeLogger] to false. */ fun reset(includeLogger: Boolean = true) { for (component in components) { @@ -111,24 +112,26 @@ data class Roboquant( } } - /** * Start a new run using the provided [feed] as data. If no [timeframe] is provided all the events in the feed * will be processed. You can provide a custom [name] that will help to later identify this run. If none is - * provided, a name will be generated with the format "run-" - * Additionally you can provide a [warmup] period in which no metrics will be logged or orders placed. + * provided, the default [name] "run" will be used. + * Additionally, you can provide a [warmup] period in which no metrics will be logged or orders placed. + * + * By default, at the beginning of a run, all components (besides the logger) will be [reset] and typically discard + * their state. If you don't want this behavior set [reset] to false. * * This is the synchronous (blocking) method of run that is convenient to use. However, if you want to execute runs - * in parallel have a look at [runAsync] + * in parallel, use the [runAsync] method. */ fun run( feed: Feed, timeframe: Timeframe = feed.timeframe, - warmup: TimeSpan = TimeSpan.ZERO, name: String = "run", + warmup: TimeSpan = TimeSpan.ZERO, reset: Boolean = true ) = runBlocking { - runAsync(feed, timeframe, warmup, name, reset) + runAsync(feed, timeframe, name, warmup, reset) } /** @@ -141,8 +144,8 @@ data class Roboquant( suspend fun runAsync( feed: Feed, timeframe: Timeframe = feed.timeframe, - warmup: TimeSpan = TimeSpan.ZERO, name: String = "run", + warmup: TimeSpan = TimeSpan.ZERO, reset: Boolean = true ) { val channel = EventChannel(channelCapacity, timeframe) diff --git a/roboquant/src/main/kotlin/org/roboquant/backtest/Backtest.kt b/roboquant/src/main/kotlin/org/roboquant/backtest/Backtest.kt index 1c00bd2e0..a50dfc80b 100644 --- a/roboquant/src/main/kotlin/org/roboquant/backtest/Backtest.kt +++ b/roboquant/src/main/kotlin/org/roboquant/backtest/Backtest.kt @@ -35,7 +35,7 @@ import org.roboquant.feeds.Feed class Backtest(val feed: Feed, val roboquant: Roboquant) { init { - require(roboquant.broker is SimBroker) { "Only a SimBroker can be used for back testing"} + require(roboquant.broker is SimBroker) { "Only a SimBroker can be used for back testing" } } /** @@ -43,7 +43,7 @@ class Backtest(val feed: Feed, val roboquant: Roboquant) { * including the warmup period. */ fun singleRun(timeframe: Timeframe = feed.timeframe, warmup: TimeSpan = TimeSpan.ZERO) { - roboquant.run(feed, timeframe, warmup, name = "run-$timeframe") + roboquant.run(feed, timeframe, name = "run-$timeframe", warmup) } /** @@ -56,7 +56,7 @@ class Backtest(val feed: Feed, val roboquant: Roboquant) { ) { require(feed.timeframe.isFinite()) { "feed needs a finite timeframe" } feed.timeframe.split(period, warmup).forEach { - roboquant.run(feed, it, warmup, name = "run-$it") + roboquant.run(feed, it, name = "run-$it", warmup) roboquant.reset(false) } } @@ -73,8 +73,8 @@ class Backtest(val feed: Feed, val roboquant: Roboquant) { warmup: TimeSpan = TimeSpan.ZERO, ) { require(feed.timeframe.isFinite()) { "feed needs a finite timeframe" } - feed.timeframe.sample(period, samples).forEach { - roboquant.run(feed, it, warmup, name = "run-$it") + feed.timeframe.sample(period, samples).forEach { + roboquant.run(feed, it, name = "run-$it", warmup) roboquant.reset(false) } } diff --git a/roboquant/src/main/kotlin/org/roboquant/backtest/Optimizer.kt b/roboquant/src/main/kotlin/org/roboquant/backtest/Optimizer.kt index 640dff139..3bde05233 100644 --- a/roboquant/src/main/kotlin/org/roboquant/backtest/Optimizer.kt +++ b/roboquant/src/main/kotlin/org/roboquant/backtest/Optimizer.kt @@ -46,7 +46,6 @@ open class Optimizer( private var run = 0 - /** * Using the default objective to maximize a metric. The default objective will use the last entry of the * provided [evalMetric] as the value to optimize. @@ -103,8 +102,6 @@ open class Optimizer( return results } - - /** * Run a Monte Carlo simulation */ @@ -135,9 +132,9 @@ open class Optimizer( for (params in space) { jobs.add { val rq = getRoboquant(params).copy(logger = getTrainLogger()) - require(rq.broker is SimBroker) { "Only a SimBroker can be used for back testing"} + require(rq.broker is SimBroker) { "Only a SimBroker can be used for back testing" } val name = "train-${run++}" - rq.runAsync(feed, tf, warmup, name = name) + rq.runAsync(feed, tf, name = name, warmup) val s = score.calculate(rq, name, tf) val result = RunResult(params, s, tf, name) results.add(result) @@ -151,10 +148,10 @@ open class Optimizer( private fun validate(feed: Feed, timeframe: Timeframe, params: Params, warmup: TimeSpan): RunResult { val rq = getRoboquant(params) - require(rq.broker is SimBroker) { "Only a SimBroker can be used for back testing"} + require(rq.broker is SimBroker) { "Only a SimBroker can be used for back testing" } val name = "validate-${run++}" - rq.run(feed, timeframe, warmup, name = name) + rq.run(feed, timeframe, name = name, warmup) val s = score.calculate(rq, name, timeframe) // println("phase=validation result=$result") return RunResult(params, s, timeframe, name) diff --git a/roboquant/src/main/kotlin/org/roboquant/backtest/Score.kt b/roboquant/src/main/kotlin/org/roboquant/backtest/Score.kt index 3f70b60ae..34feb9a39 100644 --- a/roboquant/src/main/kotlin/org/roboquant/backtest/Score.kt +++ b/roboquant/src/main/kotlin/org/roboquant/backtest/Score.kt @@ -64,14 +64,14 @@ class MetricScore(private val metricName: String, private val reduce: (TimeSerie /** * Some typical reduce functions to derive a [Double] value out of a [TimeSeries] - */ + */ companion object { fun last(ts: TimeSeries) = ts.values.last() fun mean(ts: TimeSeries) = ts.values.average() fun max(ts: TimeSeries) = ts.values.max() fun min(ts: TimeSeries) = ts.values.max() - fun annualized(ts: TimeSeries) : Double { + fun annualized(ts: TimeSeries): Double { if (ts.size < 2) return Double.NaN val perc = (ts.values.last() - ts.values.first()) / ts.values.first() return ts.timeframe.annualize(perc) diff --git a/roboquant/src/main/kotlin/org/roboquant/backtest/SearchSpace.kt b/roboquant/src/main/kotlin/org/roboquant/backtest/SearchSpace.kt index 1d91c0765..5f171fd12 100644 --- a/roboquant/src/main/kotlin/org/roboquant/backtest/SearchSpace.kt +++ b/roboquant/src/main/kotlin/org/roboquant/backtest/SearchSpace.kt @@ -22,7 +22,6 @@ package org.roboquant.backtest */ interface SearchSpace : Iterable { - /** * Update the search space based on an observation. * The observation is a combination of the selected [params] and the resulting [score]. @@ -48,7 +47,7 @@ interface SearchSpace : Iterable { class EmptySearchSpace : SearchSpace { override fun iterator(): Iterator { - return listOf(Params()).listIterator() + return listOf(Params()).listIterator() } /** @@ -59,7 +58,6 @@ class EmptySearchSpace : SearchSpace { } - /** * Random Search Space * @@ -80,11 +78,12 @@ class RandomSearch(override val size: Int) : SearchSpace { private val list: List by lazy { try { calcPermutations() - } catch (_: DoneException) {} + } catch (_: DoneException) { + } permutations } - private fun calcPermutations() { + private fun calcPermutations() { repeat(size) { val p = Params() for ((key, values) in params) { @@ -97,11 +96,9 @@ class RandomSearch(override val size: Int) : SearchSpace { } override fun iterator(): Iterator { - return list.listIterator() + return list.listIterator() } - - /** * Add a parameter function */ @@ -117,7 +114,6 @@ class RandomSearch(override val size: Int) : SearchSpace { } - } /** @@ -138,14 +134,14 @@ class GridSearch : SearchSpace { private val permutations = mutableListOf() - private fun calcPermutations(entry: Params = Params(), idx: Int = 0) { + private fun calcPermutations(entry: Params = Params(), idx: Int = 0) { val (key, values) = entries[idx] for (value in values) { entry[key] = value if (idx == entries.lastIndex) { permutations.add(entry.clone() as Params) } else { - calcPermutations(entry, idx+1) + calcPermutations(entry, idx + 1) } } @@ -170,12 +166,11 @@ class GridSearch : SearchSpace { get() = params.map { it.value.size }.reduce(Int::times) override fun iterator(): Iterator { - return list.listIterator() + return list.listIterator() } } - infix fun ClosedRange.step(step: Double): Iterable { require(start.isFinite()) require(endInclusive.isFinite()) diff --git a/roboquant/src/main/kotlin/org/roboquant/brokers/sim/execution/InternalAccount.kt b/roboquant/src/main/kotlin/org/roboquant/brokers/sim/execution/InternalAccount.kt index 98bcd8e61..5afc4f88c 100644 --- a/roboquant/src/main/kotlin/org/roboquant/brokers/sim/execution/InternalAccount.kt +++ b/roboquant/src/main/kotlin/org/roboquant/brokers/sim/execution/InternalAccount.kt @@ -172,7 +172,6 @@ class InternalAccount(var baseCurrency: Currency) { } } - /** * Create an immutable [Account] instance that can be shared with other components (Policy and Metric) and is * guaranteed not to change after it has been created. diff --git a/roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt b/roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt index c343f63cc..4e35e987e 100644 --- a/roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt +++ b/roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt @@ -57,7 +57,6 @@ class TimeSpan internal constructor(internal val period: Period, internal val du */ val ZERO = TimeSpan() - /** * Parse the string that is generated by [TimeSpan.toString] back to an instance of TimeSpan. * @@ -72,7 +71,6 @@ class TimeSpan internal constructor(internal val period: Period, internal val du return TimeSpan(Period.parse(parts[0]), Duration.parse("PT" + parts[1])) } - /** * Create a [Duration] instance based on hours, seconds and nanos */ diff --git a/roboquant/src/main/kotlin/org/roboquant/common/Timeframe.kt b/roboquant/src/main/kotlin/org/roboquant/common/Timeframe.kt index 602ca6d5b..54404ef4e 100644 --- a/roboquant/src/main/kotlin/org/roboquant/common/Timeframe.kt +++ b/roboquant/src/main/kotlin/org/roboquant/common/Timeframe.kt @@ -313,7 +313,6 @@ 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. diff --git a/roboquant/src/main/kotlin/org/roboquant/common/Wallet.kt b/roboquant/src/main/kotlin/org/roboquant/common/Wallet.kt index a93e5a21c..ed347ebc5 100644 --- a/roboquant/src/main/kotlin/org/roboquant/common/Wallet.kt +++ b/roboquant/src/main/kotlin/org/roboquant/common/Wallet.kt @@ -49,7 +49,6 @@ class Wallet(private val data: IdentityHashMap = IdentityHashM return Wallet(data) } - /** * Create a Wallet based on the [amounts] */ diff --git a/roboquant/src/main/kotlin/org/roboquant/http/WebServer.kt b/roboquant/src/main/kotlin/org/roboquant/http/WebServer.kt index 734e20d9e..01fa5867e 100644 --- a/roboquant/src/main/kotlin/org/roboquant/http/WebServer.kt +++ b/roboquant/src/main/kotlin/org/roboquant/http/WebServer.kt @@ -323,7 +323,7 @@ class WebServer(port: Int = 8000, username: String, password: String) { val rq = roboquant.copy(metrics = roboquant.metrics + metric, policy = PausablePolicy(roboquant.policy)) runs[run] = RunInfo(metric, rq, feed, timeframe, warmup) - rq.runAsync(feed, timeframe, warmup, run) + rq.runAsync(feed, timeframe, run, warmup) } diff --git a/roboquant/src/main/kotlin/org/roboquant/loggers/MetricsLogger.kt b/roboquant/src/main/kotlin/org/roboquant/loggers/MetricsLogger.kt index f8e9f30b6..7a5f4797c 100644 --- a/roboquant/src/main/kotlin/org/roboquant/loggers/MetricsLogger.kt +++ b/roboquant/src/main/kotlin/org/roboquant/loggers/MetricsLogger.kt @@ -53,8 +53,7 @@ interface MetricsLogger : Lifecycle { * This is optional to implement for a MetricsLogger since not all metric-loggers store metrics. * Use [metricNames] to see which metrics are available. */ - fun getMetric(name: String, run: String) : TimeSeries = getMetric(name)[run] ?: TimeSeries(emptyList()) - + fun getMetric(name: String, run: String): TimeSeries = getMetric(name)[run] ?: TimeSeries(emptyList()) /** * The list of metric names that are available and can be retrieved with the [getMetric]. diff --git a/roboquant/src/main/kotlin/org/roboquant/loggers/ProgressBar.kt b/roboquant/src/main/kotlin/org/roboquant/loggers/ProgressBar.kt index eb4428466..8fe984f83 100644 --- a/roboquant/src/main/kotlin/org/roboquant/loggers/ProgressBar.kt +++ b/roboquant/src/main/kotlin/org/roboquant/loggers/ProgressBar.kt @@ -37,7 +37,6 @@ internal class ProgressBar { private var pre: String = "" private var post: String = "" private var nextUpdate = Instant.MIN - private var lastOutput = "" /** diff --git a/roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt b/roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt index 84e6523a6..42712876d 100644 --- a/roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt @@ -157,7 +157,6 @@ internal class RoboquantTest { } - @Test fun runAsync() = runBlocking { val strategy = EMAStrategy() diff --git a/roboquant/src/test/kotlin/org/roboquant/backtest/OptimizerTest.kt b/roboquant/src/test/kotlin/org/roboquant/backtest/OptimizerTest.kt index 4879f8ef6..fe397bfb1 100644 --- a/roboquant/src/test/kotlin/org/roboquant/backtest/OptimizerTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/backtest/OptimizerTest.kt @@ -18,7 +18,7 @@ class OptimizerTest { space.add("y", 2..10) val opt = Optimizer(space, "account.equity") { params -> - val x = params.getInt("x") + val x = params.getInt("x") val y = x + params.getInt("y") val s = EMAStrategy(x, y) Roboquant(s, AccountMetric(), logger = LastEntryLogger()) @@ -26,7 +26,6 @@ class OptimizerTest { val feed = RandomWalkFeed.lastYears(1, nAssets = 1) - val r1 = opt.train(feed, feed.timeframe) assertTrue(r1.isNotEmpty()) @@ -46,7 +45,7 @@ class OptimizerTest { val logger = LastEntryLogger() val opt = Optimizer(space, "account.equity") { params -> - val x = params.getInt("x") + val x = params.getInt("x") val y = x + params.getInt("y") val s = EMAStrategy(x, y) Roboquant(s, AccountMetric(), logger = logger) @@ -58,7 +57,6 @@ class OptimizerTest { } - @Test fun noParams() { val space = EmptySearchSpace() @@ -73,5 +71,4 @@ class OptimizerTest { } - } \ No newline at end of file diff --git a/roboquant/src/test/kotlin/org/roboquant/backtest/ScoreTest.kt b/roboquant/src/test/kotlin/org/roboquant/backtest/ScoreTest.kt index 215b43821..0173c9d74 100644 --- a/roboquant/src/test/kotlin/org/roboquant/backtest/ScoreTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/backtest/ScoreTest.kt @@ -27,7 +27,6 @@ import kotlin.test.assertTrue class ScoreTest { - @Test fun basic() { val feed = RandomWalkFeed.lastYears(1) diff --git a/roboquant/src/test/kotlin/org/roboquant/backtest/SearchSpaceTest.kt b/roboquant/src/test/kotlin/org/roboquant/backtest/SearchSpaceTest.kt index ec2722e6a..a3eba7da3 100644 --- a/roboquant/src/test/kotlin/org/roboquant/backtest/SearchSpaceTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/backtest/SearchSpaceTest.kt @@ -33,8 +33,8 @@ class SearchSpaceTest { } val params = space.toList() - assertEquals(3*100*100, params.size) - assertEquals(100*100, params.filter{ + assertEquals(3 * 100 * 100, params.size) + assertEquals(100 * 100, params.filter { it.getString("p1") == "a" }.size) diff --git a/roboquant/src/test/kotlin/org/roboquant/brokers/NoExchangeRatesTest.kt b/roboquant/src/test/kotlin/org/roboquant/brokers/NoExchangeRatesTest.kt index 3b642f791..34fb5645f 100644 --- a/roboquant/src/test/kotlin/org/roboquant/brokers/NoExchangeRatesTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/brokers/NoExchangeRatesTest.kt @@ -40,7 +40,7 @@ internal class NoExchangeRatesTest { currencyConverter.convert(0.USD, EUR, now) } - assertThrows { + assertThrows { currencyConverter.getRate(amount1, EUR, now) } } diff --git a/roboquant/src/test/kotlin/org/roboquant/brokers/sim/SimBrokerTest.kt b/roboquant/src/test/kotlin/org/roboquant/brokers/sim/SimBrokerTest.kt index 36b320160..b0b086753 100644 --- a/roboquant/src/test/kotlin/org/roboquant/brokers/sim/SimBrokerTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/brokers/sim/SimBrokerTest.kt @@ -33,7 +33,6 @@ import kotlin.test.assertTrue internal class SimBrokerTest { - @Test fun defaults() { val broker = SimBroker() diff --git a/roboquant/src/test/kotlin/org/roboquant/http/WebServerTest.kt b/roboquant/src/test/kotlin/org/roboquant/http/WebServerTest.kt index b1067bff6..c4afdce2d 100644 --- a/roboquant/src/test/kotlin/org/roboquant/http/WebServerTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/http/WebServerTest.kt @@ -13,7 +13,7 @@ import kotlin.test.Test class WebServerTest { @Test - fun basic() { + fun basic() { Config.getProperty("FULL_COVERAGE") ?: return val feed = RandomWalkFeed(Timeframe.fromYears(2000, 2001)) val rq = Roboquant(EMAStrategy(), logger = SilentLogger()) diff --git a/roboquant/src/test/kotlin/org/roboquant/loggers/MemoryLoggerTest.kt b/roboquant/src/test/kotlin/org/roboquant/loggers/MemoryLoggerTest.kt index 36bdb958e..3b9ab936b 100644 --- a/roboquant/src/test/kotlin/org/roboquant/loggers/MemoryLoggerTest.kt +++ b/roboquant/src/test/kotlin/org/roboquant/loggers/MemoryLoggerTest.kt @@ -88,7 +88,6 @@ internal class MemoryLoggerTest { } - @Test fun testMetricsEntry() { val logger = MemoryLogger(showProgress = false)