Files
gocryptotrader/exchange.go
Adrian Gallagher c63f1b0ff6 Port from idoall's codebase (#161)
* 修复火币Post REST API方法不正确的问题,同时增加火币海带丝交易所

* add vendor folder

* 修改命名空间依赖

* 第一次提交分支

* 增加取消订单功能

* 修复binance.GetAccount方法

* 更新readme.md

* 增加 Gateio 交易所的支持,支持获取K线、支持的交易对、交易市场参数

* 替换HuobiHadax的参数

* 买/卖订单、取消订单

* OKEX 币币交易:增加获取用户信息,下订单,取消订单

* 测试ok kline

* 修复 Bitfinex 的 GetAccountInfo 方法

* 做一些不必要的删减

* 修复binfinex不返回错误的bug

* 统一我修改交易所的Kline获取方式

* Bitfinex 增加获取最新价格

* update main.go

* 更新GetSymbol方法

* 修改火币和海带丝的Kline编号ID类型

* 修改海带丝的默认配置大小写

* okex增加获取最新价格

*   调整okex的参数判断

* 调整比特儿的参数名称

* 修改火币、火币Hadax的参数全名

* 更新海带丝的配置名称

* 修改bintfinex的GetAccountInfo方法

* 去掉一行注释

* 支持zb交易所的部分功能

* 修复获取K线时没有设置参数的错误

* 增加 Binance 取消订单的方法,获取订单状态,获取所有打开的状态以及所有订单

* 修改获取深度和历史订单的数据

* 修改币安获取深度的参数

* 修改火币获取市场深度的参数

* 修改okex获取市场深度的参数

* 修改币安、OKex获取历史订单的参数

* 修复币安提交参数错误的问题

* merge upstrem

* merge后,调整一部分命名空间

* 修改ZB时间参数的命名方式

* 继续替换命名空间

* 命名空间的替换

* 继续命名空间的替换

* 测试

* Port code from idoall's PR

* Drop errors dep

* Start amending PR

* Fix commented code
* Translate text from Chinese to English (except for ZB). The reasning behind this is that it's a Chinese exchange and the structs are self explanatory in English, but would for other developers in China

* Translate Chinese text, basic formatting changes

* Remove commented lines and address feedback on PR
2018-08-04 08:30:20 +10:00

267 lines
6.7 KiB
Go

