mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 00:35:15 +00:00
refactor binance exchange factory
This commit is contained in:
parent
0ae851a085
commit
ce89835a7d
|
@ -1,40 +0,0 @@
|
||||||
package bbgo
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
kline
|
|
||||||
|
|
||||||
{
|
|
||||||
"e": "kline", // KLineEvent type
|
|
||||||
"E": 123456789, // KLineEvent time
|
|
||||||
"s": "BNBBTC", // Symbol
|
|
||||||
"k": {
|
|
||||||
"t": 123400000, // Kline start time
|
|
||||||
"T": 123460000, // Kline close time
|
|
||||||
"s": "BNBBTC", // Symbol
|
|
||||||
"i": "1m", // Interval
|
|
||||||
"f": 100, // First trade ID
|
|
||||||
"L": 200, // Last trade ID
|
|
||||||
"o": "0.0010", // Open price
|
|
||||||
"c": "0.0020", // Close price
|
|
||||||
"h": "0.0025", // High price
|
|
||||||
"l": "0.0015", // Low price
|
|
||||||
"v": "1000", // Base asset volume
|
|
||||||
"n": 100, // Number of trades
|
|
||||||
"x": false, // Is this kline closed?
|
|
||||||
"q": "1.0000", // Quote asset volume
|
|
||||||
"V": "500", // Taker buy base asset volume
|
|
||||||
"Q": "0.500", // Taker buy quote asset volume
|
|
||||||
"B": "123456" // Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
type EventBase struct {
|
|
||||||
Event string `json:"e"` // event
|
|
||||||
Time int64 `json:"E"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package bbgo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type KLineEvent struct {
|
|
||||||
EventBase
|
|
||||||
Symbol string `json:"s"`
|
|
||||||
KLine *types.KLine `json:"k,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/adshao/go-binance"
|
"github.com/adshao/go-binance"
|
||||||
"github.com/c9s/bbgo/pkg/bbgo/types"
|
"github.com/c9s/bbgo/pkg/bbgo/types"
|
||||||
|
binance2 "github.com/c9s/bbgo/pkg/exchange/binance"
|
||||||
"github.com/c9s/bbgo/pkg/util"
|
"github.com/c9s/bbgo/pkg/util"
|
||||||
"github.com/slack-go/slack"
|
"github.com/slack-go/slack"
|
||||||
"math"
|
"math"
|
||||||
|
@ -124,7 +125,7 @@ func (d *KLineDetector) String() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *KLineDetector) NewOrder(e *KLineEvent, tradingCtx *TradingContext) *Order {
|
func (d *KLineDetector) NewOrder(e *binance2.KLineEvent, tradingCtx *TradingContext) *Order {
|
||||||
var kline types.KLineOrWindow = e.KLine
|
var kline types.KLineOrWindow = e.KLine
|
||||||
if d.EnableLookBack {
|
if d.EnableLookBack {
|
||||||
klineWindow := tradingCtx.KLineWindows[e.KLine.Interval]
|
klineWindow := tradingCtx.KLineWindows[e.KLine.Interval]
|
||||||
|
@ -151,7 +152,7 @@ func (d *KLineDetector) NewOrder(e *KLineEvent, tradingCtx *TradingContext) *Ord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *KLineDetector) Detect(e *KLineEvent, tradingCtx *TradingContext) (reason string, kline types.KLineOrWindow, ok bool) {
|
func (d *KLineDetector) Detect(e *binance2.KLineEvent, tradingCtx *TradingContext) (reason string, kline types.KLineOrWindow, ok bool) {
|
||||||
kline = e.KLine
|
kline = e.KLine
|
||||||
|
|
||||||
// if the 3m trend is drop, do not buy, let 5m window handle it.
|
// if the 3m trend is drop, do not buy, let 5m window handle it.
|
||||||
|
|
|
@ -1,12 +1,2 @@
|
||||||
package bbgo
|
package bbgo
|
||||||
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
func MustParseFloat(s string) float64 {
|
|
||||||
v, err := strconv.ParseFloat(s, 64)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
package bbgo
|
|
||||||
|
|
17
bbgo/pnl.go
17
bbgo/pnl.go
|
@ -7,23 +7,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CalculateAverageCost(trades []types.Trade) (averageCost float64) {
|
|
||||||
var totalCost = 0.0
|
|
||||||
var totalQuantity = 0.0
|
|
||||||
for _, t := range trades {
|
|
||||||
if t.IsBuyer {
|
|
||||||
totalCost += t.Price * t.Volume
|
|
||||||
totalQuantity += t.Volume
|
|
||||||
} else {
|
|
||||||
totalCost -= t.Price * t.Volume
|
|
||||||
totalQuantity -= t.Volume
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
averageCost = totalCost / totalQuantity
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProfitAndLossCalculator struct {
|
type ProfitAndLossCalculator struct {
|
||||||
Symbol string
|
Symbol string
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/adshao/go-binance"
|
"github.com/adshao/go-binance"
|
||||||
"github.com/c9s/bbgo/pkg/bbgo"
|
"github.com/c9s/bbgo/pkg/bbgo"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
"github.com/c9s/bbgo/pkg/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -14,13 +15,20 @@ type Exchange struct {
|
||||||
Client *binance.Client
|
Client *binance.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewExchange(key, secret string) *Exchange {
|
||||||
|
var client = binance.NewClient(key, secret)
|
||||||
|
return &Exchange{
|
||||||
|
Client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryAveragePrice(ctx context.Context, symbol string) (float64, error) {
|
func (e *Exchange) QueryAveragePrice(ctx context.Context, symbol string) (float64, error) {
|
||||||
resp, err := e.Client.NewAveragePriceService().Symbol(symbol).Do(ctx)
|
resp, err := e.Client.NewAveragePriceService().Symbol(symbol).Do(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return bbgo.MustParseFloat(resp.Price), nil
|
return util.MustParseFloat(resp.Price), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) NewPrivateStream(ctx context.Context) (*PrivateStream, error) {
|
func (e *Exchange) NewPrivateStream(ctx context.Context) (*PrivateStream, error) {
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/c9s/bbgo/pkg/bbgo"
|
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
"github.com/c9s/bbgo/pkg/util"
|
||||||
"github.com/valyala/fastjson"
|
"github.com/valyala/fastjson"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -50,7 +50,7 @@ executionReport
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
type ExecutionReportEvent struct {
|
type ExecutionReportEvent struct {
|
||||||
bbgo.EventBase
|
EventBase
|
||||||
|
|
||||||
Symbol string `json:"s"`
|
Symbol string `json:"s"`
|
||||||
ClientOrderID string `json:"c"`
|
ClientOrderID string `json:"c"`
|
||||||
|
@ -92,12 +92,12 @@ func (e *ExecutionReportEvent) Trade() (*types.Trade, error) {
|
||||||
return &types.Trade{
|
return &types.Trade{
|
||||||
ID: e.TradeID,
|
ID: e.TradeID,
|
||||||
Symbol: e.Symbol,
|
Symbol: e.Symbol,
|
||||||
Price: bbgo.MustParseFloat(e.LastExecutedPrice),
|
Price: util.MustParseFloat(e.LastExecutedPrice),
|
||||||
Volume: bbgo.MustParseFloat(e.LastExecutedQuantity),
|
Volume: util.MustParseFloat(e.LastExecutedQuantity),
|
||||||
IsBuyer: e.Side == "BUY",
|
IsBuyer: e.Side == "BUY",
|
||||||
IsMaker: e.IsMaker,
|
IsMaker: e.IsMaker,
|
||||||
Time: tt,
|
Time: tt,
|
||||||
Fee: bbgo.MustParseFloat(e.CommissionAmount),
|
Fee: util.MustParseFloat(e.CommissionAmount),
|
||||||
FeeCurrency: e.CommissionAsset,
|
FeeCurrency: e.CommissionAsset,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ balanceUpdate
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
type BalanceUpdateEvent struct {
|
type BalanceUpdateEvent struct {
|
||||||
bbgo.EventBase
|
EventBase
|
||||||
|
|
||||||
Asset string `json:"a"`
|
Asset string `json:"a"`
|
||||||
Delta string `json:"d"`
|
Delta string `json:"d"`
|
||||||
|
@ -176,7 +176,7 @@ type Balance struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundAccountInfoEvent struct {
|
type OutboundAccountInfoEvent struct {
|
||||||
bbgo.EventBase
|
EventBase
|
||||||
|
|
||||||
MakerCommissionRate int `json:"m"`
|
MakerCommissionRate int `json:"m"`
|
||||||
TakerCommissionRate int `json:"t"`
|
TakerCommissionRate int `json:"t"`
|
||||||
|
@ -208,7 +208,7 @@ func ParseEvent(message string) (interface{}, error) {
|
||||||
|
|
||||||
switch eventType {
|
switch eventType {
|
||||||
case "kline":
|
case "kline":
|
||||||
var event bbgo.KLineEvent
|
var event KLineEvent
|
||||||
err := json.Unmarshal([]byte(message), &event)
|
err := json.Unmarshal([]byte(message), &event)
|
||||||
return &event, err
|
return &event, err
|
||||||
|
|
||||||
|
@ -236,3 +236,48 @@ func ParseEvent(message string) (interface{}, error) {
|
||||||
|
|
||||||
return nil, fmt.Errorf("unsupported message: %s", message)
|
return nil, fmt.Errorf("unsupported message: %s", message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KLineEvent struct {
|
||||||
|
EventBase
|
||||||
|
Symbol string `json:"s"`
|
||||||
|
KLine *types.KLine `json:"k,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
kline
|
||||||
|
|
||||||
|
{
|
||||||
|
"e": "kline", // KLineEvent type
|
||||||
|
"E": 123456789, // KLineEvent time
|
||||||
|
"s": "BNBBTC", // Symbol
|
||||||
|
"k": {
|
||||||
|
"t": 123400000, // Kline start time
|
||||||
|
"T": 123460000, // Kline close time
|
||||||
|
"s": "BNBBTC", // Symbol
|
||||||
|
"i": "1m", // Interval
|
||||||
|
"f": 100, // First trade ID
|
||||||
|
"L": 200, // Last trade ID
|
||||||
|
"o": "0.0010", // Open price
|
||||||
|
"c": "0.0020", // Close price
|
||||||
|
"h": "0.0025", // High price
|
||||||
|
"l": "0.0015", // Low price
|
||||||
|
"v": "1000", // Base asset volume
|
||||||
|
"n": 100, // Number of trades
|
||||||
|
"x": false, // Is this kline closed?
|
||||||
|
"q": "1.0000", // Quote asset volume
|
||||||
|
"V": "500", // Taker buy base asset volume
|
||||||
|
"Q": "0.500", // Taker buy quote asset volume
|
||||||
|
"B": "123456" // Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
type EventBase struct {
|
||||||
|
Event string `json:"e"` // event
|
||||||
|
Time int64 `json:"E"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,19 +59,19 @@ func (k KLine) GetTrend() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KLine) GetHigh() float64 {
|
func (k KLine) GetHigh() float64 {
|
||||||
return bbgo.MustParseFloat(k.High)
|
return util.MustParseFloat(k.High)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KLine) GetLow() float64 {
|
func (k KLine) GetLow() float64 {
|
||||||
return bbgo.MustParseFloat(k.Low)
|
return util.MustParseFloat(k.Low)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KLine) GetOpen() float64 {
|
func (k KLine) GetOpen() float64 {
|
||||||
return bbgo.MustParseFloat(k.Open)
|
return util.MustParseFloat(k.Open)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KLine) GetClose() float64 {
|
func (k KLine) GetClose() float64 {
|
||||||
return bbgo.MustParseFloat(k.Close)
|
return util.MustParseFloat(k.Close)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KLine) GetMaxChange() float64 {
|
func (k KLine) GetMaxChange() float64 {
|
||||||
|
|
|
@ -20,3 +20,12 @@ func Pow10(n int64) int64 {
|
||||||
func FormatFloat(val float64, prec int) string {
|
func FormatFloat(val float64, prec int) string {
|
||||||
return strconv.FormatFloat(val, 'f', prec, 64)
|
return strconv.FormatFloat(val, 'f', prec, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MustParseFloat(s string) float64 {
|
||||||
|
v, err := strconv.ParseFloat(s, 64)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user