Add base files for various cryptocurrency exchanges.

This commit is contained in:
Adrian Gallagher
2014-10-29 23:27:55 +11:00
parent 76998876df
commit 0e37811cd0
7 changed files with 1343 additions and 0 deletions

331
bitfinexhttp.go Normal file
View File

@@ -0,0 +1,331 @@
package main
import (
"net/http"
"io/ioutil"
"fmt"
"encoding/json"
"encoding/hex"
"crypto/hmac"
"crypto/sha512"
"encoding/base64"
"errors"
"strings"
"strconv"
"time"
)
const (
BITFINEX_API_URL = "https://api.bitfinex.com/v1/"
BITFINEX_TICKER = "pubticker/"
BITFINEX_STATS = "stats/"
BITFINEX_ORDERBOOK = "book/"
BITFINEX_TRADES = "trades/"
BITFINEX_SYMBOLS = "symbols/"
BITFINEX_SYMBOLS_DETAILS = "symbols_details/"
BITFINEX_DEPOSIT = "deposit/new"
BITFINEX_ORDER_NEW = "order/new"
BITFINEX_ORDER_CANCEL = "order/cancel"
BITFINEX_ORDER_CANCEL_ALL = "order/cancel/all"
BITFINEX_ORDER_STATUS = "order/status"
BITFINEX_ORDERS = "orders"
BITFINEX_POSITIONS = "positions"
BITFINEX_CLAIM_POSITION = "position/claim"
BITFINEX_HISTORY = "history"
BITFINEX_TRADE_HISTORY = "mytrades"
)
type BitfinexStats struct {
Period int64
Volume string
}
type BitfinexTicker struct {
Mid, Bid, Ask, Last_price, Low, High, Volume, Timestamp string
}
type BookStructure struct {
Price, Amount, Timestamp string
}
type BitfinexOrderbook struct {
Bids []BookStructure
Asks []BookStructure
}
type TradeStructure struct {
Timestamp, Tid int64
Price, Amount, Exchange, Type string
}
type SymbolsDetails struct {
Pair, Initial_margin, Minimum_margin, Maximum_order_size, Minimum_order_size, Expiration string
Price_precision int
}
type Bitfinex struct {
APIKey, APISecret string
Ticker BitfinexTicker
Stats []BitfinexStats
Orderbook BitfinexOrderbook
Trades []TradeStructure
SymbolsDetails []SymbolsDetails
}
func (b *Bitfinex) SendAuthenticatedHTTPRequest(path string, params map[string]interface{}) (err error) {
request := make(map[string]interface{})
request["request"] = "/v1/" + path
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)
if params != nil {
for key, value:= range params {
request[key] = value
}
}
PayloadJson, err := json.Marshal(request)
fmt.Printf("Request JSON: %s\n", PayloadJson)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}
PayloadBase64 := base64.StdEncoding.EncodeToString(PayloadJson)
fmt.Printf("Base64: %s\n", PayloadBase64)
hmac := hmac.New(sha512.New384, []byte(b.APISecret))
hmac.Write([]byte(PayloadBase64))
signature := hex.EncodeToString(hmac.Sum(nil))
method := "GET"
if strings.Contains(path, BITFINEX_ORDER_CANCEL_ALL) {
method = "POST"
}
req, err := http.NewRequest(method, BITFINEX_API_URL + path, strings.NewReader(""))
req.Header.Set("X-BFX-APIKEY", string(b.APIKey))
req.Header.Set("X-BFX-PAYLOAD", PayloadBase64)
req.Header.Set("X-BFX-SIGNATURE", signature)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
resp.Body.Close()
return nil
}
func (b *Bitfinex) GetTicker(symbol string) (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_TICKER + symbol, true, &b.Ticker)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) GetStats(symbol string) (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_STATS + symbol, true, &b.Stats)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) GetOrderbook(symbol string) (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_ORDERBOOK + symbol, true, &b.Orderbook)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) GetTrades(symbol string) (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_TRADES + symbol, true, &b.Trades)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) GetSymbols() (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_SYMBOLS, false, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) GetSymbolsDetails() (bool) {
err := SendHTTPRequest(BITFINEX_API_URL + BITFINEX_SYMBOLS_DETAILS, false, &b.SymbolsDetails)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *Bitfinex) NewDeposit(Symbol, Method, Wallet string) {
request := make(map[string]interface{})
request["currency"] = Symbol
request["method"] = Method
request["wallet_name"] = Wallet
err := b.SendAuthenticatedHTTPRequest(BITFINEX_DEPOSIT, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) NewOrder(Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) {
request := make(map[string]interface{})
request["symbol"] = Symbol
request["amount"] = fmt.Sprintf("%.8f", Amount)
request["price"] = fmt.Sprintf("%.5f", Price)
request["exchange"] = "bitfinex"
if Buy {
request["side"] = "buy"
} else {
request["side"] = "sell"
}
//request["is_hidden"] - currently not implemented
request["type"] = Type
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_NEW, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) CancelOrder(OrderID int) {
request := make(map[string]interface{})
request["order_id"] = OrderID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) CancelMultiplateOrders(OrderIDs []int) {
request := make(map[string]interface{})
request["order_ids"] = OrderIDs
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) CancelAllOrders() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL_ALL, nil)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) ReplaceOrder(OrderID int) {
request := make(map[string]interface{})
request["order_id"] = OrderID
}
func (b *Bitfinex) GetOrderStatus(OrderID int) {
request := make(map[string]interface{})
request["order_id"] = OrderID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_STATUS, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) GetActiveOrders() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDERS, nil)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) GetActivePositions() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_POSITIONS, nil)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) ClaimPosition(PositionID int) {
request := make(map[string]interface{})
request["position_id"] = PositionID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_CLAIM_POSITION, nil)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince time.Time, timeUntil time.Time, limit int, wallet string) {
request := make(map[string]interface{})
request["currency"] = symbol
request["since"] = timeSince
request["until"] = timeUntil
if limit > 0 {
request["limit"] = limit
}
if len(wallet) > 0 {
request["wallet"] = wallet
}
err := b.SendAuthenticatedHTTPRequest(BITFINEX_HISTORY, request)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitfinex) GetTradeHistory(symbol string, timestamp time.Time, limit int) {
request := make(map[string]interface{})
request["currency"] = symbol
request["timestamp"] = timestamp
if (limit > 0) {
request["limit_trades"] = limit
}
err := b.SendAuthenticatedHTTPRequest(BITFINEX_TRADE_HISTORY, nil)
if err != nil {
fmt.Println(err)
}
}
func JsonDecode(data string, result interface{}) (err error) {
r := json.NewDecoder(strings.NewReader(data))
err = r.Decode(result)
if err != nil {
return err
}
return
}

