finalize swing strategy and fix trade reporter issue

This commit is contained in:
c9s 2020-10-28 17:44:37 +08:00
parent c96845ff6a
commit 67446670ac
11 changed files with 40 additions and 41 deletions

View File

@ -5,25 +5,25 @@ imports:
notifications:
slack:
defaultChannel: "#dev-bbgo"
errorChannel: "#bbgo-error"
defaultChannel: "dev-bbgo"
errorChannel: "bbgo-error"
# if you want to route channel by symbol
symbolChannels:
"^BTC": "#btc"
"^ETH": "#eth"
"^BTC": "btc"
"^ETH": "eth"
# if you want to route channel by exchange session
sessionChannels:
max: "#bbgo-max"
binance: "#bbgo-binance"
max: "bbgo-max"
binance: "bbgo-binance"
# routing rules
routing:
trade: "$symbol"
order: "$symbol"
submitOrder: "$session"
pnL: "#bbgo-pnl"
pnL: "bbgo-pnl"
reportPnL:
- averageCostBySymbols:

View File

@ -1,20 +1,20 @@
---
notifications:
slack:
defaultChannel: "#dev-bbgo"
errorChannel: "#bbgo-error"
defaultChannel: "dev-bbgo"
errorChannel: "bbgo-error"
# if you want to route channel by symbol
symbolChannels:
"^BTC": "#btc"
"^ETH": "#eth"
"^BTC": "btc"
"^ETH": "eth"
# object routing rules
routing:
trade: "$symbol"
order: "$symbol"
submitOrder: "$session" # not supported yet
pnL: "#bbgo-pnl"
pnL: "bbgo-pnl"
sessions:
binance:

View File

@ -1,21 +1,21 @@
---
notifications:
slack:
defaultChannel: "#dev-bbgo"
errorChannel: "#bbgo-error"
defaultChannel: "dev-bbgo"
errorChannel: "bbgo-error"
# if you want to route channel by symbol
symbolChannels:
"^BTC": "#btc"
"^ETH": "#eth"
"^BNB": "#bnb"
"^BTC": "btc"
"^ETH": "eth"
"^BNB": "bnb"
# object routing rules
routing:
trade: "$symbol"
order: "$symbol"
submitOrder: "$session" # not supported yet
pnL: "#bbgo-pnl"
pnL: "bbgo-pnl"
sessions:
binance:

View File

@ -31,10 +31,10 @@ func injectField(rs reflect.Value, fieldName string, obj interface{}) error {
return nil
}
logrus.Infof("found %s in %T, injecting %T...", fieldName, rs.Type(), obj)
logrus.Infof("found %s in %s, injecting %T...", fieldName, rs.Type(), obj)
if !field.CanSet() {
return errors.Errorf("field %s of %T can not be set", fieldName, rs.Type())
return errors.Errorf("field %s of %s can not be set", fieldName, rs.Type())
}
rv := reflect.ValueOf(obj)

View File

