mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 23:05:15 +00:00
101 lines
3.5 KiB
Markdown
101 lines
3.5 KiB
Markdown
|
How To Use Builtin Indicators and Create New Indicators
|
||
|
-------------------------------------------------------
|
||
|
|
||
|
### Built-in Indicators
|
||
|
In bbgo session, we already have several indicators defined inside.
|
||
|
We could refer to the live-data without the worriedness of handling market data subscription.
|
||
|
To use the builtin ones, we could refer the `StandardIndicatorSet` type:
|
||
|
|
||
|
```go
|
||
|
// defined in pkg/bbgo/session.go
|
||
|
(*StandardIndicatorSet) BOLL(iw types.IntervalWindow, bandwidth float64) *indicator.BOLL
|
||
|
(*StandardIndicatorSet) SMA(iw types.IntervalWindow) *indicator.SMA
|
||
|
(*StandardIndicatorSet) EWMA(iw types.IntervalWindow) *indicator.EWMA
|
||
|
(*StandardIndicatorSet) STOCH(iw types.IntervalWindow) *indicator.STOCH
|
||
|
(*StandardIndicatorSet) VOLATILITY(iw types.IntervalWindow) *indicator.VOLATILITY
|
||
|
```
|
||
|
|
||
|
and to get the `*StandardIndicatorSet` from `ExchangeSession`, just need to call:
|
||
|
```go
|
||
|
indicatorSet, ok := session.StandardIndicatorSet("BTCUSDT") // param: symbol
|
||
|
```
|
||
|
in your strategy's `Run` function.
|
||
|
|
||
|
|
||
|
And in `Subscribe` function in strategy, just subscribe the `KLineChannel` on the interval window of the indicator you want to query, you should be able to acquire the latest number on the indicators.
|
||
|
|
||
|
However, what if you want to use the indicators not defined in `StandardIndicatorSet`? For example, the `AD` indicator defined in `pkg/indicators/ad.go`?
|
||
|
|
||
|
Here's a simple example in what you should write in your strategy code:
|
||
|
```go
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/c9s/bbgo/pkg/bbgo"
|
||
|
"github.com/c9s/bbgo/pkg/types"
|
||
|
"github.com/c9s/bbgo/pkg/indicator"
|
||
|
)
|
||
|
|
||
|
type Strategy struct {}
|
||
|
|
||
|
func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
|
||
|
session.Subscribe(types.KLineChannel, s.Symbol. types.SubscribeOptions{Interval: "1m"})
|
||
|
}
|
||
|
|
||
|
func (s *Strategy) Run(ctx context.Context, oe bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
|
||
|
// first we need to get market data store(cached market data) from the exchange session
|
||
|
st, ok := session.MarketDataStore(s.Symbol)
|
||
|
if !ok {
|
||
|
...
|
||
|
return err
|
||
|
}
|
||
|
// setup the time frame size
|
||
|
window := types.IntervalWindow{Window: 10, Interval: types.Interval1m}
|
||
|
// construct AD indicator
|
||
|
AD := &indicator.AD{IntervalWindow: window}
|
||
|
// bind indicator to the data store, so that our callback could be triggered
|
||
|
AD.Bind(st)
|
||
|
AD.OnUpdate(func (ad float64) {
|
||
|
fmt.Printf("now we've got ad: %f, total length: %d\n", ad, AD.Length())
|
||
|
})
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### To Contribute
|
||
|
|
||
|
try to create new indicators in `pkg/indicator/` folder, and add compilation hint of go generator:
|
||
|
```go
|
||
|
// go:generate callbackgen -type StructName
|
||
|
type StructName struct {
|
||
|
...
|
||
|
UpdateCallbacks []func(value float64)
|
||
|
}
|
||
|
|
||
|
```
|
||
|
And implement required interface methods:
|
||
|
```go
|
||
|
// custom function
|
||
|
func (inc *StructName) calculateAndUpdate(kLines []types.KLine) {
|
||
|
// calculation...
|
||
|
// assign the result to calculatedValue
|
||
|
inc.EmitUpdate(calculatedValue) // produce data, broadcast to the subscribers
|
||
|
}
|
||
|
|
||
|
// custom function
|
||
|
func (inc *StructName) handleKLineWindowUpdate(interval types.Interval, window types.KLineWindow) {
|
||
|
// filter on interval
|
||
|
inc.calculateAndUpdate(window)
|
||
|
}
|
||
|
|
||
|
// required
|
||
|
func (inc *StructName) Bind(updator KLineWindowUpdater) {
|
||
|
updater.OnKLineWindowUpdate(inc.handleKLineWindowUpdate)
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The `KLineWindowUpdater` interface is currently defined in `pkg/indicator/ewma.go` and may be moved out in the future.
|
||
|
|
||
|
Once the implementation is done, run `go generate` to generate the callback functions of the indicator.
|
||
|
You should be able to implement your strategy and use the new indicator in the same way as `AD`.
|