249
bitstamphttp.go Normal file
View File

@@ -0,0 +1,249 @@
package main
import (
"net/http"
"net/url"
"io/ioutil"
"fmt"
"encoding/hex"
"crypto/hmac"
"crypto/sha256"
"strings"
"strconv"
"errors"
"time"
)
const (
BITSTAMP_API_URL = "https://www.bitstamp.net/api/"
BITSTAMP_API_TICKER = "ticker/"
BITSTAMP_API_ORDERBOOK = "order_book/"
BITSTAMP_API_TRANSACTIONS = "transactions/"
BITSTAMP_API_EURUSD = "eur_usd/"
BITSTAMP_API_BALANCE = "balance/"
BITSTAMP_API_USER_TRANSACTIONS = "user_transactions/"
BITSTAMP_API_OPEN_ORDERS = "open_orders/"
BITSTAMP_API_CANCEL_ORDER = "cancel_order/"
BITSTAMP_API_BUY = "buy/"
BITSTAMP_API_SELL = "sell/"
BITSTAMP_API_WITHDRAWAL_REQUESTS = "withdrawal_requests/"
BITSTAMP_API_BITCOIN_WITHDRAWAL = "bitcoin_withdrawal/"
BITSTAMP_API_BITCOIN_DEPOSIT = "bitcoin_deposit_address/"
BITSTAMP_API_UNCONFIRMED_BITCOIN = "unconfirmed_btc/"
BITSTAMP_API_RIPPLE_WITHDRAWAL = "ripple_withdrawal/"
BITSTAMP_API_RIPPLE_DESPOIT = "ripple_address/"
)
type Bitstamp struct {
ClientID, APIKey, APISecret string
Ticker BitstampTicker
Orderbook Orderbook
ConversionRate ConversionRate
Transactions []Transactions
}
type BitstampTicker struct {
Last, High, Low, Vwap, Volume, Bid, Ask string
}
type Orderbook struct {
Timestamp string
Bids [][]string
Asks [][]string
}
type Transactions struct {
Date, Price, Amount string
Tid int64
}
type ConversionRate struct {
Buy string
Sell string
}
func (b *Bitstamp) GetTicker() {
err := SendHTTPRequest(BITSTAMP_API_URL + BITSTAMP_API_TICKER, true, &b.Ticker)
if err != nil {
fmt.Println(err)
return
}
}
func (b *Bitstamp) GetOrderbook() {
err := SendHTTPRequest(BITSTAMP_API_URL + BITSTAMP_API_ORDERBOOK, true, &b.Orderbook)
if err != nil {
fmt.Println(err)
return
}
}
func (b *Bitstamp) GetTransactions() {
err := SendHTTPRequest(BITSTAMP_API_URL + BITSTAMP_API_TRANSACTIONS, true, &b.Transactions)
if err != nil {
fmt.Println(err)
return
}
}
func (b *Bitstamp) GetEURUSDConversionRate() {
err := SendHTTPRequest(BITSTAMP_API_URL + BITSTAMP_API_EURUSD, true, &b.ConversionRate)
if err != nil {
fmt.Println(err)
return
}
}
func (b *Bitstamp) GetBalance() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BALANCE, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) GetUserTransactions(offset, limit, sort int64) {
var req = url.Values{}
req.Add("offset", strconv.FormatInt(offset, 10))
req.Add("limit", strconv.FormatInt(limit, 10))
req.Add("sort", strconv.FormatInt(sort, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_USER_TRANSACTIONS, req)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) CancelOrder(OrderID int64) {
var req = url.Values{}
req.Add("id", strconv.FormatInt(OrderID, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) GetOpenOrders() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_OPEN_ORDERS, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) PlaceOrder(price float64, amount float64, Type int) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', 8, 64))
req.Add("price", strconv.FormatFloat(price, 'f', 2, 64))
orderType := BITSTAMP_API_BUY
if Type == 1 {
orderType = BITSTAMP_API_SELL
}
fmt.Printf("Placing %s order at price %f for %f amount.\n", orderType, price, amount)
err := b.SendAuthenticatedHTTPRequest(orderType, req)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) GetWithdrawalRequests() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_WITHDRAWAL_REQUESTS, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) BitcoinWithdrawal(amount float64, address string) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', 8, 64))
req.Add("address", address)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_WITHDRAWAL, req)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) BitcoinDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_DEPOSIT, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) UnconfirmedBitcoin() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_UNCONFIRMED_BITCOIN, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', 8, 64))
req.Add("address", address)
req.Add("currency", currency)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_WITHDRAWAL, req)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) RippleDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_DESPOIT, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values) (err error) {
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
values.Set("key", b.APIKey)
values.Set("nonce", nonce)
hmac := hmac.New(sha256.New, []byte(b.APISecret))
hmac.Write([]byte(nonce + b.ClientID + b.APIKey))
values.Set("signature", strings.ToUpper(hex.EncodeToString(hmac.Sum(nil))))
reqBody := strings.NewReader(values.Encode())
path = BITSTAMP_API_URL + path
fmt.Println("Sending POST request to " + path)
req, err := http.NewRequest("POST", path, reqBody)
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("PostRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
resp.Body.Close()
return nil
}

161
btcchinahttp.go Normal file
View File

@@ -0,0 +1,161 @@
package main
import (
"net/http"
"net/url"
"strconv"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"strings"
"time"
"io/ioutil"
"fmt"
)
const (
BTCCHINA_API_URL = "https://api.btcchina.com/"
)
type BTCChina struct {
APISecret, APIKey string
}
func (b *BTCChina) GetTicker(symbol string) (bool) {
req := fmt.Sprintf("%sdata/ticker?market=%s", BTCCHINA_API_URL, symbol)
err := SendHTTPRequest(req, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *BTCChina) GetTradesLast24h(symbol string) (bool) {
req := fmt.Sprintf("%sdata/trades?market=%s", BTCCHINA_API_URL, symbol)
err := SendHTTPRequest(req, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *BTCChina) GetTradeHistory(symbol string, limit, sinceTid int64, time time.Time) (bool) {
req := fmt.Sprintf("%sdata/historydata?market=%s", BTCCHINA_API_URL, symbol)
v := url.Values{}
if limit > 0 {
v.Set("limit", strconv.FormatInt(limit, 10))
}
if sinceTid > 0 {
v.Set("since", strconv.FormatInt(sinceTid, 10))
}
if !time.IsZero() {
v.Set("sincetype", strconv.FormatInt(time.Unix(), 10))
}
values := v.Encode()
if (len(values) > 0) {
req += "?" + values
}
err := SendHTTPRequest(req, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *BTCChina) GetOrderBook(symbol string, limit int) (bool) {
req := fmt.Sprintf("%sdata/orderbook?market=%s&limit=%d", BTCCHINA_API_URL, symbol, limit)
err := SendHTTPRequest(req, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (b *BTCChina) GetAccountInfo() {
err := b.SendAuthenticatedHTTPRequest("getAccountInfo", nil)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCChina) BuyOrder(price, amount float64) {
params := []string{}
if (price != 0) {
params = append(params, strconv.FormatFloat(price, 'f', 8, 64))
}
err := b.SendAuthenticatedHTTPRequest("buyOrder2", nil)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCChina) SendAuthenticatedHTTPRequest(method string, params []string) (err error) {
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)[0:16]
if (len(params) > 0) {
params = nil
}
encoded := fmt.Sprintf("tonce=%s&accesskey=%s&requestmethod=post&id=%d&method=%s&params=%s", nonce, b.APIKey, 1, method, params)
fmt.Println(encoded)
hmac := hmac.New(sha1.New, []byte(b.APISecret))
hmac.Write([]byte(encoded))
hash := hex.EncodeToString(hmac.Sum(nil))
postData := make(map[string]interface{})
postData["method"] = method
postData["params"] = []string{}
postData["id"] = 1
data, err := json.Marshal(postData)
fmt.Println(string(data))
if err != nil {
return errors.New("Unable to JSON POST data")
}
fmt.Printf("Sending POST request to %s calling method %s with params %s\n", "https://api.btcchina.com/api_trade_v1.php", method, data)
reqBody := strings.NewReader(string(data))
b64 := base64.StdEncoding.EncodeToString([]byte(b.APIKey + ":" + hash))
req, err := http.NewRequest("POST", "https://api.btcchina.com/api_trade_v1.php", reqBody)
if err != nil {
return err
}
req.Header.Add("Content-type", "application/json-rpc")
req.Header.Add("Authorization", "Basic " + b64)
req.Header.Add("Json-Rpc-Tonce", nonce)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("PostRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recv'd :%s", string(contents))
resp.Body.Close()
return nil
}

146
btcehttp.go Normal file
View File

@@ -0,0 +1,146 @@
package main
import (
"net/http"
"net/url"
"strconv"
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
"errors"
"strings"
"time"
"io/ioutil"
"fmt"
)
const (
BTCE_API_URL = "https://btc-e.com/tapi"
BTCE_GET_INFO = "getInfo"
BTCE_TRANSACTION_HISTORY = "TransHistory"
BTCE_TRADE_HISTORY = "TradeHistory"
BTCE_ACTIVE_ORDERS = "ActiveOrders"
BTCE_TRADE = "Trade"
BTCE_CANCEL_ORDER = "CancelOrder"
)
type BTCE struct {
APIKey, APISecret string
}
func (b *BTCE) GetInfo() {
err := b.SendAuthenticatedHTTPRequest(BTCE_GET_INFO, url.Values{})
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) GetActiveOrders(pair string) {
req := url.Values{}
req.Add("pair", pair)
err := b.SendAuthenticatedHTTPRequest(BTCE_ACTIVE_ORDERS, req)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) CancelOrder(OrderID int64) {
req := url.Values{}
req.Add("order_id", strconv.FormatInt(OrderID, 10))
err := b.SendAuthenticatedHTTPRequest(BTCE_CANCEL_ORDER, req)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) Trade(pair, orderType string, amount, price float64) {
req := url.Values{}
req.Add("pair", pair)
req.Add("type", orderType)
req.Add("amount", strconv.FormatFloat(amount, 'f', 8, 64))
req.Add("rate", strconv.FormatFloat(price, 'f', 2, 64))
err := b.SendAuthenticatedHTTPRequest(BTCE_TRADE, req)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) GetTransactionHistory(TIDFrom, Count, TIDEnd int64, order, since, end string) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDFrom, 10))
req.Add("order", order)
req.Add("since", order)
req.Add("end", order)
err := b.SendAuthenticatedHTTPRequest(BTCE_TRANSACTION_HISTORY, req)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) GetTradeHistory(TIDFrom, Count, TIDEnd int64, order, since, end, pair string) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDFrom, 10))
req.Add("order", order)
req.Add("since", order)
req.Add("end", order)
req.Add("pair", pair)
err := b.SendAuthenticatedHTTPRequest(BTCE_TRANSACTION_HISTORY, req)
if err != nil {
fmt.Println(err)
}
}
func (b *BTCE) SendAuthenticatedHTTPRequest(method string, values url.Values) (err error) {
nonce := strconv.FormatInt(time.Now().Unix(), 10)
values.Set("nonce", nonce)
values.Set("method", method)
hmac := hmac.New(sha512.New, []byte(b.APISecret))
encoded := values.Encode()
hmac.Write([]byte(encoded))
fmt.Printf("Sending POST request to %s calling method %s with params %s\n", BTCE_API_URL, method, encoded)
reqBody := strings.NewReader(encoded)
req, err := http.NewRequest("POST", BTCE_API_URL, reqBody)
if err != nil {
return err
}
req.Header.Add("Key", b.APIKey)
req.Header.Add("Sign", hex.EncodeToString(hmac.Sum(nil)))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("PostRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
resp.Body.Close()
return nil
}

37
common.go Normal file
View File

@@ -0,0 +1,37 @@
package main
import (
"net/http"
"fmt"
"io/ioutil"
"errors"
)
func SendHTTPRequest(url string, jsonDecode bool, result interface{}) (err error) {
res, err := http.Get(url)
fmt.Println("Attempting connection to: " + url)
if err != nil {
fmt.Println(err)
return err
}
if res.StatusCode != 200 {
fmt.Printf("HTTP status code: %d", res.StatusCode)
return errors.New("Status code was not 200.")
}
contents, _ := ioutil.ReadAll(res.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
if jsonDecode {
err = JsonDecode(string(contents), result)
if err != nil {
return errors.New("Unable to JSON decode body.")
}
} else {
result = contents
}
return
}

235
itbithttp.go Normal file
View File

@@ -0,0 +1,235 @@
package main
import (
"net/http"
"strconv"
"crypto/hmac"
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"errors"
"strings"
"time"
"encoding/json"
"io/ioutil"
"fmt"
)
const (
ITBIT_API_URL = "https://api.itbit.com/v1/"
)
type ItBit struct {
ClientKey, APISecret, UserID string
}
func (i *ItBit) GetTicker(currency string) (bool) {
path := ITBIT_API_URL + "/markets/" + currency + "/ticker"
err := SendHTTPRequest(path, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (i *ItBit) GetOrderbook(currency string) (bool) {
path := ITBIT_API_URL + "/markets/" + currency + "/orders"
err := SendHTTPRequest(path , true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (i *ItBit) GetTradeHistory(currency, timestamp string) (bool) {
req := "/trades?since=" + timestamp
err := SendHTTPRequest(ITBIT_API_URL + "markets/" + currency + req, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (i *ItBit) GetWallets(page int64, perPage int64, userID string) {
path := ITBIT_API_URL + "wallets/"
params := make(map[string]interface{})
params["page"] = strconv.FormatInt(page, 10)
params["perPage"] = strconv.FormatInt(perPage, 10)
params["userID"] = userID
err := i.SendAuthenticatedHTTPRequest("GET", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetWallet(walletID string) {
path := ITBIT_API_URL + "/wallets/" + walletID
err := i.SendAuthenticatedHTTPRequest("GET", path, nil)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetWalletBalance(walletID, currency string) {
path := ITBIT_API_URL + "/wallets/ " + walletID + "/balances/" + currency
err := i.SendAuthenticatedHTTPRequest("GET", path, nil)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetWalletTrades(walletID string, page int64, perPage int64, rangeEnd int64, rangeStart int64) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/trades"
params := make(map[string]interface{})
params["page"] = strconv.FormatInt(page, 10)
params["perPage"] = strconv.FormatInt(perPage, 10)
params["rangeEnd"] = strconv.FormatInt(page, 10)
params["rangeStart"] = strconv.FormatInt(perPage, 10)
err := i.SendAuthenticatedHTTPRequest("GET", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetWalletOrders(walletID string, instrument string, page int64, perPage int64, status string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/orders"
params := make(map[string]interface{})
params["instrument"] = instrument
params["page"] = strconv.FormatInt(page, 10)
params["perPage"] = strconv.FormatInt(perPage, 10)
params["status"] = status
err := i.SendAuthenticatedHTTPRequest("GET", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) PlaceWalletOrder(walletID, side, orderType, currency string, amount, price float64, instrument string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/orders"
params := make(map[string]interface{})
params["side"] = side
params["type"] = orderType
params["currency"] = currency
params["amount"] = strconv.FormatFloat(amount, 'f', 8, 64)
params["price"] = strconv.FormatFloat(price, 'f', 2, 64)
params["instrument"] = instrument
err := i.SendAuthenticatedHTTPRequest("POST", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetWalletOrder(walletID, orderID string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/orders/" + orderID
err := i.SendAuthenticatedHTTPRequest("GET", path, nil)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) CancelWalletOrder(walletID, orderID string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/orders/" + orderID
err := i.SendAuthenticatedHTTPRequest("DELETE", path, nil)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) PlaceWithdrawalRequest(walletID, currency, address string, amount float64) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/cryptocurrency_withdrawals"
params := make(map[string]interface{})
params["currency"] = currency
params["amount"] = strconv.FormatFloat(amount, 'f', 8, 64)
params["address"] = address
err := i.SendAuthenticatedHTTPRequest("POST", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) GetDepositAddress(walletID, currency string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/cryptocurrency_deposits"
params := make(map[string]interface{})
params["currency"] = currency
err := i.SendAuthenticatedHTTPRequest("POST", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) WalletTransfer(walletID, sourceWallet, destWallet string, amount float64, currency string) {
path := ITBIT_API_URL + "/wallets/" + walletID + "/wallet_transfers"
params := make(map[string]interface{})
params["sourceWalletId"] = sourceWallet
params["destinationWalletId"] = destWallet
params["amount"] = strconv.FormatFloat(amount, 'f', 8, 64)
params["currencyCode"] = currency
err := i.SendAuthenticatedHTTPRequest("POST", path, params)
if err != nil {
fmt.Println(err)
}
}
func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params map[string]interface{}) (err error) {
request := make(map[string]interface{})
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
request["nonce"] = nonce
request["timestamp"] = nonce
if params != nil {
for key, value:= range params {
request[key] = value
}
}
PayloadJson, err := json.Marshal(request)
fmt.Printf("Request JSON: %s\n", PayloadJson)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}
hmac := hmac.New(sha512.New, []byte(i.APISecret))
hmac.Write([]byte(nonce + string(PayloadJson)))
hex := hex.EncodeToString(hmac.Sum(nil))
signature := base64.StdEncoding.EncodeToString([]byte(hex))
req, err := http.NewRequest(method, path, strings.NewReader(""))
req.Header.Add("Authorization", i.ClientKey + ":" + signature)
req.Header.Add("X-Auth-Timestamp", nonce)
req.Header.Add("X-Auth-Nonce", nonce)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
resp.Body.Close()
return nil
}

184
okcoinhttp.go Normal file
View File

@@ -0,0 +1,184 @@
package main
import (
"net/http"
"net/url"
"crypto/md5"
"errors"
"strings"
"encoding/hex"
"io/ioutil"
"strconv"
"fmt"
)
const (
OKCOIN_API_URL = "https://www.okcoin.com/api/v1/"
OKCOIN_API_URL_CHINA = "https://www.okcoin.cn/api/v1/"
)
type OKCoin struct {
PartnerID, SecretKey string
}
func (o *OKCoin) GetTicker(symbol string) (bool) {
path := "ticker.do?symbol=" + symbol
err := SendHTTPRequest(OKCOIN_API_URL + path, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (o *OKCoin) GetOrderBook(symbol string) (bool) {
path := "depth.do?symbol=" + symbol
err := SendHTTPRequest(OKCOIN_API_URL + path, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (o *OKCoin) GetTradeHistory(symbol string) (bool) {
path := "trades.do?symbol=" + symbol
err := SendHTTPRequest(OKCOIN_API_URL + path, true, nil)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (o *OKCoin) GetUserInfo() {
v := url.Values{}
v.Set("partner", o.PartnerID)
err := o.SendAuthenticatedHTTPRequest("userinfo.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) Trade(amount, price float64, symbol, orderType string) {
v := url.Values{}
v.Set("partner", o.PartnerID)
v.Set("amount", strconv.FormatFloat(amount, 'f', 8, 64))
v.Set("price", strconv.FormatFloat(price, 'f', 8, 64))
v.Set("symbol", symbol)
v.Set("type", orderType)
err := o.SendAuthenticatedHTTPRequest("trade.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) BatchTrade(orderData string, symbol, orderType string) {
v := url.Values{} //to-do batch trade support for orders_data
v.Set("partner", o.PartnerID)
v.Set("orders_data", orderData)
v.Set("symbol", symbol)
v.Set("type", orderType)
err := o.SendAuthenticatedHTTPRequest("batch_trade.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) CancelOrder(orderID int64, symbol string) {
v := url.Values{}
v.Set("partner", o.PartnerID)
v.Set("orders_id", strconv.FormatInt(orderID, 10))
v.Set("symbol", symbol)
err := o.SendAuthenticatedHTTPRequest("cancel_order.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) GetOrderInfo(orderID int64, symbol string) {
v := url.Values{}
v.Set("partner", o.PartnerID)
v.Set("orders_id", strconv.FormatInt(orderID, 10))
v.Set("symbol", symbol)
err := o.SendAuthenticatedHTTPRequest("order_info.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) GetOrdersInfo(orderID int64, orderType string, symbol string) {
v := url.Values{}
v.Set("partner", o.PartnerID)
v.Set("orders_id", strconv.FormatInt(orderID, 10))
v.Set("type", orderType)
v.Set("symbol", symbol)
err := o.SendAuthenticatedHTTPRequest("orders_info.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) GetOrderHistory(orderID, pageLength, currentPage int64, orderType string, status, symbol string) {
v := url.Values{}
v.Set("partner", o.PartnerID)
v.Set("orders_id", strconv.FormatInt(orderID, 10))
v.Set("type", orderType)
v.Set("symbol", symbol)
v.Set("status", status)
v.Set("current_page", strconv.FormatInt(currentPage, 10))
v.Set("page_length", strconv.FormatInt(pageLength, 10))
err := o.SendAuthenticatedHTTPRequest("orders_info.do", v)
if err != nil {
fmt.Println(err)
}
}
func (o *OKCoin) SendAuthenticatedHTTPRequest(method string, v url.Values) (err error) {
hasher := md5.New()
hasher.Write([]byte(v.Encode() + "&secret_key=" + o.SecretKey))
signature := strings.ToUpper(hex.EncodeToString(hasher.Sum(nil)))
v.Set("sign", signature)
encoded := v.Encode() + "&partner=" + o.PartnerID
fmt.Printf("Signature: %s\n", signature)
path := OKCOIN_API_URL + method
fmt.Printf("Sending POST request to %s with params %s\n", path, encoded)
reqBody := strings.NewReader(encoded)
req, err := http.NewRequest("POST", path, reqBody)
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return errors.New("PostRequest: Unable to send request")
}
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
resp.Body.Close()
return nil
}