Skip to content

Commit

Permalink
Introduced separate server module and added order updates to orderstate
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaron committed Aug 11, 2023
1 parent 200fdad commit b582f2f
Show file tree
Hide file tree
Showing 29 changed files with 754 additions and 618 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<module>roboquant-polygon</module>
<module>roboquant-xchange</module>
<module>roboquant-binance</module>
<module>roboquant-server</module>
<module>roboquant-perf</module>
<!-- module roboquant-ibkr is part of ibkr profile since it relies on a locally installed library -->
</modules>
Expand Down
24 changes: 0 additions & 24 deletions roboquant-alpaca/src/test/kotlin/org/roboquant/samples/alpaca.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ import org.roboquant.alpaca.*
import org.roboquant.common.*
import org.roboquant.feeds.AvroFeed
import org.roboquant.feeds.toList
import org.roboquant.http.WebServer
import org.roboquant.loggers.InfoLogger
import org.roboquant.loggers.MemoryLogger
import org.roboquant.metrics.AccountMetric
import org.roboquant.metrics.ProgressMetric
import org.roboquant.strategies.EMAStrategy
Expand Down Expand Up @@ -97,9 +95,6 @@ private fun alpacaTradeCrypto() {
private fun alpacaTradeStocks() {
val feed = AlpacaLiveFeed()

val symbols = feed.availableStocks.take(10).symbols
println(symbols.toList())

feed.subscribeStocks(*symbols, type = PriceActionType.QUOTE)
feed.heartbeatInterval = 30_000
val strategy = EMAStrategy.PERIODS_5_15
Expand All @@ -110,24 +105,6 @@ private fun alpacaTradeStocks() {
println(roboquant.broker.account.summary())
}

private fun alpacaPaperTrade() {
val feed = AlpacaLiveFeed()
feed.subscribeStocks(*symbols, type = PriceActionType.PRICE_BAR)
feed.heartbeatInterval = 30_000
val strategy = EMAStrategy.PERIODS_5_15
val broker = AlpacaBroker()
val roboquant =
Roboquant(strategy, AccountMetric(), ProgressMetric(), broker = broker, logger = MemoryLogger(false))
val tf = Timeframe.next(60.minutes)

val server = WebServer()
server.start()

server.run(roboquant, feed, tf)
server.stop()
feed.close()
println(roboquant.broker.account.summary())
}

/**
* Alpaca historic feed example where we retrieve 1-minutes price-bars in batches of 1 day for 100 days.
Expand Down Expand Up @@ -240,7 +217,6 @@ fun main() {
"ALPACA_BROKER" -> alpacaBroker()
"ALPACA_TRADE_CRYPTO" -> alpacaTradeCrypto()
"ALPACA_TRADE_STOCKS" -> alpacaTradeStocks()
"PAPER_TRADE" -> alpacaPaperTrade()
"ALPACA_HISTORIC_FEED" -> alpacaHistoricFeed()
"ALPACA_HISTORIC_FEED2" -> alpacaHistoricFeed2()
"ALPACA_HISTORIC_SP500_PRICEBAR" -> alpacaSP500PriceBar()
Expand Down
21 changes: 1 addition & 20 deletions roboquant-binance/src/test/kotlin/org/roboquant/samples/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import org.roboquant.brokers.sim.SimBroker
import org.roboquant.common.*
import org.roboquant.feeds.AvroFeed
import org.roboquant.feeds.toList
import org.roboquant.http.WebServer
import org.roboquant.loggers.ConsoleLogger
import org.roboquant.loggers.MemoryLogger
import org.roboquant.metrics.AccountMetric
import org.roboquant.metrics.ScorecardMetric
import org.roboquant.policies.FlexPolicy
Expand Down Expand Up @@ -100,22 +98,6 @@ fun binanceForwardTest() {
}


suspend fun binanceWebServer() {
val feed = BinanceLiveFeed()
feed.subscribePriceBar("BTCBUSD")
val strategy = EMAStrategy.PERIODS_5_15
val initialDeposit = Amount("BUSD", 10_000).toWallet()
val broker = SimBroker(initialDeposit)
val policy = FlexPolicy.singleAsset()
val rq = Roboquant(strategy, AccountMetric(), broker = broker, policy = policy, logger = MemoryLogger())

val server = WebServer(username = "test", password = "secret")
server.start()
val tf = Timeframe.next(8.hours)
server.runAsync(rq, feed, tf)
server.stop()
}

fun binanceBackTest() {
val strategy = EMAStrategy()
val initialDeposit = Amount("BUSD", 100_000).toWallet()
Expand All @@ -131,14 +113,13 @@ fun binanceBackTest() {



suspend fun main() {
fun main() {

when ("WEB") {
"RECORD" -> recordBinanceFeed()
"USE" -> useBinanceFeed()
"LIVE" -> binanceLiveFeed()
"HISTORIC" -> binanceBackTest()
"FORWARD" -> binanceForwardTest()
"WEB" -> binanceWebServer()
}
}
38 changes: 1 addition & 37 deletions roboquant-ibkr/src/test/kotlin/org/roboquant/samples/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,19 @@

package org.roboquant.samples

import org.roboquant.Roboquant
import org.roboquant.brokers.FixedExchangeRates
import org.roboquant.brokers.assets
import org.roboquant.common.*
import org.roboquant.feeds.AvroFeed
import org.roboquant.feeds.PriceAction
import org.roboquant.feeds.filter
import org.roboquant.feeds.toList
import org.roboquant.http.WebServer
import org.roboquant.ibkr.IBKRBroker
import org.roboquant.ibkr.IBKRExchangeRates
import org.roboquant.ibkr.IBKRHistoricFeed
import org.roboquant.ibkr.IBKRLiveFeed
import org.roboquant.loggers.ConsoleLogger
import org.roboquant.metrics.AccountMetric
import org.roboquant.metrics.ProgressMetric
import org.roboquant.orders.BracketOrder
import org.roboquant.orders.MarketOrder
import org.roboquant.strategies.EMAStrategy
import java.time.DayOfWeek
import java.time.LocalDate

Expand Down Expand Up @@ -86,35 +80,6 @@ fun showAccount() {
broker.disconnect()
}

suspend fun paperTrade() {
Config.exchangeRates = IBKRExchangeRates()
val broker = IBKRBroker()
val account = broker.account
println(account.fullSummary())

val feed = IBKRLiveFeed()
// val asset = Asset("ABN", AssetType.STOCK, "EUR", "AEB")
val asset = Asset("TSLA", AssetType.STOCK, "USD", "NASDAQ")
feed.subscribe(listOf(asset))

val strategy = EMAStrategy.PERIODS_5_15
val roboquant = Roboquant(strategy, AccountMetric(), ProgressMetric(), broker = broker, logger = ConsoleLogger())
val tf = Timeframe.next(60.minutes)


val server = WebServer()
server.start()

server.runAsync(roboquant, feed, tf)
println(broker.account.fullSummary())

server.stop()
feed.disconnect()
broker.disconnect()

println("done")
}


fun placeOrder() {
Config.exchangeRates = IBKRExchangeRates()
Expand Down Expand Up @@ -232,7 +197,7 @@ fun historicFuturesFeed() {
}


suspend fun main() {
fun main() {

when ("PAPER_TRADE") {
"ACCOUNT" -> showAccount()
Expand All @@ -241,7 +206,6 @@ suspend fun main() {
"CLOSE_POSITION" -> closePosition()
"LIVE_FEED_EU" -> liveFeedEU()
"LIVE_FEED_US" -> liveFeedUS()
"PAPER_TRADE" -> paperTrade()
"HISTORIC" -> historicFeed()
"HISTORIC2" -> historicFeed2()
"HISTORIC3" -> historicFuturesFeed()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package org.roboquant.jupyter
/*
* Copyright 2020-2023 Neural Layer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.roboquant.charts

import org.roboquant.Roboquant
import org.roboquant.charts.Chart
import org.roboquant.charts.HTMLOutput
import org.roboquant.charts.TimeSeriesChart
import org.roboquant.common.TimeSeries
import java.nio.charset.StandardCharsets

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
package org.roboquant.jupyter
/*
* Copyright 2020-2023 Neural Layer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.roboquant.charts


import org.junit.jupiter.api.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.roboquant.samples
import org.roboquant.Roboquant
import org.roboquant.common.Config
import org.roboquant.feeds.AvroFeed
import org.roboquant.jupyter.MetricsReport
import org.roboquant.charts.MetricsReport
import org.roboquant.metrics.ReturnsMetric2
import org.roboquant.metrics.ScorecardMetric
import org.roboquant.strategies.EMAStrategy
Expand Down
98 changes: 98 additions & 0 deletions roboquant-server/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2020-2023 Neural Layer
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>roboquant-parent</artifactId>
<groupId>org.roboquant</groupId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>roboquant-server</artifactId>
<packaging>jar</packaging>
<name>roboquant server</name>
<description>server to run roboquant algorithmic trading strategies</description>

<properties>
<ktor_version>2.3.3</ktor_version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.roboquant</groupId>
<artifactId>roboquant</artifactId>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-core-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-html-builder-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-content-negotiation-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-serialization-gson-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-host-common-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-auth-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-sessions-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-netty-jvm</artifactId>
<version>${ktor_version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2020-2023 Neural Layer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.roboquant.server

import org.roboquant.brokers.Account
import org.roboquant.feeds.Event
import org.roboquant.orders.Order
import org.roboquant.policies.Policy
import org.roboquant.strategies.Signal

internal class PausablePolicy(private val policy: Policy, var pause: Boolean = false) : Policy by policy {

override fun act(signals: List<Signal>, account: Account, event: Event): List<Order> {
// Still invoke the policy so any state can be updated if required.
val orders = policy.act(signals, account, event)
return if (pause) emptyList() else orders
}

}
Loading

0 comments on commit b582f2f

Please sign in to comment.