fix: gosimple alert

This commit is contained in:
zenix 2022-06-17 20:19:51 +09:00
parent f25f2f076f
commit a5ffca7fe8
32 changed files with 74 additions and 106 deletions

2
.gitignore vendored
View File

@ -42,6 +42,8 @@ otp*png
/.deploy /.deploy
testoutput
*.swp *.swp
/pkg/backtest/assets.go /pkg/backtest/assets.go

View File

@ -5,3 +5,4 @@ linters:
disable-all: true disable-all: true
enable: enable:
- gofmt - gofmt
- gosimple

View File

@ -11,10 +11,6 @@ import (
"github.com/c9s/bbgo/pkg/types" "github.com/c9s/bbgo/pkg/types"
) )
func zero(a float64) bool {
return int(math.Round(a*1e8)) == 0
}
type Stock types.Trade type Stock types.Trade
func (stock *Stock) String() string { func (stock *Stock) String() string {

View File

@ -237,7 +237,6 @@ func (m *SimplePriceMatching) executeTrade(trade types.Trade) {
m.EmitTradeUpdate(trade) m.EmitTradeUpdate(trade)
m.EmitBalanceUpdate(m.Account.Balances()) m.EmitBalanceUpdate(m.Account.Balances())
return
} }
func (m *SimplePriceMatching) newTradeFromOrder(order *types.Order, isMaker bool) types.Trade { func (m *SimplePriceMatching) newTradeFromOrder(order *types.Order, isMaker bool) types.Trade {

View File

@ -859,7 +859,7 @@ func getAuthStoreID() string {
} }
func (environ *Environment) setupInteraction(persistence service.PersistenceService) error { func (environ *Environment) setupInteraction(persistence service.PersistenceService) error {
var otpQRCodeImagePath = fmt.Sprintf("otp.png") var otpQRCodeImagePath = "otp.png"
var key *otp.Key var key *otp.Key
var keyURL string var keyURL string
var authStore = environ.getAuthStore(persistence) var authStore = environ.getAuthStore(persistence)

View File

@ -144,9 +144,8 @@ func (trader *Trader) AttachStrategyOn(session string, strategies ...SingleExcha
return fmt.Errorf("session %s is not defined, valid sessions are: %v", session, keys) return fmt.Errorf("session %s is not defined, valid sessions are: %v", session, keys)
} }
for _, s := range strategies { trader.exchangeStrategies[session] = append(
trader.exchangeStrategies[session] = append(trader.exchangeStrategies[session], s) trader.exchangeStrategies[session], strategies...)
}
return nil return nil
} }

View File

@ -84,10 +84,7 @@ type Data struct {
} }
func (s Response) IsEmpty() bool { func (s Response) IsEmpty() bool {
if len(s) == 0 { return len(s) == 0
return true
}
return false
} }
func (s Response) First() Data { func (s Response) First() Data {
@ -120,8 +117,5 @@ func (s Response) LastOptions() map[string]float64 {
} }
func (s Response) HasOptions() bool { func (s Response) HasOptions() bool {
if len(s.First().Options) == 0 { return len(s.First().Options) != 0
return false
}
return true
} }

View File

@ -82,7 +82,7 @@ func (d *datetime) UnmarshalJSON(b []byte) error {
} }
} }
*/ */
type accountResponse struct { type accountResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result account `json:"result"` Result account `json:"result"`
} }
@ -93,7 +93,7 @@ type account struct {
TotalAccountValue fixedpoint.Value `json:"totalAccountValue"` TotalAccountValue fixedpoint.Value `json:"totalAccountValue"`
} }
type positionsResponse struct { type positionsResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result []position `json:"result"` Result []position `json:"result"`
} }
@ -135,7 +135,7 @@ type position struct {
CollateralUsed fixedpoint.Value `json:"collateralUsed"` CollateralUsed fixedpoint.Value `json:"collateralUsed"`
} }
type balances struct { type balances struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result []struct { Result []struct {
@ -172,7 +172,7 @@ type balances struct {
} }
] ]
*/ */
type marketsResponse struct { type marketsResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result []market `json:"result"` Result []market `json:"result"`
} }
@ -230,19 +230,19 @@ type Candle struct {
Volume fixedpoint.Value `json:"volume"` Volume fixedpoint.Value `json:"volume"`
} }
type ordersHistoryResponse struct { type ordersHistoryResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result []order `json:"result"` Result []order `json:"result"`
HasMoreData bool `json:"hasMoreData"` HasMoreData bool `json:"hasMoreData"`
} }
type ordersResponse struct { type ordersResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result []order `json:"result"` Result []order `json:"result"`
} }
type cancelOrderResponse struct { type cancelOrderResponse struct { // nolint:golint,deadcode
Success bool `json:"success"` Success bool `json:"success"`
Result string `json:"result"` Result string `json:"result"`
} }

