Skip to content

Commit

Permalink
reformatted code
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaron committed Aug 1, 2023
1 parent f85e27d commit c1c0677
Show file tree
Hide file tree
Showing 24 changed files with 44 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ class XChangeBroker(exchange: Exchange, baseCurrencyCode: String = "USD") : Brok
updateAccount()
}


/**
* Place orders on a XChange supported exchange using the trade service.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal class CalendarChartTest {
assertTrue(chart.asHTML().isNotBlank())

Chart.counter = 0
TestData.testFile(chart,"calendarchart.txt")
TestData.testFile(chart, "calendarchart.txt")
}

}
25 changes: 14 additions & 11 deletions roboquant/src/main/kotlin/org/roboquant/Roboquant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,16 @@ 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" }
for (component in components) component.start(run, timeframe)
}

/**
* 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" }
Expand All @@ -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) {
Expand All @@ -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-<counter>"
* 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)
}

/**
Expand All @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions roboquant/src/main/kotlin/org/roboquant/backtest/Backtest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ 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" }
}

/**
* Perform a single run over the provided [timeframe] using the provided [warmup] period. The timeframe is
* 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)
}

/**
Expand All @@ -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)
}
}
Expand All @@ -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)
}
}
Expand Down
11 changes: 4 additions & 7 deletions roboquant/src/main/kotlin/org/roboquant/backtest/Optimizer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -103,8 +102,6 @@ open class Optimizer(
return results
}



/**
* Run a Monte Carlo simulation
*/
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions roboquant/src/main/kotlin/org/roboquant/backtest/Score.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 8 additions & 13 deletions roboquant/src/main/kotlin/org/roboquant/backtest/SearchSpace.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package org.roboquant.backtest
*/
interface SearchSpace : Iterable<Params> {


/**
* Update the search space based on an observation.
* The observation is a combination of the selected [params] and the resulting [score].
Expand All @@ -48,7 +47,7 @@ interface SearchSpace : Iterable<Params> {
class EmptySearchSpace : SearchSpace {

override fun iterator(): Iterator<Params> {
return listOf(Params()).listIterator()
return listOf(Params()).listIterator()
}

/**
Expand All @@ -59,7 +58,6 @@ class EmptySearchSpace : SearchSpace {

}


/**
* Random Search Space
*
Expand All @@ -80,11 +78,12 @@ class RandomSearch(override val size: Int) : SearchSpace {
private val list: List<Params> 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) {
Expand All @@ -97,11 +96,9 @@ class RandomSearch(override val size: Int) : SearchSpace {
}

override fun iterator(): Iterator<Params> {
return list.listIterator()
return list.listIterator()
}



/**
* Add a parameter function
*/
Expand All @@ -117,7 +114,6 @@ class RandomSearch(override val size: Int) : SearchSpace {
}



}

/**
Expand All @@ -138,14 +134,14 @@ class GridSearch : SearchSpace {
private val permutations = mutableListOf<Params>()


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)
}
}

Expand All @@ -170,12 +166,11 @@ class GridSearch : SearchSpace {
get() = params.map { it.value.size }.reduce(Int::times)

override fun iterator(): Iterator<Params> {
return list.listIterator()
return list.listIterator()
}
}



infix fun ClosedRange<Double>.step(step: Double): Iterable<Double> {
require(start.isFinite())
require(endInclusive.isFinite())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions roboquant/src/main/kotlin/org/roboquant/common/TimeSpan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion roboquant/src/main/kotlin/org/roboquant/common/Wallet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class Wallet(private val data: IdentityHashMap<Currency, Double> = IdentityHashM
return Wallet(data)
}


/**
* Create a Wallet based on the [amounts]
*/
Expand Down
2 changes: 1 addition & 1 deletion roboquant/src/main/kotlin/org/roboquant/http/WebServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ internal class ProgressBar {
private var pre: String = ""
private var post: String = ""
private var nextUpdate = Instant.MIN

private var lastOutput = ""

/**
Expand Down
1 change: 0 additions & 1 deletion roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ internal class RoboquantTest {

}


@Test
fun runAsync() = runBlocking {
val strategy = EMAStrategy()
Expand Down
Loading

0 comments on commit c1c0677

Please sign in to comment.