package main
import (
"errors"
"log"
"sync"
"github.com/thrasher-/gocryptotrader/common"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/anx"
"github.com/thrasher-/gocryptotrader/exchanges/binance"
"github.com/thrasher-/gocryptotrader/exchanges/bitfinex"
"github.com/thrasher-/gocryptotrader/exchanges/bitflyer"
"github.com/thrasher-/gocryptotrader/exchanges/bithumb"
"github.com/thrasher-/gocryptotrader/exchanges/bitstamp"
"github.com/thrasher-/gocryptotrader/exchanges/bittrex"
"github.com/thrasher-/gocryptotrader/exchanges/btcc"
"github.com/thrasher-/gocryptotrader/exchanges/btcmarkets"
"github.com/thrasher-/gocryptotrader/exchanges/coinbasepro"
"github.com/thrasher-/gocryptotrader/exchanges/coinut"
"github.com/thrasher-/gocryptotrader/exchanges/exmo"
"github.com/thrasher-/gocryptotrader/exchanges/gateio"
"github.com/thrasher-/gocryptotrader/exchanges/gemini"
"github.com/thrasher-/gocryptotrader/exchanges/hitbtc"
"github.com/thrasher-/gocryptotrader/exchanges/huobi"
"github.com/thrasher-/gocryptotrader/exchanges/huobihadax"
"github.com/thrasher-/gocryptotrader/exchanges/itbit"
"github.com/thrasher-/gocryptotrader/exchanges/kraken"
"github.com/thrasher-/gocryptotrader/exchanges/lakebtc"
"github.com/thrasher-/gocryptotrader/exchanges/liqui"
"github.com/thrasher-/gocryptotrader/exchanges/localbitcoins"
"github.com/thrasher-/gocryptotrader/exchanges/okcoin"
"github.com/thrasher-/gocryptotrader/exchanges/okex"
"github.com/thrasher-/gocryptotrader/exchanges/poloniex"
"github.com/thrasher-/gocryptotrader/exchanges/wex"
"github.com/thrasher-/gocryptotrader/exchanges/yobit"
"github.com/thrasher-/gocryptotrader/exchanges/zb"
)
// vars related to exchange functions
var (
ErrNoExchangesLoaded = errors.New("no exchanges have been loaded")
ErrExchangeNotFound = errors.New("exchange not found")
ErrExchangeAlreadyLoaded = errors.New("exchange already loaded")
ErrExchangeFailedToLoad = errors.New("exchange failed to load")
)
// CheckExchangeExists returns true whether or not an exchange has already
// been loaded
func CheckExchangeExists(exchName string) bool {
for x := range bot.exchanges {
if common.StringToLower(bot.exchanges[x].GetName()) == common.StringToLower(exchName) {
return true
}
}
return false
}
// GetExchangeByName returns an exchange given an exchange name
func GetExchangeByName(exchName string) exchange.IBotExchange {
for x := range bot.exchanges {
if common.StringToLower(bot.exchanges[x].GetName()) == common.StringToLower(exchName) {
return bot.exchanges[x]
}
}
return nil
}
// ReloadExchange loads an exchange config by name
func ReloadExchange(name string) error {
nameLower := common.StringToLower(name)
if len(bot.exchanges) == 0 {
return ErrNoExchangesLoaded
}
if !CheckExchangeExists(nameLower) {
return ErrExchangeNotFound
}
exchCfg, err := bot.config.GetExchangeConfig(name)
if err != nil {
return err
}
e := GetExchangeByName(nameLower)
e.Setup(exchCfg)
log.Printf("%s exchange reloaded successfully.\n", name)
return nil
}
// UnloadExchange unloads an exchange by
func UnloadExchange(name string) error {
nameLower := common.StringToLower(name)
if len(bot.exchanges) == 0 {
return ErrNoExchangesLoaded
}
if !CheckExchangeExists(nameLower) {
return ErrExchangeNotFound
}
exchCfg, err := bot.config.GetExchangeConfig(name)
if err != nil {
return err
}
exchCfg.Enabled = false
err = bot.config.UpdateExchangeConfig(exchCfg)
if err != nil {
return err
}
for x := range bot.exchanges {
if bot.exchanges[x].GetName() == name {
bot.exchanges[x].SetEnabled(false)
bot.exchanges = append(bot.exchanges[:x], bot.exchanges[x+1:]...)
return nil
}
}
return ErrExchangeNotFound
}
// LoadExchange loads an exchange by name
func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error {
nameLower := common.StringToLower(name)
var exch exchange.IBotExchange
if len(bot.exchanges) > 0 {
if CheckExchangeExists(nameLower) {
return ErrExchangeAlreadyLoaded
}
}
switch nameLower {
case "anx":
exch = new(anx.ANX)
case "binance":
exch = new(binance.Binance)
case "bitfinex":
exch = new(bitfinex.Bitfinex)
case "bitflyer":
exch = new(bitflyer.Bitflyer)
case "bithumb":
exch = new(bithumb.Bithumb)
case "bitstamp":
exch = new(bitstamp.Bitstamp)
case "bittrex":
exch = new(bittrex.Bittrex)
case "btcc":
exch = new(btcc.BTCC)
case "btc markets":
exch = new(btcmarkets.BTCMarkets)
case "coinut":
exch = new(coinut.COINUT)
case "exmo":
exch = new(exmo.EXMO)
case "coinbasepro":
exch = new(coinbasepro.CoinbasePro)
case "gateio":
exch = new(gateio.Gateio)
case "gemini":
exch = new(gemini.Gemini)
case "hitbtc":
exch = new(hitbtc.HitBTC)
case "huobi":
exch = new(huobi.HUOBI)
case "huobihadax":
exch = new(huobihadax.HUOBIHADAX)
case "itbit":
exch = new(itbit.ItBit)
case "kraken":
exch = new(kraken.Kraken)
case "lakebtc":
exch = new(lakebtc.LakeBTC)
case "liqui":
exch = new(liqui.Liqui)
case "localbitcoins":
exch = new(localbitcoins.LocalBitcoins)
case "okcoin china":
exch = new(okcoin.OKCoin)
case "okcoin international":
exch = new(okcoin.OKCoin)
case "okex":
exch = new(okex.OKEX)
case "poloniex":
exch = new(poloniex.Poloniex)
case "wex":
exch = new(wex.WEX)
case "yobit":
exch = new(yobit.Yobit)
case "zb":
exch = new(zb.ZB)
default:
return ErrExchangeNotFound
}
if exch == nil {
return ErrExchangeFailedToLoad
}
exch.SetDefaults()
bot.exchanges = append(bot.exchanges, exch)
exchCfg, err := bot.config.GetExchangeConfig(name)
if err != nil {
return err
}
exchCfg.Enabled = true
exch.Setup(exchCfg)
if useWG {
exch.Start(wg)
} else {
wg := sync.WaitGroup{}
exch.Start(&wg)
wg.Wait()
}
return nil
}
// SetupExchanges sets up the exchanges used by the bot
func SetupExchanges() {
var wg sync.WaitGroup
for _, exch := range bot.config.Exchanges {
if CheckExchangeExists(exch.Name) {
e := GetExchangeByName(exch.Name)
if e == nil {
log.Println(ErrExchangeNotFound)
continue
}
err := ReloadExchange(exch.Name)
if err != nil {
log.Printf("ReloadExchange %s failed: %s", exch.Name, err)
continue
}
if !e.IsEnabled() {
UnloadExchange(exch.Name)
continue
}
return
}
if !exch.Enabled {
log.Printf("%s: Exchange support: Disabled", exch.Name)
continue
} else {
err := LoadExchange(exch.Name, true, &wg)
if err != nil {
log.Printf("LoadExchange %s failed: %s", exch.Name, err)
continue
}
}
log.Printf(
"%s: Exchange support: Enabled (Authenticated API support: %s - Verbose mode: %s).\n",
exch.Name,
common.IsEnabled(exch.AuthenticatedAPISupport),
common.IsEnabled(exch.Verbose),
)
}
wg.Wait()
}