Feature: Implement funding rates, futures and coin margin (exchange API coverage) (#530)

* ALMOST THERE

* more api wips

* more api thingz

* testing n more api wipz

* more apiz

* more wips

* what is goin on

* more wips

* whip n testing

* testing

* testing

no keys

* remove log

* kraken is broken

ugh

* still broken

* fixing auth funcs + usdtm api docs

* wip

* api stuffs

* whip

* more wips

* whip

* more wip

* api wip n testing

* wip

* wip

* unsaved

* wip n testing

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* whip

* wrapper authenticated functions

* adding asset type and fixing dependencies

* wip

* binance auth wrapper start

* wrapper functionality

* wip

* wip

* wip

* wrapper cancel functions

* order submission for wrappers

* wip

* more error fixing and nits

* websocket beginning n error fix

* wip

* WOW

* glorious n shazzy nits

* useless nits

* wip

* fixing things

* merge stuffs

* crapveyor

* crapveyor rebuild

* probably broke more things than he fixed

* rm lns n other thangs

* hope

* please

* stop it

* done

* ofcourse

* rm vb

* fix lbank

* appveyor please

* float lev

* DONT ASK RYAN FOR HELP EVER

* wip

* wip

* endpoint upgrades continued

* path upgrade

* NeeeNeeeNeeeNeeeNING

* fix stuffs

* fixing time issue

* fixing broken funcs

* glorious nits

* shaz changes

* fixing errors for fundmon

* more error fixing for fundmon

* test running past 30s

* basic changes

* THX AGAIN SHAZBERT

* path system upgrade

* config upgrade

* unsaved stuffs

* broken wip config upgrade

* path system upgrade contd.

* path system upgrade contd

* path upgrade ready for review

* testing verbose removed

* linter stuffs

* appveyor stuffs

* appveyor stuff

* fixed?

* bugfix

* wip

* broken stuff

* fix test

* wierd hack fix

* appveyor pls stop

* error found

* more useless nits

* bitmex err

* broken wip

* broken wip path upgrade change to uint32

* changed url lookups to uint

* WOW

* ready4review

* config fixed HOPEFULLY

* config fix and glorious changes

* efficient way of getting orders and open orders

* binance wrapper logic fixing

* testing, adding tests and fixing lot of errrrrs

* merge master

* appveyor stuffs

* appveyor stuffs

* fmt

* test

* octalLiteral issue fix?

* octalLiteral fix?

* rm vb

* prnt ln to restart

* adding testz

* test fixzzz

* READY FOR REVIEW

* Actually ready now

* FORMATTING

* addressing shazzy n glorious nits

* crapveyor

* rm vb

* small change

* fixing err

* shazbert nits

* review changes

* requested changes

* more requested changes

* noo

* last nit fixes

* restart appveyor

* improving test cov

* Update .golangci.yml

* shazbert changes

* moving pair formatting

* format pair update wip

* path upgrade complete

* error fix

* appveyor linters

* more linters

* remove testexch

* more formatting changes

* changes

* shazbert changes

* checking older requested changes to ensure completion

* wip

* fixing broken code

* error fix

* all fixed

* additional changes

* more changes

* remove commented code

* ftx margin api

* appveyor fixes

* more appveyor issues + test addition

* more appveyor issues + test addition

* remove unnecessary

* testing

* testing, fixing okex api, error fix

* git merge fix

* go sum

* glorious changes and error fix

* rm vb

* more glorious changes and go mod tidy

* fixed now

* okex testing upgrade

* old config migration and batch fetching fix

* added test

* glorious requested changes WIP

* tested and fixed

* go fmted

* go fmt and test fix

* additional funcs and tests for fundingRates

* OKEX tested and fixed

* appveyor fixes

* ineff assign

* 1 glorious change

* error fix

* typo

* shazbert changes

* glorious code changes and path fixing huobi WIP

* adding assetType to accountinfo functions

* fixing panic

* panic fix and updating account info wrappers WIP

* updateaccountinfo updated

* testing WIP binance USDT n Coin Margined and Kraken Futures

* auth functions tested and fixed

* added test

* config reverted

* shazbert and glorious changes

* shazbert and glorious changes

* latest changes and portfolio update

* go fmt change:

* remove commented codes

* improved error checking

* index out of range fix

* rm ln

* critical nit

* glorious latest changes

* appveyor changes

* shazbert change

* easier readability

* latest glorious changes

* shadow dec

* assetstore updated

* last change

* another last change

* merge changes

* go mod tidy

* thrasher requested changes wip

* improving struct layouts

* appveyor go fmt

* remove unnecessary code

* shazbert changes

* small change

* oopsie

* tidy

* configtest reverted

* error fix

* oopsie

* for what

* test patch fix

* insecurities

* fixing tests

* fix config
This commit is contained in:
Adam
2021-02-12 16:19:18 +11:00
committed by GitHub
parent e9bd2ad4d8
commit 504c2fad6d
169 changed files with 227754 additions and 31776 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,845 @@
package huobi
// FContractInfoData gets contract info data for futures
type FContractInfoData struct {
Data []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
ContractSize float64 `json:"contract_size"`
PriceTick float64 `json:"price_tick"`
DeliveryDate string `json:"delivery_date"`
CreateDate string `json:"create_date"`
ContractStatus int64 `json:"contract_status"`
}
}
// FContractIndexPriceInfo stores contract index price
type FContractIndexPriceInfo struct {
Data []struct {
Symbol string `json:"symbol"`
IndexPrice float64 `json:"index_price"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FContractPriceLimits gets limits for futures contracts
type FContractPriceLimits struct {
Data struct {
Symbol string `json:"symbol"`
HighLimit float64 `json:"high_limit"`
LowLimit float64 `json:"low_limit"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FContractOIData stores open interest data for futures contracts
type FContractOIData struct {
Data []struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
Volume float64 `json:"volume"`
Amount float64 `json:"amount"`
ContractCode string `json:"contract_code"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FEstimatedDeliveryPriceInfo stores estimated delivery price data for futures
type FEstimatedDeliveryPriceInfo struct {
Data struct {
DeliveryPrice float64 `json:"delivery_price"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FMarketDepth gets orderbook data for futures
type FMarketDepth struct {
Ch string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
MRID int64 `json:"mrid"`
ID int64 `json:"id"`
Bids [][2]float64 `json:"bids"`
Asks [][2]float64 `json:"asks"`
Timestamp int64 `json:"ts"`
Version int64 `json:"version"`
Ch string `json:"ch"`
} `json:"tick"`
}
// OBData stores market depth data
type OBData struct {
Symbol string
Asks []obItem
Bids []obItem
}
type obItem struct {
Price float64
Quantity float64
}
// FKlineData stores kline data for futures
type FKlineData struct {
Ch string `json:"ch"`
Data []struct {
Vol float64 `json:"vol"`
Close float64 `json:"close"`
Count float64 `json:"count"`
High float64 `json:"high"`
ID int64 `json:"id"`
Low float64 `json:"low"`
Open float64 `json:"open"`
Amount float64 `json:"amount"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FMarketOverviewData stores overview data for futures
type FMarketOverviewData struct {
Ch string `json:"ch"`
Tick struct {
Vol float64 `json:"vol,string"`
Ask [2]float64
Bid [2]float64
Close float64 `json:"close,string"`
Count float64 `json:"count"`
High float64 `json:"high,string"`
ID int64 `jso:"id"`
Low float64 `json:"low,string"`
Open float64 `json:"open,string"`
Timestamp int64 `json:"ts"`
Amount float64 `json:"amount,string"`
} `json:"tick"`
Timestamp int64 `json:"ts"`
}
// FLastTradeData stores last trade's data for a contract
type FLastTradeData struct {
Ch string `json:"ch"`
Tick struct {
Data []struct {
Amount float64 `json:"amount,string"`
Direction string `json:"direction"`
ID int64 `json:"id"`
Price float64 `json:"price,string"`
Timestamp int64 `json:"ts"`
} `json:"data"`
ID int64 `json:"id"`
Timestamp int64 `json:"ts"`
} `json:"tick"`
Timestamp int64 `json:"ts"`
}
// FBatchTradesForContractData stores batch of trades data for a contract
type FBatchTradesForContractData struct {
Ch string `json:"ch"`
Timestamp int64 `json:"ts"`
Data []struct {
ID int64 `json:"id"`
Timestamp int64 `json:"ts"`
Data []struct {
Amount float64 `json:"amount"`
Direction string `json:"direction"`
ID int64 `json:"id"`
Price float64 `json:"price"`
Timestamp int64 `json:"ts"`
} `json:"data"`
} `json:"data"`
}
// FClawbackRateAndInsuranceData stores clawback rate and insurance data for futures
type FClawbackRateAndInsuranceData struct {
Timestamp int64 `json:"ts"`
Data []struct {
Symbol string `json:"symbol"`
InsuranceFund float64 `json:"insurance_fund"`
EstimatedClawback float64 `json:"estimated_clawback"`
} `json:"data"`
}
// FHistoricalInsuranceRecordsData stores historical records of insurance fund balances for futures
type FHistoricalInsuranceRecordsData struct {
Timestamp int64 `json:"timestamp"`
Data struct {
Symbol string `json:"symbol"`
Tick []struct {
InsuranceFund float64 `json:"insurance_fund"`
Timestamp int64 `json:"ts"`
} `json:"tick"`
} `json:"data"`
}
// FTieredAdjustmentFactorInfo stores info on adjustment factor for futures
type FTieredAdjustmentFactorInfo struct {
Data []struct {
Symbol string `json:"symbol"`
List []struct {
LeverageRate float64 `json:"lever_rate"`
Ladders []struct {
Ladder int64 `json:"ladder"`
MinSize float64 `json:"min_size"`
MaxSize float64 `json:"max_size"`
AdjustFactor float64 `json:"adjust_factor"`
} `json:"ladders"`
} `json:"list"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FOIData gets oi data on futures
type FOIData struct {
Data struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
Tick []struct {
Volume float64 `json:"volume,string"`
AmountType int64 `json:"amount_type"`
Timestamp int64 `json:"ts"`
} `json:"tick"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FInfoSystemStatusData stores system status info for futures
type FInfoSystemStatusData struct {
Data []struct {
Symbol string `json:"symbol"`
Open int64 `json:"open"`
Close int64 `json:"close"`
Cancel int64 `json:"cancel"`
TransferIn int64 `json:"transfer_in"`
TransferOut int64 `json:"transfer_out"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTopAccountsLongShortRatio stores long/short ratio for top futures accounts
type FTopAccountsLongShortRatio struct {
Data struct {
List []struct {
BuyRatio float64 `json:"buy_ratio"`
SellRatio float64 `json:"sell_ratio"`
LockedRatio float64 `json:"locked_ratio"`
Timestamp int64 `json:"ts"`
} `json:"list"`
Symbol string `json:"symbol"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTopPositionsLongShortRatio stores long short ratio for top futures positions
type FTopPositionsLongShortRatio struct {
Data struct {
Symbol string `json:"symbol"`
List []struct {
BuyRatio float64 `json:"buy_ratio"`
SellRatio float64 `json:"sell_ratio"`
Timestamp int64 `json:"timestamp"`
} `json:"list"`
} `json:"data"`
Timestamp int64 `json:"timestamp"`
}
// FLiquidationOrdersInfo stores data of futures liquidation orders
type FLiquidationOrdersInfo struct {
Data struct {
Orders []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
Direction string `json:"direction"`
Offset string `json:"offset"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
CreatedAt int64 `json:"created_at"`
} `json:"orders"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FIndexKlineData stores index kline data for futures
type FIndexKlineData struct {
Ch string `json:"ch"`
Data []struct {
Vol float64 `json:"vol"`
Close float64 `json:"close"`
Count float64 `json:"count"`
High float64 `json:"high"`
ID int64 `json:"id"`
Low float64 `json:"low"`
Open float64 `json:"open"`
Amount float64 `json:"amount"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FBasisData stores basis data for futures
type FBasisData struct {
Ch string `json:"ch"`
Data []struct {
Basis float64 `json:"basis,string"`
BasisRate float64 `json:"basis_rate,string"`
ContractPrice float64 `json:"contract_price,string"`
ID int64 `json:"id"`
IndexPrice float64 `json:"index_price,string"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FUserAccountData stores user account data info for futures
type FUserAccountData struct {
AccData []struct {
Symbol string `json:"symbol"`
MarginBalance float64 `json:"margin_balance"`
MarginPosition float64 `json:"margin_position"`
MarginFrozen float64 `json:"margin_frozen"`
MarginAvailable float64 `json:"margin_available"`
ProfitReal float64 `json:"profit_real"`
ProfitUnreal float64 `json:"profit_unreal"`
RiskRate float64 `json:"risk_rate"`
LiquidationPrice float64 `json:"liquidation_price"`
WithdrawAvailable float64 `json:"withdraw_available"`
LeverageRate float64 `json:"lever_rate"`
AdjustFactor float64 `json:"adjust_factor"`
MarginStatic float64 `json:"margin_static"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FUsersPositionsInfo stores positions data for futures
type FUsersPositionsInfo struct {
PosInfo []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
Volume float64 `json:"volume"`
Available float64 `json:"available"`
Frozen float64 `json:"frozen"`
CostOpen float64 `json:"cost_open"`
CostHold float64 `json:"cost_hold"`
ProfitUnreal float64 `json:"profit_unreal"`
ProfitRate float64 `json:"profit_rate"`
Profit float64 `json:"profit"`
PositionMargin float64 `json:"position_margin"`
LeverageRate float64 `json:"lever_rate"`
Direction string `json:"direction"`
LastPrice float64 `json:"last_price"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FSubAccountAssetsInfo gets subaccounts asset data
type FSubAccountAssetsInfo struct {
Timestamp int64 `json:"ts"`
Data []struct {
SubUID int64 `json:"sub_uid"`
List []struct {
Symbol string `json:"symbol"`
MarginBalance float64 `json:"margin_balance"`
LiquidationPrice float64 `json:"liquidation_price"`
RiskRate float64 `json:"risk_rate"`
} `json:"list"`
} `json:"data"`
}
// FSingleSubAccountAssetsInfo stores futures assets info for a single subaccount
type FSingleSubAccountAssetsInfo struct {
AssetsData []struct {
Symbol string `json:"symbol"`
MarginBalance float64 `json:"margin_balance"`
MarginPosition float64 `json:"margin_position"`
MarginFrozen float64 `json:"margin_frozen"`
MarginAvailable float64 `json:"margin_available"`
ProfitReal float64 `json:"profit_real"`
ProfitUnreal float64 `json:"profit_unreal"`
WithdrawAvailable float64 `json:"withdraw_available"`
RiskRate float64 `json:"risk_rate"`
LiquidationPrice float64 `json:"liquidation_price"`
AdjustFactor float64 `json:"adjust_factor"`
LeverageRate float64 `json:"lever_rate"`
MarginStatic float64 `json:"margin_static"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FSingleSubAccountPositionsInfo stores futures positions' info for a single subaccount
type FSingleSubAccountPositionsInfo struct {
PositionsData []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
Volume float64 `json:"volume"`
Available float64 `json:"available"`
Frozen float64 `json:"frozen"`
CostOpen float64 `json:"cost_open"`
CostHold float64 `json:"cost_hold"`
ProfitUnreal float64 `json:"profit_unreal"`
ProfitRate float64 `json:"profit_rate"`
Profit float64 `json:"profit"`
PositionMargin float64 `json:"position_margin"`
LeverageRate float64 `json:"lever_rate"`
Direction string `json:"direction"`
LastPrice float64 `json:"last_price"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FFinancialRecords stores financial records data for futures
type FFinancialRecords struct {
Data struct {
FinancialRecord []struct {
ID int64 `json:"id"`
Timestamp int64 `json:"ts"`
Symbol string `json:"symbol"`
RecordType int64 `json:"type"`
Amount float64 `json:"amount"`
} `json:"financial_record"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FSettlementRecords stores user's futures settlement records
type FSettlementRecords struct {
Data struct {
SettlementRecords []struct {
Symbol string `json:"symbol"`
MarginBalanceInit float64 `json:"margin_balance_init"`
MarginBalance int64 `json:"margin_balance"`
SettlementProfitReal float64 `json:"settlement_profit_real"`
SettlementTime int64 `json:"settlement_time"`
Clawback float64 `json:"clawback"`
DeliveryFee float64 `json:"delivery_fee"`
OffsetProfitLoss float64 `json:"offset_profitloss"`
Fee float64 `json:"fee"`
FeeAsset string `json:"fee_asset"`
Positions []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
Direction string `json:"direction"`
Volume float64 `json:"volume"`
CostOpen float64 `json:"cost_open"`
CostHoldPre float64 `json:"cost_hold_pre"`
CostHold float64 `json:"cost_hold"`
SettlementProfitUnreal float64 `json:"settlement_profit_unreal"`
SettlementPrice float64 `json:"settlement_price"`
SettlmentType string `json:"settlement_type"`
} `json:"positions"`
} `json:"settlement_records"`
CurrentPage int64 `json:"current_page"`
TotalPage int64 `json:"total_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FContractInfoOnOrderLimit stores contract info on futures order limit
type FContractInfoOnOrderLimit struct {
ContractData []struct {
OrderPriceType string `json:"order_price_type"`
List []struct {
Symbol string `json:"symbol"`
ContractTypes []struct {
ContractType string `json:"contract_type"`
OpenLimit int64 `json:"open_limit"`
CloseLimit int64 `json:"close_limit"`
} `json:"types"`
} `json:"list"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FContractTradingFeeData stores contract trading fee data
type FContractTradingFeeData struct {
ContractTradingFeeData []struct {
Symbol string `json:"symbol"`
OpenMakerFee float64 `json:"open_maker_fee,string"`
OpenTakerFee float64 `json:"open_taker_fee,string"`
CloseMakerFee float64 `json:"close_maker_fee,string"`
CloseTakerFee float64 `json:"close_taker_fee,string"`
DeliveryFee float64 `json:"delivery_fee,string"`
FeeAsset string `json:"fee_asset"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTransferLimitData stores transfer limit data for futures
type FTransferLimitData struct {
Data []struct {
Symbol string `json:"symbol"`
MaxTransferIn float64 `json:"transfer_in_max_each"`
MinTransferIn float64 `json:"transfer_in_min_each"`
MaxTransferOut float64 `json:"transfer_out_max_each"`
MinTransferOut float64 `json:"transfer_out_min_each"`
MaxTransferInDaily float64 `json:"transfer_in_max_daily"`
MaxTransferOutDaily float64 `json:"transfer_out_max_daily"`
NetTransferInMaxDaily float64 `json:"net_transfer_in_max_daily"`
NetTransferOutMaxDaily float64 `json:"net_transfer_out_max_daily"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FPositionLimitData stores information on futures positions limit
type FPositionLimitData struct {
Data []struct {
Symbol string `json:"symbol"`
List []struct {
ContractType string `json:"contract_type"`
BuyLimit float64 `json:"buy_limit"`
SellLimit float64 `json:"sell_limit"`
} `json:"list"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FAssetsAndPositionsData stores assets and positions data for futures
type FAssetsAndPositionsData struct {
Data []struct {
Symbol string `json:"symbol"`
MarginBalance float64 `json:"margin_balance"`
MarginPosition float64 `json:"margin_position"`
MarginFrozen float64 `json:"margin_frozen"`
MarginAvailable float64 `json:"margin_available"`
ProfitReal float64 `json:"profit_real"`
ProfitUnreal float64 `json:"profit_unreal"`
RiskRate float64 `json:"risk_rate"`
WithdrawAvailable float64 `json:"withdraw_available"`
} `json:"data"`
}
// FAccountTransferData stores internal transfer data for futures
type FAccountTransferData struct {
Status string `json:"status"`
Timestamp int64 `json:"ts"`
Data struct {
OrderID string `json:"order_id"`
} `json:"data"`
}
// FTransferRecords gets transfer records data
type FTransferRecords struct {
Timestamp int64 `json:"ts"`
Data struct {
TransferRecord []struct {
ID int64 `json:"id"`
Timestamp int64 `json:"ts"`
Symbol string `json:"symbol"`
SubUID int64 `json:"sub_uid"`
SubAccountName string `json:"sub_account_name"`
TransferType int64 `json:"transfer_type"`
Amount float64 `json:"amount"`
} `json:"transfer_record"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
}
// FAvailableLeverageData stores available leverage data for futures
type FAvailableLeverageData struct {
Data []struct {
Symbol string `json:"symbol"`
AvailableLeverageRate string `json:"available_level_rate"`
} `json:"data"`
Timestamp int64 `json:"timestamp"`
}
// FOrderData stores order data for futures
type FOrderData struct {
Data struct {
OrderID int64 `json:"order_id"`
OrderIDStr string `json:"order_id_str"`
ClientOrderID int64 `json:"client_order_id"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
type fBatchOrderData struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
ClientOrderID string `json:"client_order_id"`
Price float64 `json:"price"`
Volume float64 `json:"volume"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"leverRate"`
OrderPriceType string `json:"orderPriceType"`
}
// FBatchOrderResponse stores batch order data
type FBatchOrderResponse struct {
OrdersData []FOrderData `json:"orders_data"`
}
// FCancelOrderData stores cancel order data
type FCancelOrderData struct {
Data struct {
Errors []struct {
OrderID int64 `json:"order_id,string"`
ErrCode int64 `json:"err_code"`
ErrMsg string `json:"err_msg"`
} `json:"errors"`
Successes string `json:"successes"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FOrderInfo stores order info
type FOrderInfo struct {
Data []struct {
ClientOrderID int64 `json:"client_order_id"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
CreatedAt int64 `json:"created_at"`
CanceledAt int64 `json:"canceled_at"`
Direction string `json:"direction"`
Fee float64 `json:"fee"`
FeeAsset string `json:"fee_asset"`
LeverRate int64 `json:"lever_rate"`
MarginFrozen float64 `json:"margin_frozen"`
Offset string `json:"offset"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_string"`
OrderPriceType string `json:"order_price_type"`
OrderSource string `json:"order_source"`
OrderType int64 `json:"order_type"`
Price float64 `json:"price"`
Profit float64 `json:"profit"`
Status int64 `json:"status"`
Symbol string `json:"symbol"`
TradeAvgPrice float64 `json:"trade_avg_price"`
TradeTurnover float64 `json:"trade_turnover"`
TradeVolume float64 `json:"trade_volume"`
Volume float64 `json:"volume"`
LiquidationType int64 `json:"liquidation_type"`
} `json:"data"`
Timestamp int64 `json:"timestamp"`
}
// FOrderDetailsData stores order details for futures orders
type FOrderDetailsData struct {
Data struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
OrderPriceType string `json:"order_price_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"lever_rate"`
MarginFrozen float64 `json:"margin_frozen"`
Profit float64 `json:"profit"`
OrderSource string `json:"order_source"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
ClientOrderID int64 `json:"client_order_id"`
OrderType int64 `json:"order_type"`
Status int64 `json:"status"`
TradeVolume float64 `json:"trade_volume"`
TradeTurnover int64 `json:"trade_turnover"`
TradeAvgPrice float64 `json:"trade_avg_price"`
Fee float64 `json:"fee"`
CreatedAt int64 `json:"created_at"`
CanceledAt int64 `json:"canceled_at"`
FinalInterest float64 `json:"final_interest"`
AdjustValue int64 `json:"adjust_value"`
FeeAsset string `json:"fee_asset"`
Trades []struct {
ID string `json:"id"`
TradeID int64 `json:"trade_id"`
TradeVolume float64 `json:"trade_volume"`
TradePrice float64 `json:"trade_price"`
TradeFee float64 `json:"trade_fee"`
TradeTurnover float64 `json:"trade_turnover"`
Role string `json:"role"`
CreatedAt int64 `json:"created_at"`
} `json:"trades"`
TotalPage int64 `json:"total_page"`
TotalSize int64 `json:"total_size"`
CurrentPage int64 `json:"current_page"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FOpenOrdersData stores open orders data for futures
type FOpenOrdersData struct {
Data struct {
Orders []struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
OrderPriceType string `json:"order_price_type"`
OrderType int64 `json:"order_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_string"`
ClientOrderID int64 `json:"client_order_id"`
OrderSource string `json:"order_source"`
CreatedAt int64 `json:"created_at"`
TradeVolume float64 `json:"trade_volume"`
Fee float64 `json:"fee"`
TradeAvgPrice float64 `json:"trade_avg_price"`
MarginFrozen float64 `json:"margin_frozen"`
Profit float64 `json:"profit"`
Status int64 `json:"status"`
FeeAsset string `json:"fee_asset"`
} `json:"orders"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FOrderHistoryData stores order history data
type FOrderHistoryData struct {
Data struct {
Orders []struct {
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
OrderPriceType string `json:"order_price_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
OrderSource string `json:"order_source"`
CreateDate int64 `json:"create_date"`
TradeVolume float64 `json:"trade_volume"`
TradeTurnover float64 `json:"trade_turnover"`
Fee float64 `json:"fee"`
TradeAvgPrice float64 `json:"trade_avg_price"`
MarginFrozen float64 `json:"margin_frozen"`
Profit float64 `json:"profit"`
Status int64 `json:"status"`
OrderType int64 `json:"order_type"`
FeeAsset string `json:"fee_asset"`
LiquidationType int64 `json:"liquidation_type"`
} `json:"orders"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTradeHistoryData stores trade history data for futures
type FTradeHistoryData struct {
Data struct {
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
Trades []struct {
ID string `json:"id"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
CreateDate int64 `json:"create_date"`
Direction string `json:"direction"`
MatchID int64 `json:"match_id"`
Offset string `json:"offset"`
OffsetPNL float64 `json:"offset_profitloss"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
Symbol string `json:"symbol"`
OrderSource string `json:"order_source"`
TradeFee float64 `json:"trade_fee"`
TradePrice float64 `json:"trade_price"`
TradeTurnover float64 `json:"trade_turnover"`
TradeVolume float64 `json:"trade_volume"`
Role string `json:"role"`
FeeAsset string `json:"fee_asset"`
} `json:"trades"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTriggerOrderData stores trigger order data
type FTriggerOrderData struct {
Data struct {
OrderID int64 `json:"order_id"`
OrderIDStr string `json:"order_id_str"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTriggerOpenOrders stores trigger open orders data
type FTriggerOpenOrders struct {
Data struct {
Orders []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
TriggerType string `json:"trigger_type"`
Volume float64 `json:"volume"`
OrderType int64 `json:"order_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
OrderSource string `json:"order_source"`
TriggerPrice float64 `json:"trigger_price"`
OrderPrice float64 `json:"order_price"`
CreatedAt int64 `json:"created_at"`
OrderPriceType string `json:"order_price_type"`
Status int64 `json:"status"`
} `json:"orders"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}
// FTriggerOrderHistoryData stores trigger order history for futures
type FTriggerOrderHistoryData struct {
Data struct {
Orders []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
TriggerType string `json:"trigger_type"`
Volume float64 `json:"volume"`
OrderType int64 `json:"order_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate float64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
RelationOrderID string `json:"relation_order_id"`
OrderPriceType string `json:"order_price_type"`
Status string `json:"status"`
OrderSource string `json:"order_source"`
TriggerPrice int64 `json:"trigger_price"`
TriggeredPrice float64 `json:"triggered_price"`
OrderPrice float64 `json:"order_price"`
CreatedAt int64 `json:"created_at"`
TriggeredAt int64 `json:"triggered_at"`
OrderInsertAt float64 `json:"order_insert_at"`
CancelledAt int64 `json:"canceled_at"`
FailCode int64 `json:"fail_code"`
FailReason string `json:"fail_reason"`
} `json:"orders"`
TotalPage int64 `json:"total_page"`
CurrentPage int64 `json:"current_page"`
TotalSize int64 `json:"total_size"`
} `json:"data"`
Timestamp int64 `json:"ts"`
}

View File

@@ -15,17 +15,22 @@ import (
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
)
const (
huobiAPIURL = "https://api.huobi.pro"
huobiURL = "https://api.hbdm.com/"
huobiFuturesURL = "https://api.hbdm.com"
huobiAPIVersion = "1"
huobiAPIVersion2 = "2"
// Spot endpoints
huobiMarketHistoryKline = "market/history/kline"
huobiMarketDetail = "market/detail"
huobiMarketDetailMerged = "market/detail/merged"
huobi24HrMarketSummary = "/market/detail?"
huobiMarketDepth = "market/depth"
huobiMarketTrade = "market/trade"
huobiMarketTickers = "market/tickers"
@@ -56,6 +61,7 @@ const (
huobiWithdrawCreate = "dw/withdraw/api/create"
huobiWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobiStatusError = "error"
huobiMarginRates = "margin/loan-info"
)
// HUOBI is the overarching type across this package
@@ -64,11 +70,29 @@ type HUOBI struct {
AccountID string
}
// GetMarginRates gets margin rates
func (h *HUOBI) GetMarginRates(symbol currency.Pair) (MarginRatesData, error) {
var resp MarginRatesData
vals := url.Values{}
if symbol != (currency.Pair{}) {
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return resp, err
}
vals.Set("symbol", symbolValue)
}
return resp, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginRates, vals, nil, &resp, false)
}
// GetSpotKline returns kline data
// KlinesRequestParams contains symbol, period and size
// KlinesRequestParams contains symbol currency.Pair, period and size
func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) {
vals := url.Values{}
vals.Set("symbol", arg.Symbol)
symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
vals.Set("period", arg.Period)
if arg.Size != 0 {
@@ -81,26 +105,40 @@ func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) {
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketHistoryKline)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketHistoryKline, vals), &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
return result.Data, err
}
// Get24HrMarketSummary returns 24hr market summary for a given market symbol
func (h *HUOBI) Get24HrMarketSummary(symbol currency.Pair) (MarketSummary24Hr, error) {
var result MarketSummary24Hr
params := url.Values{}
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return result, err
}
params.Set("symbol", symbolValue)
return result, h.SendHTTPRequest(exchange.RestSpot, huobi24HrMarketSummary+params.Encode(), &result)
}
// GetTickers returns the ticker for the specified symbol
func (h *HUOBI) GetTickers() (Tickers, error) {
var result Tickers
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketTickers)
return result, h.SendHTTPRequest(urlPath, &result)
return result, h.SendHTTPRequest(exchange.RestSpot, "/"+huobiMarketTickers, &result)
}
// GetMarketDetailMerged returns the ticker for the specified symbol
func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) {
func (h *HUOBI) GetMarketDetailMerged(symbol currency.Pair) (DetailMerged, error) {
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return DetailMerged{}, err
}
vals.Set("symbol", symbolValue)
type response struct {
Response
@@ -108,9 +146,8 @@ func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) {
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketDetailMerged)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetailMerged, vals), &result)
if result.ErrorMessage != "" {
return result.Tick, errors.New(result.ErrorMessage)
}
@@ -120,7 +157,11 @@ func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) {
// GetDepth returns the depth for the specified symbol
func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) {
vals := url.Values{}
vals.Set("symbol", obd.Symbol)
symbolValue, err := h.FormatSymbol(obd.Symbol, asset.Spot)
if err != nil {
return Orderbook{}, err
}
vals.Set("symbol", symbolValue)
if obd.Type != OrderBookDataRequestParamsTypeNone {
vals.Set("type", string(obd.Type))
@@ -132,9 +173,8 @@ func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) {
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketDepth)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDepth, vals), &result)
if result.ErrorMessage != "" {
return result.Depth, errors.New(result.ErrorMessage)
}
@@ -142,9 +182,13 @@ func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) {
}
// GetTrades returns the trades for the specified symbol
func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) {
func (h *HUOBI) GetTrades(symbol currency.Pair) ([]Trade, error) {
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
type response struct {
Response
@@ -154,9 +198,8 @@ func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) {
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketTrade)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTrade, vals), &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
@@ -166,7 +209,7 @@ func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) {
// GetLatestSpotPrice returns latest spot price of symbol
//
// symbol: string of currency pair
func (h *HUOBI) GetLatestSpotPrice(symbol string) (float64, error) {
func (h *HUOBI) GetLatestSpotPrice(symbol currency.Pair) (float64, error) {
list, err := h.GetTradeHistory(symbol, 1)
if err != nil {
@@ -180,9 +223,13 @@ func (h *HUOBI) GetLatestSpotPrice(symbol string) (float64, error) {
}
// GetTradeHistory returns the trades for the specified symbol
func (h *HUOBI) GetTradeHistory(symbol string, size int64) ([]TradeHistory, error) {
func (h *HUOBI) GetTradeHistory(symbol currency.Pair, size int64) ([]TradeHistory, error) {
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
if size > 0 {
vals.Set("size", strconv.FormatInt(size, 10))
@@ -194,9 +241,8 @@ func (h *HUOBI) GetTradeHistory(symbol string, size int64) ([]TradeHistory, erro
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketTradeHistory)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTradeHistory, vals), &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
@@ -204,9 +250,13 @@ func (h *HUOBI) GetTradeHistory(symbol string, size int64) ([]TradeHistory, erro
}
// GetMarketDetail returns the ticker for the specified symbol
func (h *HUOBI) GetMarketDetail(symbol string) (Detail, error) {
func (h *HUOBI) GetMarketDetail(symbol currency.Pair) (Detail, error) {
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return Detail{}, err
}
vals.Set("symbol", symbolValue)
type response struct {
Response
@@ -214,9 +264,8 @@ func (h *HUOBI) GetMarketDetail(symbol string) (Detail, error) {
}
var result response
urlPath := fmt.Sprintf("%s/%s", h.API.Endpoints.URL, huobiMarketDetail)
err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result)
err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetail, vals), &result)
if result.ErrorMessage != "" {
return result.Tick, errors.New(result.ErrorMessage)
}
@@ -231,9 +280,8 @@ func (h *HUOBI) GetSymbols() ([]Symbol, error) {
}
var result response
urlPath := fmt.Sprintf("%s/v%s/%s", h.API.Endpoints.URL, huobiAPIVersion, huobiSymbols)
err := h.SendHTTPRequest(urlPath, &result)
err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiSymbols, &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
@@ -248,9 +296,8 @@ func (h *HUOBI) GetCurrencies() ([]string, error) {
}
var result response
urlPath := fmt.Sprintf("%s/v%s/%s", h.API.Endpoints.URL, huobiAPIVersion, huobiCurrencies)
err := h.SendHTTPRequest(urlPath, &result)
err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiCurrencies, &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
@@ -265,9 +312,8 @@ func (h *HUOBI) GetTimestamp() (int64, error) {
}
var result response
urlPath := fmt.Sprintf("%s/v%s/%s", h.API.Endpoints.URL, huobiAPIVersion, huobiTimestamp)
err := h.SendHTTPRequest(urlPath, &result)
err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiTimestamp, &result)
if result.ErrorMessage != "" {
return 0, errors.New(result.ErrorMessage)
}
@@ -279,7 +325,7 @@ func (h *HUOBI) GetAccounts() ([]Account, error) {
result := struct {
Accounts []Account `json:"data"`
}{}
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false)
return result.Accounts, err
}
@@ -291,7 +337,7 @@ func (h *HUOBI) GetAccountBalance(accountID string) ([]AccountBalanceDetail, err
endpoint := fmt.Sprintf(huobiAccountBalance, accountID)
v := url.Values{}
v.Set("account-id", accountID)
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, v, nil, &result, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, v, nil, &result, false)
return result.AccountBalanceData.AccountBalanceDetails, err
}
@@ -300,7 +346,7 @@ func (h *HUOBI) GetAggregatedBalance() ([]AggregatedBalance, error) {
result := struct {
AggregatedBalances []AggregatedBalance `json:"data"`
}{}
err := h.SendAuthenticatedHTTPRequest(
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot,
http.MethodGet,
huobiAggregatedBalance,
nil,
@@ -312,7 +358,12 @@ func (h *HUOBI) GetAggregatedBalance() ([]AggregatedBalance, error) {
}
// SpotNewOrder submits an order to Huobi
func (h *HUOBI) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) {
func (h *HUOBI) SpotNewOrder(arg *SpotNewOrderRequestParams) (int64, error) {
symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot)
if err != nil {
return 0, err
}
data := struct {
AccountID int `json:"account-id,string"`
Amount string `json:"amount"`
@@ -323,7 +374,7 @@ func (h *HUOBI) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) {
}{
AccountID: arg.AccountID,
Amount: strconv.FormatFloat(arg.Amount, 'f', -1, 64),
Symbol: arg.Symbol,
Symbol: symbolValue,
Type: string(arg.Type),
}
@@ -339,7 +390,7 @@ func (h *HUOBI) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) {
result := struct {
OrderID int64 `json:"data,string"`
}{}
err := h.SendAuthenticatedHTTPRequest(
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot,
http.MethodPost,
huobiOrderPlace,
nil,
@@ -356,7 +407,7 @@ func (h *HUOBI) CancelExistingOrder(orderID int64) (int64, error) {
OrderID int64 `json:"data,string"`
}{}
endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, url.Values{}, nil, &resp, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, url.Values{}, nil, &resp, false)
return resp.OrderID, err
}
@@ -368,7 +419,7 @@ func (h *HUOBI) CancelOrderBatch(_ []int64) ([]CancelOrderBatch, error) {
}
var result response
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result, false)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
@@ -377,9 +428,12 @@ func (h *HUOBI) CancelOrderBatch(_ []int64) ([]CancelOrderBatch, error) {
}
// CancelOpenOrdersBatch cancels a batch of orders -- to-do
func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrdersBatch, error) {
func (h *HUOBI) CancelOpenOrdersBatch(accountID string, symbol currency.Pair) (CancelOpenOrdersBatch, error) {
params := url.Values{}
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return CancelOpenOrdersBatch{}, err
}
params.Set("account-id", accountID)
var result CancelOpenOrdersBatch
@@ -388,10 +442,10 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrder
Symbol string `json:"symbol"`
}{
AccountID: accountID,
Symbol: symbol,
Symbol: symbolValue,
}
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false)
if result.Data.FailedCount > 0 {
return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount)
}
@@ -406,7 +460,7 @@ func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) {
}{}
urlVal := url.Values{}
urlVal.Set("clientOrderId", strconv.FormatInt(orderID, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodGet,
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet,
huobiGetOrder,
urlVal,
nil,
@@ -421,18 +475,22 @@ func (h *HUOBI) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) {
Orders []OrderMatchInfo `json:"data"`
}{}
endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, endpoint, url.Values{}, nil, &resp, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, url.Values{}, nil, &resp, false)
return resp.Orders, err
}
// GetOrders returns a list of orders
func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size string) ([]OrderInfo, error) {
func (h *HUOBI) GetOrders(symbol currency.Pair, types, start, end, states, from, direct, size string) ([]OrderInfo, error) {
resp := struct {
Orders []OrderInfo `json:"data"`
}{}
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
vals.Set("states", states)
if types != "" {
@@ -459,36 +517,44 @@ func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size
vals.Set("size", size)
}
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrders, vals, nil, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOrders, vals, nil, &resp, false)
return resp.Orders, err
}
// GetOpenOrders returns a list of orders
func (h *HUOBI) GetOpenOrders(accountID, symbol, side string, size int64) ([]OrderInfo, error) {
func (h *HUOBI) GetOpenOrders(symbol currency.Pair, accountID, side string, size int64) ([]OrderInfo, error) {
resp := struct {
Orders []OrderInfo `json:"data"`
}{}
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
vals.Set("accountID", accountID)
if len(side) > 0 {
vals.Set("side", side)
}
vals.Set("size", strconv.FormatInt(size, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false)
return resp.Orders, err
}
// GetOrdersMatch returns a list of matched orders
func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) {
func (h *HUOBI) GetOrdersMatch(symbol currency.Pair, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) {
resp := struct {
Orders []OrderMatchInfo `json:"data"`
}{}
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
if types != "" {
vals.Set("types", types)
@@ -514,18 +580,22 @@ func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size str
vals.Set("size", size)
}
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false)
return resp.Orders, err
}
// MarginTransfer transfers assets into or out of the margin account
func (h *HUOBI) MarginTransfer(symbol, currency string, amount float64, in bool) (int64, error) {
func (h *HUOBI) MarginTransfer(symbol currency.Pair, currency string, amount float64, in bool) (int64, error) {
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return 0, err
}
data := struct {
Symbol string `json:"symbol"`
Currency string `json:"currency"`
Amount string `json:"amount"`
}{
Symbol: symbol,
Symbol: symbolValue,
Currency: currency,
Amount: strconv.FormatFloat(amount, 'f', -1, 64),
}
@@ -538,18 +608,22 @@ func (h *HUOBI) MarginTransfer(symbol, currency string, amount float64, in bool)
resp := struct {
TransferID int64 `json:"data"`
}{}
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, path, nil, data, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, nil, data, &resp, false)
return resp.TransferID, err
}
// MarginOrder submits a margin order application
func (h *HUOBI) MarginOrder(symbol, currency string, amount float64) (int64, error) {
func (h *HUOBI) MarginOrder(symbol currency.Pair, currency string, amount float64) (int64, error) {
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return 0, err
}
data := struct {
Symbol string `json:"symbol"`
Currency string `json:"currency"`
Amount string `json:"amount"`
}{
Symbol: symbol,
Symbol: symbolValue,
Currency: currency,
Amount: strconv.FormatFloat(amount, 'f', -1, 64),
}
@@ -557,7 +631,7 @@ func (h *HUOBI) MarginOrder(symbol, currency string, amount float64) (int64, err
resp := struct {
MarginOrderID int64 `json:"data"`
}{}
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiMarginOrders, nil, data, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiMarginOrders, nil, data, &resp, false)
return resp.MarginOrderID, err
}
@@ -574,14 +648,18 @@ func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) {
}{}
endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, nil, data, &resp, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, nil, data, &resp, false)
return resp.MarginOrderID, err
}
// GetMarginLoanOrders returns the margin loan orders
func (h *HUOBI) GetMarginLoanOrders(symbol, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) {
func (h *HUOBI) GetMarginLoanOrders(symbol currency.Pair, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) {
vals := url.Values{}
vals.Set("symbol", symbol)
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return nil, err
}
vals.Set("symbol", symbolValue)
vals.Set("currency", currency)
if start != "" {
@@ -611,20 +689,24 @@ func (h *HUOBI) GetMarginLoanOrders(symbol, currency, start, end, states, from,
resp := struct {
MarginLoanOrders []MarginOrder `json:"data"`
}{}
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false)
err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false)
return resp.MarginLoanOrders, err
}
// GetMarginAccountBalance returns the margin account balances
func (h *HUOBI) GetMarginAccountBalance(symbol string) ([]MarginAccountBalance, error) {
func (h *HUOBI) GetMarginAccountBalance(symbol currency.Pair) ([]MarginAccountBalance, error) {
resp := struct {
Balances []MarginAccountBalance `json:"data"`
}{}
vals := url.Values{}
if symbol != "" {
vals.Set("symbol", symbol)
if symbol != (currency.Pair{}) {
symbolValue, err := h.FormatSymbol(symbol, asset.Spot)
if err != nil {
return resp.Balances, err
}
vals.Set("symbol", symbolValue)
}
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false)
return resp.Balances, err
}
@@ -654,7 +736,7 @@ func (h *HUOBI) Withdraw(c currency.Code, address, addrTag string, amount, fee f
data.AddrTag = addrTag
}
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiWithdrawCreate, nil, data, &resp.WithdrawID, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiWithdrawCreate, nil, data, &resp.WithdrawID, false)
return resp.WithdrawID, err
}
@@ -667,7 +749,7 @@ func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) {
vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10))
endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10))
err := h.SendAuthenticatedHTTPRequest(http.MethodPost, endpoint, vals, nil, &resp, false)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, vals, nil, &resp, false)
return resp.WithdrawID, err
}
@@ -680,7 +762,7 @@ func (h *HUOBI) QueryDepositAddress(cryptocurrency string) (DepositAddress, erro
vals := url.Values{}
vals.Set("currency", cryptocurrency)
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true)
if err != nil {
return DepositAddress{}, err
}
@@ -699,7 +781,7 @@ func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error
vals := url.Values{}
vals.Set("currency", cryptocurrency)
err := h.SendAuthenticatedHTTPRequest(http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true)
err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true)
if err != nil {
return WithdrawQuota{}, err
}
@@ -707,23 +789,41 @@ func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (h *HUOBI) SendHTTPRequest(path string, result interface{}) error {
return h.SendPayload(context.Background(), &request.Item{
func (h *HUOBI) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error {
endpoint, err := h.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
var tempResp json.RawMessage
var errCap errorCapture
err = h.SendPayload(context.Background(), &request.Item{
Method: http.MethodGet,
Path: path,
Result: result,
Path: endpoint + path,
Result: &tempResp,
Verbose: h.Verbose,
HTTPDebugging: h.HTTPDebugging,
HTTPRecording: h.HTTPRecording,
})
if err != nil {
return err
}
if err := json.Unmarshal(tempResp, &errCap); err == nil {
if errCap.Code != 200 && errCap.ErrMsg != "" {
return errors.New(errCap.ErrMsg)
}
}
return json.Unmarshal(tempResp, result)
}
// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API
func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, data, result interface{}, isVersion2API bool) error {
func (h *HUOBI) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, values url.Values, data, result interface{}, isVersion2API bool) error {
if !h.AllowAuthenticatedRequest() {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name)
}
ePoint, err := h.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
if values == nil {
values = url.Values{}
}
@@ -735,9 +835,9 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url
values.Set("Timestamp", now.UTC().Format("2006-01-02T15:04:05"))
if isVersion2API {
endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion2, endpoint)
endpoint = "/v" + huobiAPIVersion2 + "/" + endpoint
} else {
endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion, endpoint)
endpoint = "/v" + huobiAPIVersion + "/" + endpoint
}
payload := fmt.Sprintf("%s\napi.huobi.pro\n%s\n%s",
@@ -753,22 +853,21 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url
hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(payload), []byte(h.API.Credentials.Secret))
values.Set("Signature", crypto.Base64Encode(hmac))
urlPath := h.API.Endpoints.URL + common.EncodeURLValues(endpoint, values)
urlPath := ePoint + common.EncodeURLValues(endpoint, values)
var body []byte
if data != nil {
encoded, err := json.Marshal(data)
body, err = json.Marshal(data)
if err != nil {
return err
}
body = encoded
}
// Time difference between your timestamp and standard should be less than 1 minute.
ctx, cancel := context.WithDeadline(context.Background(), now.Add(time.Minute))
defer cancel()
interim := json.RawMessage{}
err := h.SendPayload(ctx, &request.Item{
err = h.SendPayload(ctx, &request.Item{
Method: method,
Path: urlPath,
Headers: headers,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,416 @@
package huobi
import (
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
)
type errorCapture struct {
Status string `json:"status"`
Code int64 `json:"err_code"`
ErrMsg string `json:"err_msg"`
Timestamp int64 `json:"ts"`
}
// MarketSummary24Hr stores past 24hr market summary data of a given symbol
type MarketSummary24Hr struct {
Tick struct {
Amount float64 `json:"amount"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
ID int64 `json:"id"`
Count float64 `json:"count"`
Low float64 `json:"low"`
Version int64 `json:"version"`
Volume float64 `json:"vol"`
}
}
// WsKlineData stores kline data for futures and swap websocket
type WsKlineData struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
ID int64 `json:"id"`
MRID int64 `json:"mrid"`
Volume float64 `json:"vol"`
Count float64 `json:"count"`
Open float64 `json:"open"`
Close float64 `json:"close"`
Low float64 `json:"low"`
High float64 `json:"high"`
Amount float64 `json:"amount"`
} `json:"tick"`
}
// WsMarketDepth stores market depth data for futures and swap websocket
type WsMarketDepth struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
MRID int64 `json:"mrid"`
ID int64 `json:"id"`
Bids [][2]float64 `json:"bids"`
Asks [][2]float64 `json:"asks"`
Timestamp int64 `json:"ts"`
Version int64 `json:"version"`
Channel string `json:"ch"`
} `json:"tick"`
}
// WsIncrementalMarketDepth stores incremental market depth data for swap and futures websocket
type WsIncrementalMarketDepth struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
MRID int64 `json:"mrid"`
ID int64 `json:"id"`
Bids [][2]float64 `json:"bids"`
Asks [][2]float64 `json:"asks"`
Timestamp int64 `json:"ts"`
Version int64 `json:"version"`
Channel string `json:"ch"`
Event string `json:"event"`
} `json:"tick"`
}
// WsMarketDetail stores market detail data for futures and swap websocket
type WsMarketDetail struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
ID int64 `json:"id"`
MRID int64 `json:"mrid"`
Open float64 `json:"open"`
Close float64 `json:"close"`
High float64 `json:"high"`
Low float64 `json:"low"`
Amount float64 `json:"amount"`
Volume float64 `json:"vol"`
Count float64 `json:"count"`
} `json:"tick"`
}
// WsMarketBBOData stores BBO data for futures and swap websocket
type WsMarketBBOData struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
Channel string `json:"ch"`
MRID int64 `json:"mrid"`
ID int64 `json:"id"`
Bid [2]float64 `json:"bid"`
Ask [2]float64 `json:"ask"`
Timestamp int64 `json:"ts"`
Version int64 `json:":version"`
} `json:"tick"`
}
// WsSubTradeDetail stores trade detail data for futures websocket
type WsSubTradeDetail struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
ID int64 `json:"id"`
Timestamp int64 `json:"ts"`
Data []struct {
Amount float64 `json:"amount"`
Timestamp int64 `json:"ts"`
ID int64 `json:"id"`
Price float64 `json:"price"`
Direction string `json:"direction"`
} `json:"data"`
} `json:"tick"`
}
//
// Futures
// FWsRequestKline stores requested kline data for futures websocket
type FWsRequestKline struct {
Rep string `json:"rep"`
ID string `json:"id"`
WsID int64 `json:"wsid"`
Tick []struct {
Volume float64 `json:"vol"`
Count float64 `json:"count"`
ID int64 `json:"id"`
Open float64 `json:"open"`
Close float64 `json:"close"`
Low float64 `json:"low"`
High float64 `json:"high"`
Amount float64 `json:"amount"`
} `json:"tick"`
}
// FWsReqTradeDetail stores requested trade detail data for futures websocket
type FWsReqTradeDetail struct {
Rep string `json:"rep"`
ID string `json:"id"`
Timestamp int64 `json:"ts"`
Data []struct {
ID int64 `json:"id"`
Price float64 `json:"price"`
Amount float64 `json:"amount"`
Direction string `json:"direction"`
Timestamp int64 `json:"ts"`
} `json:"data"`
}
// FWsSubKlineIndex stores subscribed kline index data for futures websocket
type FWsSubKlineIndex struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
ID string `json:"id"`
Open float64 `json:"open,string"`
Close float64 `json:"close,string"`
High float64 `json:"high,string"`
Low float64 `json:"low,string"`
Amount float64 `json:"amount,string"`
Volume float64 `json:"vol,string"`
Count float64 `json:"count,string"`
} `json:"tick"`
}
// FWsReqKlineIndex stores requested kline index data for futures websocket
type FWsReqKlineIndex struct {
ID string `json:"id"`
Rep string `json:"rep"`
WsID int64 `json:"wsid"`
Timestamp int64 `json:"ts"`
Data []struct {
ID int64 `json:"id"`
Open float64 `json:"open"`
Close float64 `json:"close"`
Low float64 `json:"low"`
High float64 `json:"high"`
Amount float64 `json:"amount"`
Volume float64 `json:"vol"`
Count float64 `json:"count"`
} `json:"data"`
}
// FWsSubBasisData stores subscribed basis data for futures websocket
type FWsSubBasisData struct {
Channel string `json:"ch"`
Timestamp int64 `json:"ts"`
Tick struct {
ID int64 `json:"id"`
IndexPrice float64 `json:"index_price,string"`
ContractPrice float64 `json:"contract_price,string"`
Basis float64 `json:"basis,string"`
BasisRate float64 `json:"basis_rate,string"`
}
}
// FWsReqBasisData stores requested basis data for futures websocket
type FWsReqBasisData struct {
ID string `json:"id"`
Rep string `json:"rep"`
Timestamp int64 `json:"ts"`
WsID int64 `json:"wsid"`
Tick struct {
ID int64 `json:"id"`
IndexPrice float64 `json:"index_price,string"`
ContractPrice float64 `json:"contract_price,string"`
Basis float64 `json:"basis,string"`
BasisRate float64 `json:"basis_rate,string"`
} `json:"tick"`
}
// FWsSubOrderData stores subscribed order data for futures websocket
type FWsSubOrderData struct {
Operation string `json:"op"`
Topic string `json:"topic"`
UID string `json:"uid"`
Timestamp int64 `json:"ts"`
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
OrderPriceType string `json:"order_price_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
Status int64 `json:"status"`
LeverageRate int64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_string"`
ClientOrderID int64 `json:"client_order_id"`
OrderSource string `json:"order_source"`
OrderType int64 `json:"order_type"`
CreatedAt int64 `json:"created_at"`
TradeVolume float64 `json:"trade_volume"`
TradeTurnover float64 `json:"trade_turnover"`
Fee float64 `json:"fee"`
TradeAvgPrice float64 `json:"trade_avg_price"`
MarginFrozen float64 `json:"margin_frozen"`
Profit float64 `json:"profit"`
FeeAsset string `json:"fee_asset"`
CancelledAt int64 `json:"canceled_at"`
Trade []struct {
ID string `json:"id"`
TradeID int64 `json:"trade_id"`
TradeVolume float64 `json:"trade_volume"`
TradePrice float64 `json:"trade_price"`
TradeFee float64 `json:"trade_fee"`
TradeTurnover float64 `json:"trade_turnover"`
CreatedAt int64 `json:"created_at"`
Role string `json:"role"`
FeeAsset string `json:"fee_asset"`
} `json:"trade"`
}
// FWsSubMatchOrderData stores subscribed match order data for futures websocket
type FWsSubMatchOrderData struct {
Operation string `json:"op"`
Topic string `json:"topic"`
UID string `json:"uid"`
Timestamp int64 `json:"ts"`
Symbol string `json:"symbol"`
ContractType string `json:"contract_type"`
ContractCode string `json:"contract_code"`
Status int64 `json:"status"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_string"`
OrderType string `json:"order_type"`
Volume float64 `json:"volume"`
TradeVolume float64 `json:"trade_volume"`
ClientOrderID int64 `json:"client_order_id"`
Trade []struct {
ID string `json:"id"`
TradeID int64 `json:"trade_id"`
TradeVolume float64 `json:"trade_volume"`
TradePrice float64 `json:"trade_price"`
TradeTurnover float64 `json:"trade_turnover"`
CreatedAt int64 `json:"created_at"`
Role string `json:"role"`
}
}
// FWsSubEquityUpdates stores account equity updates data for futures websocket
type FWsSubEquityUpdates struct {
Operation string `json:"op"`
Topic string `json:"topic"`
UID string `json:"uid"`
Timestamp int64 `json:"ts"`
Event string `json:"event"`
Data []struct {
Symbol string `json:"symbol"`
MarginBalance float64 `json:"margin_balance"`
MarginStatic int64 `json:"margin_static"`
MarginPosition float64 `json:"margin_position"`
MarginFrozen float64 `json:"margin_frozen"`
MarginAvailable float64 `json:"margin_available"`
ProfitReal float64 `json:"profit_real"`
ProfitUnreal float64 `json:"profit_unreal"`
WithdrawAvailable float64 `json:"withdraw_available"`
RiskRate float64 `json:"risk_rate"`
LiquidationPrice float64 `json:"liquidation_price"`
LeverageRate float64 `json:"lever_rate"`
AdjustFactor float64 `json:"adjust_factor"`
} `json:"data"`
}
// FWsSubPositionUpdates stores subscribed position updates data for futures websocket
type FWsSubPositionUpdates struct {
Operation string `json:"op"`
Topic string `json:"topic"`
UID string `json:"uid"`
Timestamp int64 `json:"ts"`
Event string `json:"event"`
PositionsData []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
Volume float64 `json:"volume"`
Available float64 `json:"available"`
Frozen float64 `json:"frozen"`
CostOpen float64 `json:"cost_open"`
CostHold float64 `json:"cost_hold"`
ProfitUnreal float64 `json:"profit_unreal"`
ProfitRate float64 `json:"profit_rate"`
Profit float64 `json:"profit"`
PositionMargin float64 `json:"position_margin"`
LeverageRate float64 `json:"lever_rate"`
Direction string `json:"direction"`
LastPrice float64 `json:"last_price"`
} `json:"data"`
}
// FWsSubLiquidationOrders stores subscribed liquidation orders data for futures websocket
type FWsSubLiquidationOrders struct {
Operation string `json:"op"`
Topic string `json:"topic"`
Timestamp int64 `json:"ts"`
OrdersData []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
Direction string `json:"direction"`
Offset string `json:"offset"`
Volume float64 `json:"volume"`
Price float64 `json:"price"`
CreatedAt int64 `json:"created_at"`
} `json:"data"`
}
// FWsSubContractInfo stores contract info data for futures websocket
type FWsSubContractInfo struct {
Operation string `json:"op"`
Topic string `json:"topic"`
Timestamp int64 `json:"ts"`
Event string `json:"event"`
ContractData []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
ContractSize float64 `json:"contract_size"`
PriceTick float64 `json:"price_tick"`
DeliveryDate string `json:"delivery_date"`
CreateDate string `json:"create_date"`
ContractStatus int64 `json:"contract_status"`
} `json:"data"`
}
// FWsSubTriggerOrderUpdates stores subscribed trigger order updates data for futures websocket
type FWsSubTriggerOrderUpdates struct {
Operation string `json:"op"`
Topic string `json:"topic"`
UID string `json:"uid"`
Event string `json:"event"`
Data []struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractType string `json:"contract_type"`
TriggerType string `json:"trigger_type"`
Volume float64 `json:"volume"`
OrderType int64 `json:"order_type"`
Direction string `json:"direction"`
Offset string `json:"offset"`
LeverageRate int64 `json:"lever_rate"`
OrderID int64 `json:"order_id"`
OrderIDString string `json:"order_id_str"`
RelationOrderID string `json:"relation_order_id"`
OrderPriceType string `json:"order_price_type"`
Status int64 `json:"status"`
OrderSource string `json:"order_source"`
TriggerPrice float64 `json:"trigger_price"`
TriggeredPrice float64 `json:"triggered_price"`
OrderPrice float64 `json:"order_price"`
CreatedAt int64 `json:"created_at"`
TriggeredAt int64 `json:"triggered_at"`
OrderInsertAt int64 `json:"order_insert_at"`
CancelledAt int64 `json:"canceled_at"`
FailCode int64 `json:"fail_code"`
FailReason string `json:"fail_reason"`
} `json:"data"`
}
// --------------------------------Spot-----------------------------------------
// Response stores the Huobi response information
type Response struct {
Status string `json:"status"`
@@ -9,12 +420,38 @@ type Response struct {
ErrorMessage string `json:"err-msg"`
}
// MarginRatesData stores margin rates data
type MarginRatesData struct {
Data []struct {
Symbol string `json:"symbol"`
Currencies []struct {
Currency string `json:"currency"`
InterestRate float64 `json:"interest-rate,string"`
MinLoanAmount float64 `json:"min-loan-amt,string"`
MaxLoanAmount float64 `json:"max-loan-amt,string"`
LoanableAmount float64 `json:"loanable-amt,string"`
ActualRate float64 `json:"actual-rate,string"`
} `json:"currencies"`
} `json:"data"`
}
// ResponseV2 stores the Huobi generic response info
type ResponseV2 struct {
Code int32 `json:"code"`
Message string `json:"message"`
}
// SwapMarketsData stores market data for swaps
type SwapMarketsData struct {
Symbol string `json:"symbol"`
ContractCode string `json:"contract_code"`
ContractSize float64 `json:"contract_size"`
PriceTick float64 `json:"price_tick"`
SettlementDate string `json:"settlement_date"`
CreateDate string `json:"create_date"`
ContractStatus int64 `json:"contract_status"`
}
// KlineItem stores a kline item
type KlineItem struct {
ID int64 `json:"id"`
@@ -79,8 +516,8 @@ var (
// OrderBookDataRequestParams represents Klines request data.
type OrderBookDataRequestParams struct {
Symbol string `json:"symbol"` // Required; example LTCBTC,BTCUSDT
Type OrderBookDataRequestParamsType `json:"type"` // step0, step1, step2, step3, step4, step5 (combined depth 0-5); when step0, no depth is merged
Symbol currency.Pair // Required; example LTCBTC,BTCUSDT
Type OrderBookDataRequestParamsType `json:"type"` // step0, step1, step2, step3, step4, step5 (combined depth 0-5); when step0, no depth is merged
}
// Orderbook stores the orderbook data
@@ -122,17 +559,25 @@ type Detail struct {
// Symbol stores the symbol data
type Symbol struct {
BaseCurrency string `json:"base-currency"`
QuoteCurrency string `json:"quote-currency"`
PricePrecision int `json:"price-precision"`
AmountPrecision int `json:"amount-precision"`
SymbolPartition string `json:"symbol-partition"`
Innovation string `json:"innovation"`
State string `json:"state"`
ValuePrecision int `json:"value-precision"`
MinimumOrderAmount float64 `json:"min-order-amt"`
MaximumOrderAmount float64 `json:"max-order-amt"`
MinimumOrderValue float64 `json:"min-order-value"`
BaseCurrency string `json:"base-currency"`
QuoteCurrency string `json:"quote-currency"`
PricePrecision float64 `json:"price-precision"`
AmountPrecision float64 `json:"amount-precision"`
SymbolPartition string `json:"symbol-partition"`
Symbol string `json:"symbol"`
State string `json:"state"`
ValuePrecision float64 `json:"value-precision"`
MinOrderAmt float64 `json:"min-order-amt"`
MaxOrderAmt float64 `json:"max-order-amt"`
MinOrderValue float64 `json:"min-order-value"`
LimitOrderMinOrderAmt float64 `json:"limit-order-min-order-amt"`
LimitOrderMaxOrderAmt float64 `json:"limit-order-max-order-amt"`
SellMarketMinOrderAmt float64 `json:"sell-market-min-order-amt"`
SellMarketMaxOrderAmt float64 `json:"sell-market-max-order-amt"`
BuyMarketMaxOrderAmt float64 `json:"buy-market-max-order-amt"`
LeverageRatio float64 `json:"leverage-ratio"`
SuperMarginLeverageRatio float64 `json:"super-margin-leverage-ratio"`
FundingLeverageRatio float64 `json:"funding-leverage-ratio"`
}
// Account stores the account data
@@ -248,7 +693,7 @@ type SpotNewOrderRequestParams struct {
Amount float64 `json:"amount"` // The limit price indicates the quantity of the order, the market price indicates how much to buy when the order is paid, and the market price indicates how much the coin is sold when the order is sold.
Price float64 `json:"price"` // Order price, market price does not use this parameter
Source string `json:"source"` // Order source, api: API call, margin-api: loan asset transaction
Symbol string `json:"symbol"` // The symbol to use; example btcusdt, bccbtc......
Symbol currency.Pair `json:"symbol"` // The symbol to use; example btcusdt, bccbtc......
Type SpotNewOrderRequestParamsType `json:"type"` // 订单类型, buy-market: 市价买, sell-market: 市价卖, buy-limit: 限价买, sell-limit: 限价卖
}
@@ -299,9 +744,9 @@ var (
// KlinesRequestParams represents Klines request data.
type KlinesRequestParams struct {
Symbol string // Symbol to be used; example btcusdt, bccbtc......
Period string // Kline time interval; 1min, 5min, 15min......
Size int // Size; [1-2000]
Symbol currency.Pair // Symbol to be used; example btcusdt, bccbtc......
Period string // Kline time interval; 1min, 5min, 15min......
Size int // Size; [1-2000]
}
// WsRequest defines a request data structure
@@ -597,3 +1042,167 @@ type authenticationPing struct {
OP string `json:"op"`
TS int64 `json:"ts"`
}
// OrderVars stores side, status and type for any order/trade
type OrderVars struct {
Side order.Side
Status order.Status
OrderType order.Type
Fee float64
}
// Variables below are used to check api requests being sent out
var (
validPeriods = []string{"5min", "15min", "30min", "60min", "4hour", "1day"}
validBasisPriceTypes = []string{"open", "close", "high", "low", "average"}
validAmountType = map[string]int64{
"cont": 1,
"cryptocurrency": 2,
}
validTransferType = []string{
"master_to_sub", "sub_to_master",
}
validTradeTypes = map[string]int64{
"filled": 0,
"closed": 5,
"open": 6,
}
validOrderType = map[string]int64{
"quotation": 1,
"cancelledOrder": 2,
"forcedLiquidation": 3,
"deliveryOrder": 4,
}
validOrderTypes = []string{
"limit", "opponent", "lightning", "optimal_5", "optimal_10", "optimal_20",
"fok", "ioc", "opponent_ioc", "lightning_ioc", "optimal_5_ioc",
"optimal_10_ioc", "optimal_20_ioc", "opponent_fok", "optimal_20_fok",
}
validTriggerType = map[string]string{
"greaterOrEqual": "ge",
"smallerOrEqual": "le",
}
validOrderPriceType = []string{
"limit", "optimal_5", "optimal_10", "optimal_20",
}
validLightningOrderPriceType = []string{
"lightning", "lightning_fok", "lightning_ioc",
}
validTradeType = map[string]int64{
"all": 0,
"openLong": 1,
"openShort": 2,
"closeShort": 3,
"closeLong": 4,
"liquidateLong": 5,
"liquidateShort": 6,
}
validFuturesTradeType = map[string]int64{
"all": 0,
"openLong": 1,
"openShort": 2,
"closeShort": 3,
"closeLong": 4,
"liquidateLong": 5,
"liquidateShort": 6,
"deliveryLong": 7,
"deliveryShort": 8,
"reduceLong": 11,
"reduceShort": 12,
}
validContractTypes = []string{
"this_week", "next_week", "quarter", "next_quarter",
}
validFuturesPeriods = []string{
"1min", "5min", "15min", "30min", "60min", "1hour", "4hour", "1day",
}
validFuturesOrderPriceTypes = []string{
"limit", "opponent", "lightning", "optimal_5", "optimal_10",
"optimal_20", "fok", "ioc", "opponent_ioc", "lightning_ioc",
"optimal_5_ioc", "optimal_10_ioc", "optimal_20_ioc", "opponent_fok",
"lightning_fok", "optimal_5_fok", "optimal_10_fok", "optimal_20_fok",
}
validFuturesRecordTypes = map[string]string{
"closeLong": "3",
"closeShort": "4",
"openOpenPositionsTakerFees": "5",
"openPositionsMakerFees": "6",
"closePositionsTakerFees": "7",
"closePositionsMakerFees": "8",
"closeLongDelivery": "9",
"closeShortDelivery": "10",
"deliveryFee": "11",
"longLiquidationClose": "12",
"shortLiquidationClose": "13",
"transferFromSpotToContracts": "14",
"transferFromContractsToSpot": "15",
"settleUnrealizedLongPNL": "16",
"settleUnrealizedShortPNL": "17",
"clawback": "19",
"system": "26",
"activityPrizeRewards": "28",
"rebate": "29",
"transferToSub": "34",
"transferFromSub": "35",
"transferToMaster": "36",
"transferFromMaster": "37",
}
validOffsetTypes = []string{
"open", "close",
}
validOPTypes = []string{
"lightning", "lightning_fok", "lightning_ioc",
}
validFuturesReqType = map[string]int64{
"all": 1,
"finishedStatus": 2,
}
validFuturesOrderTypes = map[string]int64{
"limit": 1,
"opponent": 3,
"lightning": 4,
"triggerOrder": 5,
"postOnly": 6,
"optimal_5": 7,
"optimal_10": 8,
"optimal_20": 9,
"fok": 10,
"ioc": 11,
}
validOrderStatus = map[order.Status]int64{
order.AnyStatus: 0,
order.Active: 3,
order.PartiallyFilled: 4,
order.PartiallyCancelled: 5,
order.Filled: 6,
order.Cancelled: 7,
}
validStatusTypes = map[string]int64{
"all": 0,
"success": 4,
"failed": 5,
"cancelled": 6,
}
)

View File

@@ -25,7 +25,8 @@ import (
)
const (
baseWSURL = "wss://api.huobi.pro"
baseWSURL = "wss://api.huobi.pro"
futuresWSURL = "wss://api.hbdm.com/"
wsMarketURL = baseWSURL + "/ws"
wsMarketKline = "market.%s.kline.1min"

File diff suppressed because it is too large Load Diff