Skip to content

Commit

Permalink
Optimized API
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaron committed Apr 12, 2024
1 parent 902b7b2 commit 5386b68
Show file tree
Hide file tree
Showing 16 changed files with 25 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ internal class AlpacaSamples {
val strategy = EMAStrategy(3, 5)
val roboquant = Roboquant(strategy, broker = broker)
val tf = Timeframe.next(60.minutes)
val account2 = roboquant.run(feed, tf)
val account2 = roboquant.run(feed, timeframe = tf)
feed.close()

println(account2.fullSummary())
Expand All @@ -91,7 +91,7 @@ internal class AlpacaSamples {
val strategy = EMAStrategy.PERIODS_5_15
val roboquant = Roboquant(strategy)
val tf = Timeframe.next(10.minutes)
val account = roboquant.run(feed, tf)
val account = roboquant.run(feed, timeframe = tf)
feed.close()
println(account.summary())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ internal class AvroSamples {

// Walk forward
feed.split(2.years).forEach {
roboquant.run(feed, it)
roboquant.run(feed, timeframe = it)
}

// Walk forward learning
feed.split(2.years).map { it.splitTwoWay(0.2) }.forEach { (train, test) ->
roboquant.run(feed, train)
roboquant.run(feed, timeframe = train)
roboquant.reset()
roboquant.run(feed, test)
roboquant.run(feed, timeframe = test)
}

}
Expand All @@ -130,7 +130,7 @@ internal class AvroSamples {
val policy = MyPolicy().resolve(SignalResolution.NO_CONFLICTS)

val roboquant = Roboquant(strategy, policy = policy)
roboquant.run(feed, Timeframe.past(5.years))
roboquant.run(feed, timeframe = Timeframe.past(5.years))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ internal class BinanceSamples {

// We'll run the forward test for thirty minutes
val tf = Timeframe.next(30.minutes)
rq.run(feed, tf)
rq.run(feed, timeframe = tf)
}

@Test
Expand Down Expand Up @@ -155,7 +155,7 @@ internal class BinanceSamples {
repeat(3) {
jobs.add {
val rq = Roboquant(EMAStrategy())
rq.run(feed, tf)
rq.run(feed, timeframe = tf)
}
}

Expand Down
13 changes: 0 additions & 13 deletions roboquant-charts/src/main/kotlin/org/roboquant/charts/BoxChart.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import org.icepear.echarts.components.coord.cartesian.ValueAxis
import org.icepear.echarts.components.dataZoom.DataZoom
import org.roboquant.common.TimeSeries
import org.roboquant.common.clean
import org.roboquant.common.flatten
import java.math.MathContext
import java.math.RoundingMode
import java.time.temporal.ChronoUnit
Expand All @@ -51,18 +50,6 @@ class BoxChart(
private val precision: Int = 8
) : Chart() {

/**
* Create box plot from multiple runs
*/
constructor(
metricData: Map<String, TimeSeries>,
period: ChronoUnit = ChronoUnit.MONTHS,
lowPercentile: Double = 25.0,
midPercentile: Double = 50.0,
highPercentile: Double = 75.0,
precision: Int = 8
) : this(metricData.flatten(true), period, lowPercentile, midPercentile, highPercentile, precision)


private fun toSeriesData(): List<Pair<String, Any>> {
val result = mutableListOf<Pair<String, Any>>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ import org.icepear.echarts.charts.heatmap.HeatmapSeries
import org.icepear.echarts.components.title.Title
import org.icepear.echarts.components.tooltip.Tooltip
import org.roboquant.common.TimeSeries
import org.roboquant.common.flatten
import org.roboquant.common.round
import java.math.BigDecimal
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import kotlin.collections.*

Expand All @@ -43,12 +41,6 @@ class CalendarChart(
private val zoneId: ZoneId = ZoneId.of("UTC")
) : Chart() {

/**
* Create a calendar chart from multiple runs. The data will be flattened before plotted.
*/
constructor(metricsData: Map<String, TimeSeries>, fractionDigits: Int = 2, zoneId: ZoneId = ZoneOffset.UTC) :
this(metricsData.flatten(true), fractionDigits, zoneId)

private val timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(zoneId)
private val metricsData = timeSeries.filter { it.value.isFinite() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import org.icepear.echarts.components.coord.cartesian.ValueAxis
import org.icepear.echarts.components.dataZoom.DataZoom
import org.icepear.echarts.components.series.LineStyle
import org.roboquant.common.TimeSeries
import org.roboquant.common.flatten
import java.math.BigDecimal
import java.math.RoundingMode

Expand All @@ -48,45 +47,6 @@ class TimeSeriesChart(
constructor(timeSeries: TimeSeries, useTime: Boolean = true, fractionDigits: Int = 2) :
this(mapOf("" to timeSeries), useTime, fractionDigits)

/**
* @suppress
*/
companion object {

/**
* Return a chart based on multiple runs. Because each run starts fresh, not the absolute values, but the
* returns are used to flatten runs to a single timeline.
*
* Optionally, a Monte Carlo simulation can be run on the returns to get an impression how the data would look
* like if the returns had occurred in a different order.
*
* ```
* val data = roboquant.logger.getMetric("account.equity")
* TimeSeriesChart.walkForward(data, monteCarlo = 100)
* ```
*/
fun walkForward(
metricsData: Map<String, TimeSeries>,
fractionDigits: Int = 2,
monteCarlo: Int = 0,
): TimeSeriesChart {
require(monteCarlo >= 0)
require(fractionDigits >= 0)

val d = metricsData.mapValues { it.value.returns() }.flatten()
var data = d.runningFold(100.0)
if (monteCarlo == 0) return TimeSeriesChart(mapOf("" to data))

val result = mutableMapOf("original" to data)
repeat(monteCarlo) {
data = d.shuffle().runningFold(100.0)
result["mc-$it"] = data
}
return TimeSeriesChart(result)

}

}

/**
* Identify common suffix (same run), so they can be removed from the series name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@

package org.roboquant.charts

import org.roboquant.loggers.MemoryLogger
import kotlin.test.Test
import kotlin.test.assertTrue

internal class BoxChartTest {

@Test
fun test() {
val logger = MemoryLogger()
val data = logger.getMetric("test")
val data = TestData.data
val chart = BoxChart(data)
assertTrue(chart.renderJson().isNotBlank())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,9 @@ object TestData {

val data by lazy {
val feed = HistoricTestFeed(50..150)
var journal = MetricsJournal(AccountMetric())
val journal = MetricsJournal(AccountMetric())
org.roboquant.run(feed, EMAStrategy(), journal)
val run1 = journal.getMetric("account.equity")
journal = MetricsJournal(AccountMetric())
org.roboquant.run(feed, EMAStrategy(), journal)
val run2 = journal.getMetric("account.equity")
mapOf("run1" to run1, "run2" to run2)
journal.getMetric("account.equity")
}

private fun loadFile(name: String): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal class TimeSeriesChartTest {
@Test
fun single() {
val data = TestData.data
val chart = TimeSeriesChart(data.values.first())
val chart = TimeSeriesChart(data)

assertDoesNotThrow {
chart.renderJson()
Expand All @@ -35,29 +35,7 @@ internal class TimeSeriesChartTest {
assertTrue(chart.renderJson().isNotBlank())
}

@Test
fun predefined() {
val data = TestData.data
val chart = TimeSeriesChart.walkForward(data)

assertDoesNotThrow {
chart.renderJson()
}

assertTrue(chart.renderJson().isNotBlank())
}

@Test
fun predefined2() {
val data = TestData.data
val chart = TimeSeriesChart.walkForward(data)

assertDoesNotThrow {
chart.renderJson()
}

assertTrue(chart.renderJson().isNotBlank())
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ internal class IBKRSamples {
policy = policy,
broker = broker,
)
rq.run(feed, Timeframe.next(2.hours))
rq.run(feed, timeframe = Timeframe.next(2.hours))

feed.disconnect()
broker.disconnect()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ internal class MLSamples {
}
val rq = Roboquant(strategy, policy = policy, broker = broker)
val (train, valid) = feed.timeframe.splitTwoWay(9.months)
rq.run(feed, train)
rq.run(feed, timeframe = train)
rq.broker.reset()
val account = rq.run(feed, valid)
val account = rq.run(feed, timeframe = valid)
println(account.summary())
val trades = account.trades
println(trades.filter { !it.pnlValue.iszero }.joinToString("\n") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal class TiingoSamples {
val feed = TiingoLiveFeed.iex()
feed.subscribe("AAPL", "TSLA")
val rq = Roboquant(EMAStrategy())
val account = rq.run(feed, Timeframe.next(10.minutes))
val account = rq.run(feed, timeframe = Timeframe.next(10.minutes))
println(account.fullSummary())
}

Expand All @@ -60,7 +60,7 @@ internal class TiingoSamples {
val feed = TiingoLiveFeed.fx()
feed.subscribe("EURUSD")
val rq = Roboquant(EMAStrategy())
val account = rq.run(feed, Timeframe.next(1.minutes))
val account = rq.run(feed, timeframe = Timeframe.next(1.minutes))
println(account.fullSummary())
}

Expand All @@ -73,7 +73,7 @@ internal class TiingoSamples {

feed.subscribe("BNBFDUSD")
val rq = Roboquant(EMAStrategy())
val account = rq.run(feed, Timeframe.next(1.minutes))
val account = rq.run(feed, timeframe = Timeframe.next(1.minutes))
println(account.fullSummary())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal class TiingoLiveFeedTestIT {
val feed = TiingoLiveFeed.fx()
feed.subscribe("EURUSD")
val rq = Roboquant(EMAStrategy())
rq.run(feed, Timeframe.next(1.minutes))
rq.run(feed, timeframe = Timeframe.next(1.minutes))
}

@Test
Expand All @@ -53,7 +53,7 @@ internal class TiingoLiveFeedTestIT {
Config.registerAsset("BNBFDUSD", asset)
feed.subscribe("BNBFDUSD")
val rq = Roboquant(EMAStrategy())
rq.run(feed, Timeframe.next(1.minutes))
rq.run(feed, timeframe = Timeframe.next(1.minutes))
}


Expand Down
6 changes: 3 additions & 3 deletions roboquant/src/main/kotlin/org/roboquant/Roboquant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ data class Roboquant(
*/
fun run(
feed: Feed,
timeframe: Timeframe = feed.timeframe,
journal: Journal? = null,
timeframe: Timeframe = feed.timeframe,
channel: EventChannel = EventChannel(timeframe, 10),
heartbeatTimeout: Long = -1,
showProgressBar: Boolean = false
): Account = runBlocking {
return@runBlocking runAsync(feed, timeframe, journal, channel, heartbeatTimeout, showProgressBar)
return@runBlocking runAsync(feed, journal, timeframe, channel, heartbeatTimeout, showProgressBar)
}

/**
Expand All @@ -99,8 +99,8 @@ data class Roboquant(
*/
suspend fun runAsync(
feed: Feed,
timeframe: Timeframe = feed.timeframe,
journal: Journal? = null,
timeframe: Timeframe = feed.timeframe,
channel: EventChannel = EventChannel(timeframe, 10),
heartbeatTimeout: Long = -1,
showProgressBar: Boolean = false
Expand Down
2 changes: 1 addition & 1 deletion roboquant/src/test/kotlin/org/roboquant/RoboquantTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal class RoboquantTest {
val broker = SimBroker(initial)
val logger = MemoryLogger()
val roboquant = Roboquant(strategy, broker = broker)
roboquant.run(feed, Timeframe.INFINITE)
roboquant.run(feed, timeframe = Timeframe.INFINITE)
roboquant.broker.reset()
assertTrue(logger.history.isEmpty())
val account = broker.sync()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ internal class AggregatorFeedTest {
aggFeed.timeframe.split(3.months).forEach {
jobs.add {
val rq = Roboquant(EMAStrategy())
rq.runAsync(aggFeed, it)
rq.runAsync(aggFeed, timeframe = it)
}
}
}
Expand Down

0 comments on commit 5386b68

Please sign in to comment.