@ -79,8 +79,12 @@ func (store *MarketDataStore) handleKLineClosed(kline types.KLine) {
}
func (store *MarketDataStore) AddKLine(kline types.KLine) {
window := store.KLineWindows[kline.Interval]
window.Add(kline)
window, ok := store.KLineWindows[kline.Interval]
if !ok {
window = types.KLineWindow{kline}
} else {
window.Add(kline)
}
store.KLineWindows[kline.Interval] = window
store.LastKLine = kline

View File

@ -142,15 +142,15 @@ func (router *ObjectChannelRouter) Route(obj interface{}) (channel string, ok bo
}
type TradeReporter struct {
notifier Notifier
*Notifiability
channel string
channelRoutes map[*regexp.Regexp]string
}
func NewTradeReporter(notifier Notifier) *TradeReporter {
func NewTradeReporter(notifiability *Notifiability) *TradeReporter {
return &TradeReporter{
notifier: notifier,
Notifiability: notifiability,
channelRoutes: make(map[*regexp.Regexp]string),
}
}
@ -182,5 +182,5 @@ func (reporter *TradeReporter) Report(trade types.Trade) {
var channel = reporter.getChannel(trade.Symbol)
var text = util.Render(`:handshake: {{ .Symbol }} {{ .Side }} Trade Execution @ {{ .Price }}`, trade)
reporter.notifier.NotifyTo(channel, text, trade)
reporter.NotifyTo(channel, text, trade)
}

View File

@ -86,8 +86,6 @@ type ExchangeSession struct {
// standard indicators of each market
standardIndicatorSets map[string]*StandardIndicatorSet
tradeReporter *TradeReporter
loadedSymbols map[string]struct{}
}
@ -130,11 +128,6 @@ func (session *ExchangeSession) Market(symbol string) (market types.Market, ok b
return market, ok
}
func (session *ExchangeSession) ReportTrade(notifier Notifier) *TradeReporter {
session.tradeReporter = NewTradeReporter(notifier)
return session.tradeReporter
}
// Subscribe save the subscription info, later it will be assigned to the stream
func (session *ExchangeSession) Subscribe(channel types.Channel, symbol string, options types.SubscribeOptions) *ExchangeSession {
sub := types.Subscription{

View File

@ -107,11 +107,7 @@ func (trader *Trader) Run(ctx context.Context) error {
// session based trade reporter
for sessionName := range trader.environment.sessions {
var session = trader.environment.sessions[sessionName]
if session.tradeReporter != nil {
session.Stream.OnTrade(func(trade types.Trade) {
session.tradeReporter.Report(trade)
})
} else if trader.tradeReporter != nil {
if trader.tradeReporter != nil {
session.Stream.OnTrade(func(trade types.Trade) {
trader.tradeReporter.Report(trade)
})

View File

@ -2,6 +2,7 @@ package max
import (
"context"
"math"
"time"
"github.com/google/uuid"
@ -54,7 +55,7 @@ func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
BaseCurrency: toGlobalCurrency(m.BaseUnit),
MinNotional: m.MinQuoteAmount,
MinAmount: m.MinQuoteAmount,
MinLot: m.MinBaseAmount,
MinLot: 1.0 / math.Pow10(m.BaseUnitPrecision), // make it like 0.0001
MinQuantity: m.MinBaseAmount,
MaxQuantity: 10000.0,
MinPrice: 0.1,

View File

@ -40,6 +40,10 @@ func (n *Notifier) Notify(format string, args ...interface{}) {
}
func (n *Notifier) NotifyTo(channel, format string, args ...interface{}) {
if len(channel) == 0 {
channel = n.channel
}
var slackAttachments []slack.Attachment
var slackArgsOffset = -1

View File

@ -22,6 +22,7 @@ type Strategy struct {
*bbgo.MarketDataStore
*types.Market
// OrderExecutor is an interface for submitting order
bbgo.OrderExecutor
// These fields will be filled from the config file (it translates YAML to JSON)
@ -116,7 +117,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
case 1:
// if it goes up and it's above the moving average price, then we sell
if closePrice > movingAveragePrice {
s.notify(":chart_with_upwards_trend: closePrice %f is above movingAveragePrice %f, submitting sell order", closePrice, movingAveragePrice)
s.notify(":chart_with_upwards_trend: closePrice %f is above movingAveragePrice %f, submitting SELL order", closePrice, movingAveragePrice)
_, err := orderExecutor.SubmitOrders(ctx, types.SubmitOrder{
Symbol: s.Symbol,
@ -132,7 +133,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
case -1:
// if it goes down and it's below the moving average price, then we buy
if closePrice < movingAveragePrice {
s.notify(":chart_with_downwards_trend: closePrice %f is below movingAveragePrice %f, submitting buy order", closePrice, movingAveragePrice)
s.notify(":chart_with_downwards_trend: closePrice %f is below movingAveragePrice %f, submitting BUY order", closePrice, movingAveragePrice)
_, err := orderExecutor.SubmitOrders(ctx, types.SubmitOrder{
Symbol: s.Symbol,