func (self *Kucoin) getMinSize(client *exchange.ApiService, market string) (float64, error) {
	symbol, err := self.getSymbol(client, market)
	if err != nil {
		return 0, err
	}
	out, err := strconv.ParseFloat(symbol.BaseMinSize, 64)
	if err != nil {
		return 0, errors.Wrap(err, 1)
	}
	return out, nil
}
the minimum order quantity requried to place an order.
package exchanges
import (
	"encoding/json"
	"fmt"
	"log"
	"runtime"
	"strconv"
	"strings"
	"time"
	filemutex "github.com/alexflint/go-filemutex"
	"github.com/svanas/nefertiti/aggregation"
	"github.com/svanas/nefertiti/errors"
	"github.com/svanas/nefertiti/flag"
	exchange "github.com/svanas/nefertiti/kucoin"
	"github.com/svanas/nefertiti/model"
	"github.com/svanas/nefertiti/multiplier"
	"github.com/svanas/nefertiti/notify"
	"github.com/svanas/nefertiti/precision"
	"github.com/svanas/nefertiti/pricing"
	"github.com/svanas/nefertiti/session"
	"github.com/svanas/nefertiti/uuid"
)
var (
	kucoinMutex *filemutex.FileMutex
)
const (
	kucoinSessionFile = "kucoin.time"
	kucoinSessionLock = "kucoin.lock"
)
func init() {
	exchange.BeforeRequest = func(client *exchange.ApiService, request *exchange.Request, rps float64) error {
		var err error
		if kucoinMutex == nil {
			if kucoinMutex, err = filemutex.New(session.GetSessionFile(kucoinSessionLock)); err != nil {
				return err
			}
		}
		if err = kucoinMutex.Lock(); err != nil {
			return err
		}
		var lastRequest *time.Time
		if lastRequest, err = session.GetLastRequest(kucoinSessionFile); err != nil {
			return err
		}
		if lastRequest != nil {
			elapsed := time.Since(*lastRequest)
			if elapsed.Seconds() < (float64(1) / rps) {
				sleep := time.Duration((float64(time.Second) / rps)) - elapsed
				if flag.Debug() {
					log.Printf("[DEBUG] sleeping %f seconds", sleep.Seconds())
				}
				time.Sleep(sleep)
			}
		}
		if flag.Debug() {
			log.Printf("[DEBUG] %s %s", request.Method, request.Path)
		}
		return nil
	}
	exchange.AfterRequest = func() {
		defer func() {
			kucoinMutex.Unlock()
		}()
		session.SetLastRequest(kucoinSessionFile, time.Now())
	}
}
const (
	kucoinPartnerID     = "nefertiti"
	kucoinPartnerSecret = "1fac7c63-33d6-4662-801f-4a0900ecbd88"
)
type Kucoin struct {
	*model.ExchangeInfo
	symbols exchange.SymbolsModel
}
func (self *Kucoin) baseURI(sandbox bool) string {
	if sandbox {
		return self.ExchangeInfo.REST.Sandbox
	}
	return self.ExchangeInfo.REST.URI
}
func (self *Kucoin) error(err error, level int64, service model.Notify) {
	pc, file, line, _ := runtime.Caller(1)
	prefix := errors.FormatCaller(pc, file, line)
	msg := fmt.Sprintf("%s %v", prefix, err)
	if strings.Contains(err.Error(), "no such host") || strings.Contains(err.Error(), "network is unreachable") {
		log.Printf("[ERROR] %s", msg)
		return
	}
	_, ok := err.(*errors.Error)
	if ok && flag.Debug() {
		log.Printf("[ERROR] %s", err.(*errors.Error).ErrorStack(prefix, ""))
	} else {
		log.Printf("[ERROR] %s", msg)
	}
	if service != nil {
		if notify.CanSend(level, notify.ERROR) {
			err := service.SendMessage(msg, "Kucoin - ERROR", model.ONCE_PER_MINUTE)
			if err != nil {
				log.Printf("[ERROR] %v", err)
			}
		}
	}
}
func (self *Kucoin) getAvailableBalance(client *exchange.ApiService, curr string) (float64, error) {
	var (
		err      error
		out      float64
		resp     *exchange.ApiResponse
		accounts exchange.AccountsModel
	)
	if resp, err = client.Accounts(curr, "trade"); err != nil {
		return 0, errors.Wrap(err, 1)
	}
	if err = resp.ReadData(&accounts); err != nil {
		return 0, errors.Wrap(err, 1)
	}
	if len(accounts) == 0 {
		return 0, errors.Errorf("currency %s does not exist", curr)
	}
	if out, err = strconv.ParseFloat(accounts[0].Available, 64); err != nil {
		return 0, errors.Wrap(err, 1)
	}
	return out, nil
}
func (self *Kucoin) getSymbol(client *exchange.ApiService, name string) (*exchange.SymbolModel, error) {
	cached := true
	for {
		symbols, err := self.getSymbols(client, cached)
		if err != nil {
			return nil, err
		}
		for _, symbol := range symbols {
			if symbol.Symbol == name {
				return symbol, nil
			}
		}
		if !cached {
			return nil, errors.Errorf("symbol %s does not exist", name)
		}
		cached = false
	}
}
func (self *Kucoin) getSymbols(client *exchange.ApiService, cached bool) (exchange.SymbolsModel, error) {
	if self.symbols == nil || !cached {
		var (
			err     error
			resp    *exchange.ApiResponse
			symbols exchange.SymbolsModel
		)
		if resp, err = client.Symbols(""); err != nil {
			return self.symbols, errors.Wrap(err, 1)
		}
		if err = resp.ReadData(&symbols); err != nil {
			return self.symbols, errors.Wrap(err, 1)
		}
		self.symbols = symbols
	}
	return self.symbols, nil
}