View File

@ -133,16 +133,16 @@ type PrivateRequestParams struct {
type GetPrivateTradesRequest struct { type GetPrivateTradesRequest struct {
client requestgen.AuthenticatedAPIClient client requestgen.AuthenticatedAPIClient
market string `param:"market"` market string `param:"market"` // nolint:golint,structcheck
// timestamp is the seconds elapsed since Unix epoch, set to return trades executed before the time only // timestamp is the seconds elapsed since Unix epoch, set to return trades executed before the time only
timestamp *time.Time `param:"timestamp,seconds"` timestamp *time.Time `param:"timestamp,seconds"` // nolint:golint,structcheck
// From field is a trade id, set ot return trades created after the trade // From field is a trade id, set ot return trades created after the trade
from *int64 `param:"from"` from *int64 `param:"from"` // nolint:golint,structcheck
// To field trade id, set to return trades created before the trade // To field trade id, set to return trades created before the trade
to *int64 `param:"to"` to *int64 `param:"to"` // nolint:golint,structcheck
orderBy *string `param:"order_by"` orderBy *string `param:"order_by"`

View File

@ -272,7 +272,7 @@ func toGlobalOrderType(orderType okexapi.OrderType) (types.OrderType, error) {
} }
func toLocalInterval(src string) string { func toLocalInterval(src string) string {
var re = regexp.MustCompile("\\d+[hdw]") var re = regexp.MustCompile(`\d+[hdw]`)
return re.ReplaceAllStringFunc(src, func(w string) string { return re.ReplaceAllStringFunc(src, func(w string) string {
return strings.ToUpper(w) return strings.ToUpper(w)
}) })

View File

@ -231,7 +231,7 @@ func (v Value) MarshalJSON() ([]byte, error) {
} }
func (v *Value) UnmarshalJSON(data []byte) error { func (v *Value) UnmarshalJSON(data []byte) error {
if bytes.Compare(data, []byte{'n', 'u', 'l', 'l'}) == 0 { if bytes.Equal(data, []byte{'n', 'u', 'l', 'l'}) {
*v = Zero *v = Zero
return nil return nil
} }

View File

@ -16,7 +16,7 @@ func BenchmarkMul(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x := NewFromFloat(20.0) x := NewFromFloat(20.0)
y := NewFromFloat(20.0) y := NewFromFloat(20.0)
x = x.Mul(y) x = x.Mul(y) // nolint
} }
}) })
@ -24,7 +24,7 @@ func BenchmarkMul(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x := NewFromFloat(88.12345678) x := NewFromFloat(88.12345678)
y := NewFromFloat(88.12345678) y := NewFromFloat(88.12345678)
x = x.Mul(y) x = x.Mul(y) // nolint
} }
}) })
@ -32,7 +32,7 @@ func BenchmarkMul(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x := big.NewFloat(20.0) x := big.NewFloat(20.0)
y := big.NewFloat(20.0) y := big.NewFloat(20.0)
x = new(big.Float).Mul(x, y) x = new(big.Float).Mul(x, y) // nolint
} }
}) })
@ -40,7 +40,7 @@ func BenchmarkMul(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x := big.NewFloat(88.12345678) x := big.NewFloat(88.12345678)
y := big.NewFloat(88.12345678) y := big.NewFloat(88.12345678)
x = new(big.Float).Mul(x, y) x = new(big.Float).Mul(x, y) // nolint
} }
}) })
} }
@ -170,8 +170,7 @@ func TestJson(t *testing.T) {
_ = json.Unmarshal([]byte("0.00153917575"), &p) _ = json.Unmarshal([]byte("0.00153917575"), &p)
assert.Equal(t, "0.00153917", p.FormatString(8)) assert.Equal(t, "0.00153917", p.FormatString(8))
var q Value q := NewFromFloat(0.00153917575)
q = NewFromFloat(0.00153917575)
assert.Equal(t, p, q) assert.Equal(t, p, q)
_ = json.Unmarshal([]byte("6e-8"), &p) _ = json.Unmarshal([]byte("6e-8"), &p)
_ = json.Unmarshal([]byte("0.000062"), &q) _ = json.Unmarshal([]byte("0.000062"), &q)

View File

@ -46,8 +46,6 @@ type Interact struct {
states map[State]State states map[State]State
statesFunc map[State]interface{} statesFunc map[State]interface{}
authenticatedSessions map[string]Session
customInteractions []CustomInteraction customInteractions []CustomInteraction
messengers []Messenger messengers []Messenger
@ -97,10 +95,6 @@ func (it *Interact) getNextState(session Session, currentState State) (nextState
return session.GetOriginState(), final return session.GetOriginState(), final
} }
func (it *Interact) handleCallback(session Session, payload string) error {
return nil
}
func (it *Interact) handleResponse(session Session, text string, ctxObjects ...interface{}) error { func (it *Interact) handleResponse(session Session, text string, ctxObjects ...interface{}) error {
// We only need response when executing a command // We only need response when executing a command
switch session.GetState() { switch session.GetState() {

View File

@ -104,8 +104,6 @@ type Telegram struct {
// Private is used to protect the telegram bot, users not authenticated can not see messages or sending commands // Private is used to protect the telegram bot, users not authenticated can not see messages or sending commands
Private bool `json:"private,omitempty"` Private bool `json:"private,omitempty"`
authorizing bool
sessions TelegramSessionMap sessions TelegramSessionMap
// textMessageResponder is used for interact to register its message handler // textMessageResponder is used for interact to register its message handler
@ -237,7 +235,7 @@ func (tm *Telegram) Sessions() TelegramSessionMap {
} }
func (tm *Telegram) RestoreSessions(sessions TelegramSessionMap) { func (tm *Telegram) RestoreSessions(sessions TelegramSessionMap) {
if sessions == nil || len(sessions) == 0 { if len(sessions) == 0 {
return return
} }

View File

@ -597,7 +597,6 @@ func (s *Server) tradingVolume(c *gin.Context) {
} }
c.JSON(http.StatusOK, gin.H{"tradingVolumes": rows}) c.JSON(http.StatusOK, gin.H{"tradingVolumes": rows})
return
} }
func newServer(r http.Handler, bind string) *http.Server { func newServer(r http.Handler, bind string) *http.Server {

View File

@ -226,7 +226,7 @@ func (s *BacktestService) QueryKLinesCh(since, until time.Time, exchange types.E
} }
func returnError(err error) (chan types.KLine, chan error) { func returnError(err error) (chan types.KLine, chan error) {
ch := make(chan types.KLine, 0) ch := make(chan types.KLine)
close(ch) close(ch)
log.WithError(err).Error("backtest query error") log.WithError(err).Error("backtest query error")

View File

@ -47,11 +47,7 @@ func (s *DepositService) Sync(ctx context.Context, ex types.Exchange, startTime
}, },
Filter: func(obj interface{}) bool { Filter: func(obj interface{}) bool {
deposit := obj.(types.Deposit) deposit := obj.(types.Deposit)
if len(deposit.TransactionID) == 0 { return len(deposit.TransactionID) != 0
return false
}
return true
}, },
LogInsert: true, LogInsert: true,
}, },

View File

@ -40,7 +40,7 @@ func (t *LogHook) Fire(e *logrus.Entry) error {
return nil return nil
} }
var color = "" var color string
switch e.Level { switch e.Level {
case logrus.DebugLevel: case logrus.DebugLevel:

View File

@ -431,7 +431,7 @@ func (s *Strategy) validateOrder(order *types.SubmitOrder) error {
order.Quantity.Compare(s.Market.MinQuantity) < 0 || order.Quantity.Compare(s.Market.MinQuantity) < 0 ||
orderAmount.Compare(s.Market.MinNotional) < 0 { orderAmount.Compare(s.Market.MinNotional) < 0 {
log.Debug("amount fail") log.Debug("amount fail")
return errors.New(fmt.Sprintf("amount fail: quantity: %v, amount: %v", order.Quantity, orderAmount)) return fmt.Errorf("amount fail: quantity: %v, amount: %v", order.Quantity, orderAmount)
} }
return nil return nil
} else if order.Side == types.SideTypeBuy { } else if order.Side == types.SideTypeBuy {
@ -458,7 +458,7 @@ func (s *Strategy) validateOrder(order *types.SubmitOrder) error {
orderAmount.Compare(s.Market.MinNotional) < 0 || orderAmount.Compare(s.Market.MinNotional) < 0 ||
order.Quantity.Compare(s.Market.MinQuantity) < 0 { order.Quantity.Compare(s.Market.MinQuantity) < 0 {
log.Debug("amount fail") log.Debug("amount fail")
return errors.New(fmt.Sprintf("amount fail: quantity: %v, amount: %v", order.Quantity, orderAmount)) return fmt.Errorf("amount fail: quantity: %v, amount: %v", order.Quantity, orderAmount)
} }
return nil return nil
} }
@ -801,7 +801,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
store, ok := s.Session.MarketDataStore(s.Symbol) store, ok := s.Session.MarketDataStore(s.Symbol)
if !ok { if !ok {
return errors.New(fmt.Sprintf("cannot get marketdatastore of %s", s.Symbol)) return fmt.Errorf("cannot get marketdatastore of %s", s.Symbol)
} }
s.SetupIndicators(store) s.SetupIndicators(store)
@ -893,27 +893,22 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
percentAvgTPfromCCI = percentAvgTPfromCCI*float64(counterTPfromCCI) + pnlRate percentAvgTPfromCCI = percentAvgTPfromCCI*float64(counterTPfromCCI) + pnlRate
counterTPfromCCI += 1 counterTPfromCCI += 1
percentAvgTPfromCCI /= float64(counterTPfromCCI) percentAvgTPfromCCI /= float64(counterTPfromCCI)
break
case 1: case 1:
percentAvgTPfromLongShort = percentAvgTPfromLongShort*float64(counterTPfromLongShort) + pnlRate percentAvgTPfromLongShort = percentAvgTPfromLongShort*float64(counterTPfromLongShort) + pnlRate
counterTPfromLongShort += 1 counterTPfromLongShort += 1
percentAvgTPfromLongShort /= float64(counterTPfromLongShort) percentAvgTPfromLongShort /= float64(counterTPfromLongShort)
break
case 2: case 2:
percentAvgTPfromAtr = percentAvgTPfromAtr*float64(counterTPfromAtr) + pnlRate percentAvgTPfromAtr = percentAvgTPfromAtr*float64(counterTPfromAtr) + pnlRate
counterTPfromAtr += 1 counterTPfromAtr += 1
percentAvgTPfromAtr /= float64(counterTPfromAtr) percentAvgTPfromAtr /= float64(counterTPfromAtr)
break
case 3: case 3:
percentAvgTPfromPeak = percentAvgTPfromPeak*float64(counterTPfromPeak) + pnlRate percentAvgTPfromPeak = percentAvgTPfromPeak*float64(counterTPfromPeak) + pnlRate
counterTPfromPeak += 1 counterTPfromPeak += 1
percentAvgTPfromPeak /= float64(counterTPfromPeak) percentAvgTPfromPeak /= float64(counterTPfromPeak)
break
case 4: case 4:
percentAvgSLfromSL = percentAvgSLfromSL*float64(counterSLfromSL) + pnlRate percentAvgSLfromSL = percentAvgSLfromSL*float64(counterSLfromSL) + pnlRate
counterSLfromSL += 1 counterSLfromSL += 1
percentAvgSLfromSL /= float64(counterSLfromSL) percentAvgSLfromSL /= float64(counterSLfromSL)
break
} }
} }
@ -1002,27 +997,22 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
percentAvgTPfromCCI = percentAvgTPfromCCI*float64(counterTPfromCCI) + pnlRate percentAvgTPfromCCI = percentAvgTPfromCCI*float64(counterTPfromCCI) + pnlRate
counterTPfromCCI += 1 counterTPfromCCI += 1
percentAvgTPfromCCI /= float64(counterTPfromCCI) percentAvgTPfromCCI /= float64(counterTPfromCCI)
break
case 1: case 1:
percentAvgTPfromLongShort = percentAvgTPfromLongShort*float64(counterTPfromLongShort) + pnlRate percentAvgTPfromLongShort = percentAvgTPfromLongShort*float64(counterTPfromLongShort) + pnlRate
counterTPfromLongShort += 1 counterTPfromLongShort += 1
percentAvgTPfromLongShort /= float64(counterTPfromLongShort) percentAvgTPfromLongShort /= float64(counterTPfromLongShort)
break
case 2: case 2:
percentAvgTPfromAtr = percentAvgTPfromAtr*float64(counterTPfromAtr) + pnlRate percentAvgTPfromAtr = percentAvgTPfromAtr*float64(counterTPfromAtr) + pnlRate
counterTPfromAtr += 1 counterTPfromAtr += 1
percentAvgTPfromAtr /= float64(counterTPfromAtr) percentAvgTPfromAtr /= float64(counterTPfromAtr)
break
case 3: case 3:
percentAvgTPfromPeak = percentAvgTPfromPeak*float64(counterTPfromPeak) + pnlRate percentAvgTPfromPeak = percentAvgTPfromPeak*float64(counterTPfromPeak) + pnlRate
counterTPfromPeak += 1 counterTPfromPeak += 1
percentAvgTPfromPeak /= float64(counterTPfromPeak) percentAvgTPfromPeak /= float64(counterTPfromPeak)
break
case 4: case 4:
percentAvgSLfromSL = percentAvgSLfromSL*float64(counterSLfromSL) + pnlRate percentAvgSLfromSL = percentAvgSLfromSL*float64(counterSLfromSL) + pnlRate
counterSLfromSL += 1 counterSLfromSL += 1
percentAvgSLfromSL /= float64(counterSLfromSL) percentAvgSLfromSL /= float64(counterSLfromSL)
break
} }
} }
} }

