# \[ANN\] Announcing Trading.jl

**URL:** https://discourse.julialang.org/t/ann-announcing-trading-jl/97812
**Category:** Package Announcements
**Tags:** package, algorithmic-trading, backtesting
**Created:** [April 23, 2023, 11:44am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812 "2023-04-23T11:44:04Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 23, 2023, 11:44am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/1 "2023-04-23T11:44:04Z")

</div>

Hi All,

I’m delighted to announce [Trading.jl](https://github.com/louisponet/Trading.jl), an event-driven algorithmic trading and backtesting package.

It provides an easy-to-use framework for defining and executing trading strategies based on technical indicators, as well as backtesting these strategies on historical data. The backtesting is set up in a way to be as equivalent to realtime trading as possible.

It builds on the ease of use, extensibility, inherent performance and elegance of the ECS (Entity-Component-System) paradigm, implemented through [Overseer.jl](https://github.com/louisponet/Overseer.jl), and keeps interoperability with the Julia ecosystem by interfacing with [TimeSeries.jl](https://github.com/JuliaStats/TimeSeries.jl).

# [Features](https://louisponet.github.io/Trading.jl/dev/#Features)

- Highly customizable and extensible by being based on ECS
- Backtesting and Realtime trading treated on completely equal footing
- Several built in indicators such as [`SMA`](https://louisponet.github.io/Trading.jl/dev/indicators/#Trading.SMA), [`EMA`](https://louisponet.github.io/Trading.jl/dev/indicators/#Trading.EMA), [`MovingStdDev`](https://louisponet.github.io/Trading.jl/dev/indicators/#Trading.MovingStdDev), [`RSI`](https://louisponet.github.io/Trading.jl/dev/indicators/#Trading.RSI) and [`Bollinger`](https://louisponet.github.io/Trading.jl/dev/indicators/#Trading.Bollinger)
- Interaction with brokers such as [Alpaca](https://alpaca.markets/)
- High performance, with backtesting on 100k data points within seconds

# [Illustrative Example](https://louisponet.github.io/Trading.jl/dev/#Illustrative-Example)

To define a trading strategy, all you need to do is implement a Julia `struct` that subtypes `System` with an `update`function that defines the trading logic. The `update` function is called periodically by the framework and has access to tick data for the tickers that the strategy was created for, as well as any technical indicators requested by the strategy. The package includes several built-in technical [`indicators`](https://louisponet.github.io/Trading.jl/dev/indicators/#Indicators) such as simple moving averages, relative strength index, and exponential moving averages. Users can also define their own custom [`indicators`](https://louisponet.github.io/Trading.jl/dev/indicators/#Indicators).

```julia-auto
struct MyStrategy <: System end

Overseer.requested_components(::MyStrategy) = (Open, Close, SMA{20, Close}, SMA{200, Close})

function Overseer.update(s::MyStrategy, trader, ticker_ledgers)
   for ledger in ticker_ledgers
        for e in new_entities(ledger, s)
            #Trading logic goes here
        end
    end
end

```

To execute a trading strategy in real-time, users can create a [`Trader`](https://louisponet.github.io/Trading.jl/dev/trader/#Trading.Trader) object with the desired strategies, and connect it to a real-time data source through the different broker APIs:

```julia-auto
broker = AlpacaBroker("<key_id>", "<secret>")
strategy = Strategy(:my_strategy, [MyStrategy()], tickers=["AAPL"])
trader = Trader(broker, strategies=[strategy])
start(trader)

```

If you want to backtest a trading strategy on historical data, you can use [`BackTester`](https://louisponet.github.io/Trading.jl/dev/trader/#Trading.BackTester) instead of [`Trader`](https://louisponet.github.io/Trading.jl/dev/trader/#Trading.Trader) with the desired data range, interval, and strategies. The [`BackTester`](https://louisponet.github.io/Trading.jl/dev/trader/#Trading.BackTester) will simulate the behavior of a realtime [`Trader`](https://louisponet.github.io/Trading.jl/dev/trader/#Trading.Trader) on the specified data. Afterward, a `TimeArray` can be created with the data from the trader, and used for performance analysis.

```julia-auto
trader = BackTester(HistoricalBroker(broker),
                    strategies=[strategy],
                    start = <start date>,
                    stop = <stop date>,
                    dt = <data timeframe>)
start(trader)

```

The [Documentation](https://louisponet.github.io/Trading.jl/dev/) is relatively complete and ever improving.

Have a look, let me know if you have any feedback, and happy trading!

Cheers

---

<div class="post-metadata">

### Author: ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)
#### Post date: [April 25, 2023, 11:56pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/2 "2023-04-25T23:56:17Z")

</div>

I really like how Trader and BackTester can be swapped. That seems elegant to me. There’s a lot I don’t understand yet (mostly due to being a Julia beginner), but I have some questions about this line:

```julia
Overseer.requested_components(::MyStrategy) = (Open, Close, SMA{20, Close}, SMA{200, Close})

```

- What timeframe will the Open and Close values be in?
- How does a strategy get access to the values for Open, Close, and SMA{20, Close}?

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [April 26, 2023, 1:08am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/3 "2023-04-26T01:08:15Z")

</div>

how to add broker support? is there an “interface” to implement? asking because I still have [GitHub - Moelf/TDAmeritrade.jl: A pure Julia wrapper for TD Ameritrade APIs](https://github.com/Moelf/TDAmeritrade.jl) maintained

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 26, 2023, 7:36am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/4 "2023-04-26T07:36:51Z")

</div>

Yes, I’ll do a small writeup in the documentation. It’s not too much. I’ll have a look also at your api.

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 26, 2023, 7:43am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/5 "2023-04-26T07:43:41Z")

</div>

In the case of a `BackTester` there’s a `dt` keyword argument that will determine the frequency of bars that will come in and thus also those quantities. Ofc `SMA{20,Close}` will have nothing for the first 19 timesteps and then each timestep it will be the rolling value.

In the case of a realtime `Trader` it will be as fast as they stream in from the `Broker`. So usually 1 Min based. There’s an automatic interpolation that happens when for example a couple of timesteps no bars show up (I’ve had this happen using the Alpaca realtime stream) and then one comes in.

I am planning to make it a bit more controllable though, say if you want to have only 5Min based strategies, or at least an automatic binner.

In the definition of a `Strategy` you specify which tickers it works on. Those will be registered and the system will listen for bar updates. These are then streamed into the `TickerLedgers`, 1 for each of the tickers, and passed as the 3rd argument to the `Overseer.update` function of your strategy.

Derived quantities such as `SMA{20, Close}` will be automatically computed in the `TickerLedgers` as data rolls in.

---

<div class="post-metadata">

### Author: ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)
#### Post date: [April 26, 2023, 11:36am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/6 "2023-04-26T11:36:33Z")

</div>

Looks really great! I was wondering if there’s an easy way to integrate trading costs? Especially in real-time trading the costs of the trade more often than not eat up all the profit.

---

<div class="post-metadata">

### Author: ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)
#### Post date: [April 26, 2023, 11:48am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/7 "2023-04-26T11:48:33Z")

</div>

Thank you for publishing this package! I wonder if it is possible to supply a limit order book to provide ask/bid price/volume info for performing more accurate backtesting?

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 26, 2023, 11:57am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/8 "2023-04-26T11:57:57Z")

</div>

The way that’s done right now when backtesting is through some settings in the `HistoricalBroker` (see [in the middle of the page here](https://louisponet.github.io/Trading.jl/dev/strategies/cointegration/)):

```julia
broker = HistoricalBroker(AlpacaBroker(ENV["ALPACA_KEY_ID"], ENV["ALPACA_SECRET"]))

broker.variable_transaction_fee = 0.0
broker.fee_per_share = 0.005
broker.fixed_transaction_fee = 0.0;

```

I will clarify this a bit more in the `HistoricalBroker` documentation though thanks!

EDIT: I’m also considering to put in some possibility to delay the order execution, potentially randomly since I’ve found that to also be quite an important difference in Realtime vs Backtesting. Then it would be possible to play around with cancellation of Orders that weren’t filled etc, something that’s not quite in there yet

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 26, 2023, 12:00pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/9 "2023-04-26T12:00:28Z")

</div>

I think technically this is absolutely possible, at least through `Alpaca`. There’s a way to ask for the [`quotes`](https://louisponet.github.io/Trading.jl/dev/brokers/#Trading.quotes) in a particular timerange. I’m not sure if this is exactly the order book but probably it could be derived from it.

For actual trades that happened there’s something similar with [`trades`](https://louisponet.github.io/Trading.jl/dev/brokers/#Trading.trades)

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [April 26, 2023, 1:03pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/10 "2023-04-26T13:03:17Z")

</div>

Cool package.

Also, Alpaca looks pretty cool as well. Their paper trading platform looks like a good start but it does make some pretty strong/weird assumptions (that they are honest about). Just a word of caution if you run a paper account algo there and see good performance, they are assuming away a decent chunk of real world order outcomes, so your live money performance will be potentially quite quite different. I’m guessing here, but maybe you could offer better backtesting realism in the package, but with data from Alpaca (which is just from IEX).

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 26, 2023, 1:26pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/11 "2023-04-26T13:26:36Z")

</div>

Right, although for now even with their paper trading I haven’t really found a reliable strategy 😛, I also had those concerns and that’s why I thought about putting some more capability in the HistoricalBroker.

As another project I’m actually working a bit on implementing my own stock exchange thingy which would also use their data to simulate trading. But that’s mainly to improve my c++ so it’ll be a long time before that’s anywhere near as useful as what Alpaca offers already 😛

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 27, 2023, 9:58pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/12 "2023-04-27T21:58:21Z")

</div>

I’ve written up a page on how to integrate new brokers [here](https://louisponet.github.io/Trading.jl/dev/developers/). Let me know what you think!

---

<div class="post-metadata">

### Author: ![Ininterrompue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ininterrompue/32/5594_2.png) [@Ininterrompue](https://discourse.julialang.org/u/Ininterrompue)
#### Post date: [April 28, 2023, 5:42am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/13 "2023-04-28T05:42:08Z")

</div>

Does this support equity and index options trades/backtesting?

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [April 28, 2023, 6:04am UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/14 "2023-04-28T06:04:43Z")

</div>

That simply depends on your broker, the package is agnostic to what asset you’re trading. It uses strings for identification, so as long as your asset can be identified with a string and your broker can receive orders and give you data updates for those assets it is possible

---

<div class="post-metadata">

### Author: ![1153dent](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1153dent/32/43968_2.png) [@1153dent](https://discourse.julialang.org/u/1153dent)
#### Post date: [April 30, 2023, 1:25pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/15 "2023-04-30T13:25:58Z")

</div>

this looks pretty interesting.

**Have you put an example of your results on a webpage?**

I’d like to see a real time example of how it works.

Maybe hook it up to a Yahoo or Google data feed? Exciting stuff well done.

---

<div class="post-metadata">

### Author: ![1153dent](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1153dent/32/43968_2.png) [@1153dent](https://discourse.julialang.org/u/1153dent)
#### Post date: [April 30, 2023, 1:28pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/16 "2023-04-30T13:28:23Z")

</div>

how about the greeks for options? Simple ones would be interesting delta/gamma. Also implied volatility would play a role so that would be of value. This looks VERY interesting to me

---

<div class="post-metadata">

### Author: ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)
#### Post date: [May 9, 2023, 7:10pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/17 "2023-05-09T19:10:40Z")

</div>

If one wanted to look at more than one timeframe at a time, is that possible with your system? For example, if the broker were feeding you 1m candles, could you derive candles in higher timeframes (like 30m and 4h) from them, and could strategies do analysis on those derived values?

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [May 9, 2023, 7:30pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/18 "2023-05-09T19:30:44Z")

</div>

Currently there’s no such system implemented, but it’s extremely simple to achieve though!

It’s very similar to the other indicator systems. You’d essentially have a `Binner` System which would look through components for a `Bin{timeframe}` component and then handle adding new values as bars stream in.

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [May 9, 2023, 8:20pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/19 "2023-05-09T20:20:03Z")

</div>

Sorry for replying so delayed. It’s a bit difficult showing a realtime example, but since the backtester and realtime are essentially identical, if your system runs in a backtester it’ll run in realtime too. Whether it’s as performant a strategy is of course a very different question 😃.

It kind of depends on how much real market conditions are simulated by the HistoricalBroker during backtesting. For now the most basic assumptions on order execution etc are used and so might not reflect real world conditions very well. I am planning to implement more sim features in the HistoricalBroker but one step at a time (ofc help would speed things up).

So far I’ve been focused on implementing the framework’s features rather than trying out different types of strategies.

Orderbook support for example is almost there 😃

---

<div class="post-metadata">

### Author: ![louisponet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/louisponet/32/2070_2.png) [@louisponet](https://discourse.julialang.org/u/louisponet)
#### Post date: [May 9, 2023, 8:20pm UTC](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812/20 "2023-05-09T20:20:32Z")

</div>

These should be very easy to implement similar to the current Indicator systems.

[Next page](https://discourse.julialang.org/t/ann-announcing-trading-jl/97812.md?page=2)
