qbtrade/pkg/strategy/ccinr/strategy.go

129 lines
3.1 KiB
Go
Raw Normal View History

2024-07-21 14:42:15 +00:00
package ccinr
import (
"context"
"fmt"
"git.qtrade.icu/lychiyu/qbtrade/pkg/exchange/binance"
"git.qtrade.icu/lychiyu/qbtrade/pkg/qbtrade"
"git.qtrade.icu/lychiyu/qbtrade/pkg/strategy/common"
"git.qtrade.icu/lychiyu/qbtrade/pkg/types"
log "github.com/sirupsen/logrus"
"sync"
)
const ID = "ccinr"
func init() {
qbtrade.RegisterStrategy(ID, &Strategy{})
}
type Strategy struct {
*common.Strategy
Symbol string `json:"symbol"`
Interval types.Interval `json:"interval"`
ExchangeSession *qbtrade.ExchangeSession
}
func (s *Strategy) ID() string {
return ID
}
func (s *Strategy) Subscribe(session *qbtrade.ExchangeSession) {
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval})
if !qbtrade.IsBackTesting {
session.Subscribe(types.MarketTradeChannel, s.Symbol, types.SubscribeOptions{})
}
}
func (s *Strategy) Initialize() error {
if s.Strategy == nil {
s.Strategy = &common.Strategy{}
}
return nil
}
func (s *Strategy) Run(ctx context.Context, orderExecutor qbtrade.OrderExecutor, session *qbtrade.ExchangeSession) error {
s.ExchangeSession = session
nr := session.Indicators(s.Symbol).NR(s.Interval, 4, true)
nr.OnUpdate(func(v float64) {
msg := fmt.Sprintf("交易信号:时间: %s, 最高价:%f最低价:%f", nr.NrKLine.GetStartTime(), nr.NrKLine.High.Float64(), nr.NrKLine.Low.Float64())
qbtrade.Notify(msg)
fmt.Println(v)
})
//session.MarketDataStream.OnKLineClosed(func(k types.KLine) {
// if k.Symbol != s.Symbol || k.Interval != s.Interval {
// return
// }
// fmt.Println(k)
//})
//
//session.MarketDataStream.OnMarketTrade(func(trade types.Trade) {
// // handle market trade event here
// fmt.Println(trade)
//})
b, ok := s.getBalance(ctx)
fmt.Println(b, ok)
session.UserDataStream.OnOrderUpdate(func(order types.Order) {
if order.Status == types.OrderStatusFilled {
log.Infof("your order is filled: %+v", order)
}
})
session.UserDataStream.OnTradeUpdate(func(trade types.Trade) {
log.Infof("trade price %f, fee %f %s", trade.Price.Float64(), trade.Fee.Float64(), trade.FeeCurrency)
})
qbtrade.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
if err := s.Strategy.OrderExecutor.GracefulCancel(ctx); err != nil {
log.WithError(err).Error("unable to cancel open orders...")
}
qbtrade.Sync(ctx, s)
})
return nil
}
func (s *Strategy) handleBalanceUpdate(balances types.BalanceMap) {
for _, b := range balances {
if b.Available.IsZero() && b.Borrowed.IsZero() {
continue
}
}
}
func (s *Strategy) handleBinanceBalanceUpdateEvent(event *binance.BalanceUpdateEvent) {
qbtrade.Notify(event)
account := s.ExchangeSession.GetAccount()
fmt.Println(account)
delta := event.Delta
// ignore outflow
if delta.Sign() < 0 {
return
}
}
// getBalance 获取账户余额
func (s *Strategy) getBalance(ctx context.Context) (balance types.Balance, ok bool) {
// 更新并获取account信息
account, err := s.ExchangeSession.UpdateAccount(ctx)
if err != nil {
log.WithError(err).Error("unable to update account")
return
}
// 获取balance信息
return account.Balance("USDT")
}