View File

@ -550,8 +550,8 @@ func (s *Strategy) placeBounceSellOrders(ctx context.Context, resistancePrice fi
for i := 0; i < numLayers; i++ { for i := 0; i < numLayers; i++ {
balances := s.session.GetAccount().Balances() balances := s.session.GetAccount().Balances()
quoteBalance, _ := balances[s.Market.QuoteCurrency] quoteBalance := balances[s.Market.QuoteCurrency]
baseBalance, _ := balances[s.Market.BaseCurrency] baseBalance := balances[s.Market.BaseCurrency]
// price = (resistance_price * (1.0 - ratio)) * ((1.0 + layerSpread) * i) // price = (resistance_price * (1.0 - ratio)) * ((1.0 + layerSpread) * i)
price := resistancePrice.Mul(fixedpoint.One.Sub(s.BounceShort.Ratio)) price := resistancePrice.Mul(fixedpoint.One.Sub(s.BounceShort.Ratio))

View File

@ -36,7 +36,7 @@ type State struct {
} }
func (s *State) IsOver24Hours() bool { func (s *State) IsOver24Hours() bool {
return time.Now().Sub(time.Unix(s.Since, 0)) >= 24*time.Hour return time.Since(time.Unix(s.Since, 0)) >= 24*time.Hour
} }
func (s *State) PlainText() string { func (s *State) PlainText() string {

View File

@ -42,7 +42,7 @@ type State struct {
} }
func (s *State) IsOver24Hours() bool { func (s *State) IsOver24Hours() bool {
return time.Now().Sub(s.AccumulatedFeeStartedAt) >= 24*time.Hour return time.Since(s.AccumulatedFeeStartedAt) >= 24*time.Hour
} }
func (s *State) Reset() { func (s *State) Reset() {

View File

@ -113,7 +113,7 @@ func (s *Strategy) update(orderExecutor bbgo.OrderExecutor, session *bbgo.Exchan
func (s *Strategy) updateOrders(orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession, side types.SideType) { func (s *Strategy) updateOrders(orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession, side types.SideType) {
var book = s.book.Copy() var book = s.book.Copy()
var pvs = book.SideBook(side) var pvs = book.SideBook(side)
if pvs == nil || len(pvs) == 0 { if len(pvs) == 0 {
log.Warnf("empty side: %s", side) log.Warnf("empty side: %s", side)
return return
} }

View File

@ -123,7 +123,7 @@ func (m AssetMap) SlackAttachment() slack.Attachment {
Short: false, Short: false,
}) })
} else { } else {
text := fmt.Sprintf("%s", a.NetAsset.String()) text := a.NetAsset.String()
if !a.Borrowed.IsZero() { if !a.Borrowed.IsZero() {
text += fmt.Sprintf(" Borrowed: %s", a.Borrowed.String()) text += fmt.Sprintf(" Borrowed: %s", a.Borrowed.String())

View File

@ -50,7 +50,7 @@ func (b Balance) Net() fixedpoint.Value {
} }
func (b Balance) ValueString() (o string) { func (b Balance) ValueString() (o string) {
o = fmt.Sprintf("%s", b.Available.String()) o = b.Available.String()
if b.Locked.Sign() > 0 { if b.Locked.Sign() > 0 {
o += fmt.Sprintf(" (locked %v)", b.Locked) o += fmt.Sprintf(" (locked %v)", b.Locked)

View File

@ -135,8 +135,8 @@ func Predict(a Series, lookback int, offset ...int) float64 {
if a.Length() < lookback { if a.Length() < lookback {
lookback = a.Length() lookback = a.Length()
} }
x := make([]float64, lookback, lookback) x := make([]float64, lookback)
y := make([]float64, lookback, lookback) y := make([]float64, lookback)
var weights []float64 var weights []float64
for i := 0; i < lookback; i++ { for i := 0; i < lookback; i++ {
x[i] = float64(i) x[i] = float64(i)
@ -163,9 +163,9 @@ func NextCross(a Series, b Series, lookback int) (int, float64, bool) {
if b.Length() < lookback { if b.Length() < lookback {
lookback = b.Length() lookback = b.Length()
} }
x := make([]float64, lookback, lookback) x := make([]float64, lookback)
y1 := make([]float64, lookback, lookback) y1 := make([]float64, lookback)
y2 := make([]float64, lookback, lookback) y2 := make([]float64, lookback)
var weights []float64 var weights []float64
for i := 0; i < lookback; i++ { for i := 0; i < lookback; i++ {
x[i] = float64(i) x[i] = float64(i)
@ -295,20 +295,20 @@ func Add(a interface{}, b interface{}) Series {
var aa Series var aa Series
var bb Series var bb Series
switch a.(type) { switch tp := a.(type) {
case float64: case float64:
aa = NumberSeries(a.(float64)) aa = NumberSeries(tp)
case Series: case Series:
aa = a.(Series) aa = tp
default: default:
panic("input should be either *Series or float64") panic("input should be either *Series or float64")
} }
switch b.(type) { switch tp := b.(type) {
case float64: case float64:
bb = NumberSeries(b.(float64)) bb = NumberSeries(tp)
case Series: case Series:
bb = b.(Series) bb = tp
default: default:
panic("input should be either *Series or float64") panic("input should be either *Series or float64")
@ -367,19 +367,19 @@ func (a *MinusSeriesResult) Length() int {
var _ Series = &MinusSeriesResult{} var _ Series = &MinusSeriesResult{}
func switchIface(b interface{}) Series { func switchIface(b interface{}) Series {
switch b.(type) { switch tp := b.(type) {
case float64: case float64:
return NumberSeries(b.(float64)) return NumberSeries(tp)
case int32: case int32:
return NumberSeries(float64(b.(int32))) return NumberSeries(float64(tp))
case int64: case int64:
return NumberSeries(float64(b.(int64))) return NumberSeries(float64(tp))
case float32: case float32:
return NumberSeries(float64(b.(float32))) return NumberSeries(float64(tp))
case int: case int:
return NumberSeries(float64(b.(int))) return NumberSeries(float64(tp))
case Series: case Series:
return b.(Series) return tp
default: default:
fmt.Println(reflect.TypeOf(b)) fmt.Println(reflect.TypeOf(b))
panic("input should be either *Series or float64") panic("input should be either *Series or float64")
@ -427,19 +427,19 @@ func Mul(a interface{}, b interface{}) Series {
var aa Series var aa Series
var bb Series var bb Series
switch a.(type) { switch tp := a.(type) {
case float64: case float64:
aa = NumberSeries(a.(float64)) aa = NumberSeries(tp)
case Series: case Series:
aa = a.(Series) aa = tp
default: default:
panic("input should be either Series or float64") panic("input should be either Series or float64")
} }
switch b.(type) { switch tp := b.(type) {
case float64: case float64:
bb = NumberSeries(b.(float64)) bb = NumberSeries(tp)
case Series: case Series:
bb = b.(Series) bb = tp
default: default:
panic("input should be either Series or float64") panic("input should be either Series or float64")
@ -490,7 +490,7 @@ func ToArray(a Series, limit ...int) (result []float64) {
if l < a.Length() { if l < a.Length() {
l = a.Length() l = a.Length()
} }
result = make([]float64, l, l) result = make([]float64, l)
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
result[i] = a.Index(i) result[i] = a.Index(i)
} }
@ -510,7 +510,7 @@ func ToReverseArray(a Series, limit ...int) (result Float64Slice) {
if l < a.Length() { if l < a.Length() {
l = a.Length() l = a.Length()
} }
result = make([]float64, l, l) result = make([]float64, l)
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
result[l-i-1] = a.Index(i) result[l-i-1] = a.Index(i)
} }

View File

@ -563,6 +563,8 @@ type KLineSeries struct {
func (k *KLineSeries) Last() float64 { func (k *KLineSeries) Last() float64 {
length := len(*k.lines) length := len(*k.lines)
switch k.kv { switch k.kv {
case kOpUnknown:
panic("kline series operator unknown")
case kOpenValue: case kOpenValue:
return (*k.lines)[length-1].GetOpen().Float64() return (*k.lines)[length-1].GetOpen().Float64()
case kCloseValue: case kCloseValue:

View File

@ -38,13 +38,13 @@ func (slice PriceVolumeSlice) CopyDepth(depth int) PriceVolumeSlice {
return slice.Copy() return slice.Copy()
} }
var s = make(PriceVolumeSlice, depth, depth) var s = make(PriceVolumeSlice, depth)
copy(s, slice[:depth]) copy(s, slice[:depth])
return s return s
} }
func (slice PriceVolumeSlice) Copy() PriceVolumeSlice { func (slice PriceVolumeSlice) Copy() PriceVolumeSlice {
var s = make(PriceVolumeSlice, len(slice), len(slice)) var s = make(PriceVolumeSlice, len(slice))
copy(s, slice) copy(s, slice)
return s return s
} }

View File

@ -153,7 +153,7 @@ func (b *SliceOrderBook) Update(book SliceOrderBook) {
} }
func (b *SliceOrderBook) Print() { func (b *SliceOrderBook) Print() {
fmt.Printf(b.String()) fmt.Print(b.String())
} }
func (b *SliceOrderBook) String() string { func (b *SliceOrderBook) String() string {

View File

@ -115,8 +115,7 @@ func (t *MillisecondTimestamp) UnmarshalJSON(data []byte) error {
} }
// fallback to RFC3339 // Unreachable
return (*time.Time)(t).UnmarshalJSON(data)
} }
func convertFloat64ToTime(vt string, f float64) (time.Time, error) { func convertFloat64ToTime(vt string, f float64) (time.Time, error) {

View File

@ -27,7 +27,7 @@ type TradeSlice struct {
func (s *TradeSlice) Copy() []Trade { func (s *TradeSlice) Copy() []Trade {
s.mu.Lock() s.mu.Lock()
slice := make([]Trade, len(s.Trades), len(s.Trades)) slice := make([]Trade, len(s.Trades))
copy(slice, s.Trades) copy(slice, s.Trades)
s.mu.Unlock() s.mu.Unlock()

View File

@ -19,7 +19,7 @@ func StartTimeProfile(args ...string) TimeProfile {
} }
func (p *TimeProfile) TilNow() time.Duration { func (p *TimeProfile) TilNow() time.Duration {
return time.Now().Sub(p.StartTime) return time.Since(p.StartTime)
} }
func (p *TimeProfile) Stop() time.Duration { func (p *TimeProfile) Stop() time.Duration {