4
ध्यान केंद्रित करना
1271
समर्थक

आविष्कारक का मात्रात्मक व्यापार मंच सार्वभौमिक प्रोटोकॉल कस्टम एक्सचेंज से जुड़ा हुआ है

में बनाया: 2017-08-24 16:29:56, को अपडेट: 2021-06-10 15:33:02
comments   23
hits   17429

जीएमओ दस्तावेज़ीकरण

इस जीपीओ का उपयोग कर किसी भी सेवा तक पहुंच सकते हैंAPIव्यापार के लिए एक्सचेंजों, विशिष्ट एपीआई प्रोटोकॉल के बिना, या तोrestwebsocketfix… का उपयोग किया जा सकता है. पाइथन जनरल प्रोटोकॉल उदाहरणः https://www.fmz.com/strategy/101399

  • ### 1. जीपीएस प्लगइन चलाना, पोर्ट सेटिंग

एक अच्छी तरह से लिखा गया जीपीएस प्लगइन टूलकिट के मॉनिटरिंग पते और पोर्ट सेटिंग्स उदाहरण:http://127.0.0.1:6666/DigitalAssetया फिर:http://127.0.0.1:6666/exchange

यह सब क्यों बनाया गया?IPरास्ताऊनी कपड़े? क्योंकिआविष्कारक की मात्रापृष्ठनियंत्रण केंद्रकूदोएक्सचेंज जोड़ेंपृष्ठ, चयन करें जीपीओ फलक, के अलावा प्रदर्शित करेंAPI-KEY, और एक सेवा पता बॉक्स है, यह सेवा पता है कि यह बताने के लिए कि क्या आईपी और बंदरगाहों के लिए समय आ गया है ((मेजबान और जीपीओ प्लगइन एक ही डिवाइस पर नहीं चल सकता है)) । सेवा पता उदाहरण भरनाhttp://127.0.0.1:6666/DigitalAssetDigitalAssetयह एक उदाहरण के रूप में अपना नाम है।

आविष्कारकों के लिए, एक्सचेंज का पृष्ठ इस प्रकार है: आम तौर पर, एक्सचेंजों को केवल कॉन्फ़िगर करने की आवश्यकता होती हैaccess keyऔरsecret keyलेकिन कुछ एक्सचेंजों के एपीआई इंटरफेस के लिए आवश्यक है कि ट्रेडिंग पासवर्ड (जैसे कि कुछ एक्सचेंजों के ऑर्डर इंटरफेस) को प्रसारित किया जाए, जब सामान्य प्रोटोकॉल पेज के पास इन सूचनाओं को लिखने के लिए कोई अतिरिक्त नियंत्रण नहीं होता है, तो हम इस तरह के एक्सचेंजों के एपीआई के साथ आने पर, हम अतिरिक्त आवश्यकताओं को प्रसारित करने के लिए कॉन्फ़िगरेशन जानकारी लिख सकते हैंsecret keyयदि जानकारी संवेदनशील नहीं है, तो इसे लिख सकते हैंaccess key), फिर जीपीएस प्लगइन में स्ट्रिंग के रूप मेंsplitऑपरेशन, इन आंकड़ों को अलग करें, जैसा कि चित्रित उदाहरण में दिखाया गया है।

आविष्कारक का मात्रात्मक व्यापार मंच सार्वभौमिक प्रोटोकॉल कस्टम एक्सचेंज से जुड़ा हुआ है

और फिर प्लगइन में इसे संसाधित करने के लिए, यह हैXXX_PassWord。 उदाहरण के लिए, इस पोस्ट के अंतिम पूर्ण उदाहरण में, newBitgo फ़ंक्शनः

  func newBitgo(accessKey, secretKey string) *iBitgo {
      s := new(iBitgo)
      s.accessKey = accessKey
      s.secretKey = secretKey
      // 在此可以分离secretKey中的额外配置信息,可以写成如下注释中的内容
      /*
      arr := strings.SplitN(secretKey, ",", 2)
      if len(arr) != 2 {
          panic("配置错误!")
      }
      s.secretKey = arr[0]   // secret key 
      s.passWord = arr[1]    // XXX_PassWord
      */
      s.apiBase = "https://www.bitgo.cn"
      s.timeout = 20 * time.Second
      s.timeLocation = time.FixedZone("Asia/Shanghai", 8*60*60)

      return s
  }

आविष्कारक का मात्रात्मक व्यापार मंच सार्वभौमिक प्रोटोकॉल कस्टम एक्सचेंज से जुड़ा हुआ है

समग्र जीपीओ प्लगइनmainफ़ंक्शन का उदाहरण: Goभाषा का वर्णन:

  func main(){
      var addr = flag.String("b", "127.0.0.1:6666", "bing addr")   // 设置命令行参数,默认值描述,端口设置6666
      flag.Parse()                                                 // 解析命令行
      if *addr == "" {
          flag.Usage()                                             // 显示命令行描述
          return 
      }
      basePath := "/DigitalAsset"
      log.Println("Running ", fmt.Sprintf("http://%s%s", *addr, basePath), "...")   // 打印监听端口信息
      http.HandleFunc(basePath, OnPost)
      http.ListenAndServe(*addr, nil)
  }
  • #### 2. प्रतिक्रिया फ़ंक्शन

एक जीपीएस प्लगइन को बंद कर दिया है और एक विशिष्ट बंदरगाहों पर लगातार मॉनिटरिंग के लिए अनुरोध भेजने के लिएrequestएक बार जब अनुरोध किया जाता है, तो प्रतिक्रिया फ़ंक्शन को प्रतिक्रिया निष्पादन के लिए बुलाया जाता है, फिर अनुरोध डेटा में पैरामीटर को पार्स किया जाता है, और होस्ट द्वारा भेजा गया अनुरोध डेटा हैः

  /* request的JSON结构,发明者量化调用GetTicker,托管者发送给通用协议插件情况举例(各个API调用时,params的值可能不一样,此处method为ticker):
  {
      "access_key" : "XXX",               // `json:"access_key"`
      "secret_key" : "XXX",               // `json:"secret_key"`
      "nonce" : "1502345965295519602",    // `json:"nonce"`
      "method" : "ticker",                // `json:"method"`
      "params" : {                        // `json:"params"`
                     "symbol" : "btc",
                     ...
                 },                       // 各个请求参数略有区别。即在策略中调用不同的 发明者量化 API会有不同的参数, 在下文各个API 有介绍说明。
  }
  */

इसलिए जीपीएस प्लगइन में प्राप्त अनुरोध बॉडी डेटा के आधार पर JSON अनुक्रमण के बाद प्राप्त संरचनाrequestमेंMethodहम इसका उपयोग कर सकते हैंswitchवर्गीकृत करने के लिए विभिन्न आविष्कारकों की मात्रा पर एपीआई (((यानी पहचान करने के लिए कि कौन सा आविष्कारक की मात्रा पर होस्ट पर चल रही नीति को बुलाया गया हैAPI) कॉल करेंः

Goभाषा उदाहरण:

  switch request.Method {    // 此处request.Method的M为大写,通用协议程序接收到的请求主体中为JSON数据,在Go语言中反JSON序列化(Unmarshal)为结构体,字段首字母必须大写
    case "accounts" :        // 当托管者上的机器人策略中调用了exchange.GetAccount()函数,托管者会发送来请求,其中Body携带的数据中method属性值为accounts
        data, err = e.GetAccount(symbol)
    case "ticker" :
        data, err = e.GetTicker(symbol)
    case "depth" :
        data, err = e.GetDepth(symbol)
    case "trades" :
        data, err = e.GetTrades(symbol)
    case "trade" :
    ...
    default:
        ...

इन शाखाओं को एक जीपीएस प्लगइन द्वारा उत्तर देने के लिए एक संरचना में लिखा गया है, जो ट्रस्टी के अनुरोधों का जवाब देने के लिए डेटा को वापस करता है।

Go भाषा का उदाहरण:

  defer func(){                                // 处理收尾工作 
        if e := recover(); e != nil {          // recover()函数用于捕获panic,e != nil即有错误发生
            if ee, ok := e.(error); ok {       // 类型推导,推导成功把ee.Error()赋值给e
                e = ee.Error()                 // 调用Error方法获取返回的错误字符串
            }
            ret = map[string]string{"error": fmt.Sprintf("%v", e)}
        }
        b, _ := json.Marshal(ret)              // 把本次调用获取的结果ret编码,赋值给b,写入响应指针
        w.Write(b)
        //fmt.Println("after w.Write the b is", string(b))     // 测试
    }()
  • #### 3। एपीआई का प्रकार

यह लगभग दो श्रेणियों में बांटा गया हैः 1. सार्वजनिक इंटरफेस जिन्हें हस्ताक्षर की आवश्यकता नहीं है, जैसेः

GetTicker()

GetDepth()

GetTrades()

GetRecords(period)

  1. उपयोगकर्ता इंटरफ़ेस जिसे हस्ताक्षर की आवश्यकता होती है, जैसेः

BuySell

GetOrder(id)

GetOrders()

GetAccount()

CancelOrder(id) … प्रत्येक एक्सचेंज के लिए हस्ताक्षर का तरीका अलग-अलग हो सकता है और आवश्यकताओं के अनुसार विशेष रूप से तैयार किया जाना चाहिए।

  • ### 4, जब आविष्कारक प्रत्येक एपीआई इंटरफेस कॉल को मापता हैसामान्य प्रोटोकॉल प्लगइनऔरमेज़बानइंटरैक्टिव डेटा प्रारूपः

कुछ आविष्कारकों ने एपीआई का उपयोग किया है।GetName()GetLabel()फ़ंक्शंस, जब वे बुलाया जाता हैसामान्य प्रोटोकॉल प्लगइनअनुरोध भेजें exchange.GetName()सामान्य प्लगइन विन्यस्त एक्सचेंजों को कॉल करने पर “एक्सचेंज” वापस आ जाता है।

  • 1、GetTicker: वर्तमान डेटा प्राप्त करने के लिए।

    मेज़बानयह है कि यह कैसे किया जाता है?requestमेंmethodइसके लिएःticker

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.symbol: रोबोट पृष्ठ पर व्यवस्थापक द्वारा सेट किए गए सिक्के भेजें।

    डेटा प्रारूप जिसे होस्ट को अनुरोध करने के लिए कहा जाता है जब वह जीपीओ प्लगइन के लिए अनुरोध करता है (जेएसओएन)

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "ticker",
        "params" :     {"symbol" : "ETH_BTC"},     // 以ETH_BTC交易对举例
    }
    

    अंत में होस्ट को भेजे गए रिटर्न स्ट्रक्चरः ((यानी, जीपीओ प्लगइन द्वारा अनुरोध किए गए एक्सचेंज इंटरफेस के बाद डेटा होस्ट को लौटाया गया प्रारूप)

    JSON संरचना

    {
        "data": {
            "time": 1500793319499,  // 毫秒时间戳,整型
            "buy": 1000,            // 以下浮点型
            "sell": 1001,
            "last": 1005,
            "high": 1100,
            "low": 980,
            "vol": 523,
        }
    }
    
  • 2、GetRecords:एक्सचेंज द्वारा उपलब्ध कराए गए K-लाइन डेटा प्राप्त करने के लिए.

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःrecords

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.periodमूल्य संबंधexchange.GetRecordsफ़ंक्शन के पहले पैरामीटर, वास्तविकrequest.Params.periodमिनटों में व्यक्त की गई अवधि, उदाहरण के लिए, दिन की अवधि60*24अभी1440request.Params.symbol: व्यवस्थापक द्वारा निर्धारित मुद्राओं में भेजें

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "records",
        "params" :     {"symbol" : "ETH_BTC", "period" : "1440"},     // 以ETH_BTC交易对,K线周期为日线举例
    }
    

    अंत में होस्ट को भेजे जाने वाले रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data": [
                [1500793319, 1.1, 2.2, 3.3, 4.4, 5.5],         // "Time":1500793319000,"Open":1.1,"High":2.2,"Low":3.3,"Close":4.4,"Volume":5.5
                [1500793259, 1.01, 2.02, 3.03, 4.04, 5.05],
                ...
        ]
    }
    

    Go भाषा परीक्षण के आंकड़े:

    ret_records = []interface{}{
        [6]interface{}{1500793319, 1.1, 2.2, 3.3, 4.4, 5.5}, 
        [6]interface{}{1500793259, 1.01, 2.02, 3.03, 4.04, 5.05}
    }
    

    आविष्कारकों के लिए क्वांटिटेटिव प्लेटफॉर्मLogदिखाओrecordsआंकड़े:

    [
        {"Time":1500793319000,"Open":1.1,"High":2.2,"Low":3.3,"Close":4.4,"Volume":5.5},
        {"Time":1500793259000,"Open":1.01,"High":2.02,"Low":3.03,"Close":4.04,"Volume":5.05}
    ]
    

    ध्यान देंः 1, 2D सरणी में पहला तत्व हैintटाइप, समय को दर्शाता है 。 2। व्यवस्थापक स्वचालित रूप से समय को 1000 से गुणा करता है, ऊपर देखा जा सकता है 。

  • 3、GetDepth:एक्सचेंजों के बारे में गहराई से जानकारी प्राप्त करने के लिए (ऑर्डर पतले हैं, एक बेचें, दो बेचें … एक खरीदें, दो खरीदें …)

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःdepth

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.symbol: प्रबंधक द्वारा नीतिगत रूप से निर्धारित करेंसी भेजी जाती है

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "depth",
        "params" :     {"symbol" : "ETH_BTC"},     // 以ETH_BTC交易对举例
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data" : {
            "time" : 1500793319499,
            "asks" : [ [1000, 0.5], [1001, 0.23], [1004, 2.1], ... ],
            "bids" : [ [999, 0.25], [998, 0.8], [995, 1.4], ... ],
        }
    }
    
  • 4、GetTrades:एक्सचेंज द्वारा प्रदान किए गए एक्सचेंज के पूरे समय के लिए लेनदेन रिकॉर्ड प्राप्त करें (अन्य लेनदेन रिकॉर्ड)

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःtrades

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.symbolउदाहरण के लिएःbtc, एक ट्रस्टी द्वारा नीतिगत रूप से सेट किए गए सिक्के द्वारा भेजा जाता है.

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "trades",
        "params" :     {"symbol" : "ETH_BTC"},     // 以ETH_BTC交易对举例
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    { 
        "data": [
            {
                "id": 12232153,
                "time" : 1529919412968,
                "price": 1000,
                "amount": 0.5,
                "type": "buy",             // "buy"、"sell"
            },{
                "id": 12545664,
                "time" : 1529919412900,
                "price": 1001,
                "amount": 1,
                "type": "sell",
            },{
                ...
            }
        ]
    }
    
  • 5、GetAccount:खाता संपत्तियों की जानकारी प्राप्त करें

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःaccounts

    प्रशासक द्वारा भेजा गया पैरामीटरः ((ध्यान दें! आम तौर पर सभी खातों को प्राप्त करें! एक्सचेंज इंटरफ़ेस के आधार पर, व्यक्तिगत रूप से या कुल संपत्ति की जानकारी प्राप्त करें)

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "accounts",
        "params" :     {},                         
    }
    

    अंत में होस्ट को भेजे जाने वाले रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data": [
            {"currency": "btc", "free": 1.2, "frozen": 0.1},
            {"currency": "ltc", "free": 25, "frozen": 2.1},
            {"currency": "ltc", "free": 25, "frozen": 2.1},
            ...
        ],
        "raw" : {...}             // 可以写入插件访问交易所时,交易所返回的原始信息(response)
    }
    
  • 6、Buy、Sell:आदेश भेजें, आदेश दें, सौदा करें.

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःtrade

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.typeसंचालक: बुलाए जाने परexchange.Buyयाexchange.Sellभेजेंrequest.Params.priceरणनीति में बुलाया गयाःAPIफ़ंक्शन का पहला पैरामीटर,request.Params.amountरणनीति में बुलाया गयाःAPIफ़ंक्शन का दूसरा पैरामीटर,request.Params.symbol: व्यवस्थापक द्वारा निर्धारित मुद्राओं में भेजें

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "trade",
        "params" :     {
                           "symbol" : "ETH_BTC", 
                           "type" : "buy", 
                           "price" : "1000", 
                           "amount" : "1"
                       },                          // 以ETH_BTC交易对,"type":"buy"买请求,价格1000,数量1举例
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data": {
            "id": 125456,      // 下单后返回的订单id
                               // 如果订单id是"asdf346sfasf532"这样的字符串形式
                               // 此处id也可以是字符串类型
        }
    }
    
  • 7、GetOrder:निर्दिष्ट आदेश संख्या के लिए आदेश जानकारी प्राप्त करें

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःorder

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.idrequest.Params.symbol

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "order",
        "params" :     {"symbol" : "ETH_BTC", "id" : "XXX"},     // 以ETH_BTC交易对,订单id为XXX举例,注意有些交易所的订单号是数字形式的订单ID,如123456,有些交易所的订单号是字符串形式的ID,如poimd55sdfheqxv,具体看交易所的订单ID格式
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    { 
        "data": {
            "id": 2565244,
            "amount": 0.15,
            "price": 1002,
            "status": "open",    // "open":挂起状态、"closed":完成关闭状态、"cancelled":已取消
            "deal_amount": 0,
            "type": "buy",       // "buy"、"sell"
            "avg_price": 0,      // 如果交易所没有提供,在处理时可以赋值为0
        }
    }
    
  • 8、GetOrders: सभी अधूरे आदेशों की जानकारी प्राप्त करें

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestयहाँ method है:orders

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.symbol

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "orders",
        "params" :     {"symbol" : "ETH_BTC"},     // 以ETH_BTC交易对举例
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data": [{
            "id": 542156,
            "amount": 0.25,
            "price": 1005,
            "deal_amount": 0,
            "type": "buy",      // "buy"、"sell"
            "status": "open",   // "open"
        },{
            ...
        }]
    }
    
  • 9、CancelOrder: निर्दिष्ट आदेश संख्या के आदेश को रद्द करना

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodइसके लिएःcancel

    प्रशासक द्वारा भेजे गए पैरामीटरःrequest.Params.id: स्ट्रिंग प्रकार, एपीआई फ़ंक्शन का पहला पैरामीटर जिसे नीति बुलाती है,request.Params.symbol:btc (उदाहरण) एक व्यवस्थापक द्वारा नीतिगत रूप से सेट किए गए सिक्के द्वारा भेजा जाता है

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "cancel",
        "params" :     {"symbol" : "ETH_BTC", "id" : "XXX"},     // 以ETH_BTC交易对,id为"XXX"(同GetOrder函数的参数id一样),举例
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    JSON संरचना

    {
        "data": true,        // true or false
    }
    
  • 10、IO: एक्सचेंज.आईओ फंक्शन को कॉल करें

    एक होस्ट के लिए भेजने के लिए मॉनिटर प्रतिक्रिया समारोहrequestमेंmethodके लिए__api_विधि का नाम जो शुरू होता है

    डेटा प्रारूप जो होस्ट को जीपीओ प्लगइन के लिए अनुरोध करते समय ले जाने के लिए कहा जाता है

    {
        "access_key" : "access_key",
        "secret_key" : "secret_key",
        "nonce" :      "1500793319499",            // 毫秒时间戳
        "method" :     "__api_XXX",                // XXX为具体交易所的API接口(不包含基地址)
        "params" :     {"borrow_id" : "123", "symbol" : "cny"},      // 具体是传入IO函数的参数
    }
    

    अंत में होस्ट को भेजा गया रिटर्न स्ट्रक्चरः

    {
        "data": {...}       // 具体的接口调用的返回值
    }
    

    उदाहरण के लिए, रणनीति का आह्वानः

    var io_str = exchange.IO("api", "POST", "cancel_borrow", "symbol=cny&borrow_id=123")
    

    प्लगइन में परीक्षण कोड (गो भाषा):

    fmt.Println("request.Method:", request.Method, "request.Params:", request.Params)
    

    प्लगइन कमांड लाइन: 2017/08/31 10:19:59 Running http://127.0.0.1:6666/DigitalAsset

    प्लगइन कमांड लाइन में मुद्रित request.Method,request.Params प्रबन्धक द्वारा भेजे गए अनुरोध शरीर में डेटा विश्लेषण के बाद अनुरोध मेंःrequest.Methodइसके लिएः__api_cancel_borrow प्रबन्धक द्वारा भेजे गए अनुरोध शरीर में डेटा विश्लेषण के बाद अनुरोध मेंःrequest.Paramsइसके लिएः{"borrow_id" : "123", "symbol" : "cny"}

    विनिमय के लिए इन प्रत्यक्ष पहुँच को अनुकूलित करेंAPIकाexchange.IOबुलावा

    # 注意:
    # 在调用exchange.IO("api", "POST", "/api/v1/getAccount", "symbol=BTC_USDT")时,
    # 如果第二个参数不是POST,而是:exchange.IO("api", "GET", "/api/v1/getAccount", "symbol=BTC_USDT")
    # 是GET方法,这时在通用协议插件接受到的http请求中头部Http-Method中储存的才是GET,
    # 所以在通用协议处理IO函数实现时,需要参考以下范例代码:
    // tapiCall函数定义
    func (p *iStocksExchange) tapiCall(method string, params map[string]string, httpType string) (js *Json, err error) {
        ...
    }
    
    
    // 在OnPost函数中
    if strings.HasPrefix(request.Method, "__api_") {
        var js *Json
        js, err = e.tapiCall(request.Method[6:], request.Params, r.Header.Get("Http-Method"))
        ...
    }
    
  • Exchange.GetRawJSON के लिए समर्थन

    नीचे की ओर स्वचालितexchange.GetRawJSONयह प्लगइन में लागू नहीं किया जाना चाहिए।

  • Exchange.Go के लिए समर्थन

    नीचे की ओर स्वचालितexchange.Goऔर यह प्लगइन में काम नहीं करता है।

    var beginTime = new Date().getTime()
    var ret = exchange.Go("GetDepth")
    var endTime = new Date().getTime()
    Log(endTime - beginTime, "#FF0000")
    
    
    // Sleep(2000)
    beginTime = new Date().getTime()
    Log(exchange.GetTicker())
    endTime = new Date().getTime()
    Log(endTime - beginTime, "#FF0000")
    var depth = ret.wait()
    Log("depth:", depth)
    

    आविष्कारक का मात्रात्मक व्यापार मंच सार्वभौमिक प्रोटोकॉल कस्टम एक्सचेंज से जुड़ा हुआ है

    आविष्कारक का मात्रात्मक व्यापार मंच सार्वभौमिक प्रोटोकॉल कस्टम एक्सचेंज से जुड़ा हुआ है

    # 注意:使用exchange.Go在wait的时候如果指定了超时时间, 
    #      一定要确保获取到最终的数据,这样申请的并发线程才能回收。
    
  • फ्यूचर फ़ंक्शन के लिए समर्थन

    प्लगइन में विशिष्ट प्रसंस्करण की आवश्यकता होती है, जैसे कि लीवर, अनुबंध कोड, ऑर्डर दिशा सेट करना, एक स्थानीय चर रिकॉर्ड सेट किया जा सकता है, स्टॉकहोल्डर को एक्सेस करने के लिए एक्सचेंज इंटरफेस पर जाने की आवश्यकता होती है ताकि मूल डेटा प्राप्त किया जा सके और एफएमजेड प्लेटफॉर्म पर परिभाषित स्टॉकहोल्डर संरचना को संसाधित किया जा सके और वापस किया जा सके। जब नीति में निम्न फ़ंक्शंस को बुलाया जाता है, तो प्लगइन प्राप्त करता हैRpcअनुरोध प्रारूप अन्य इंटरफेस से थोड़ा अलग है, ध्यान देने की आवश्यकता है कि जीपीएस प्लगइनRpcRequestके प्रारूप में, मुख्य अंतर यह है कि params का मान एक जटिल संरचना है.

    • SetContractType
      अनुबंध कोड सेट करें
      {"access_key":"123","method":"io","nonce":1623307269528738000,"params":{"args":["quarter"],"code":2},"secret_key":"123"}
    
    • SetDirection भविष्य के लिए एक दिशा निर्धारित करें
      {"access_key":"123","method":"io","nonce":1623308734966484000,"params":{"args":["closesell"],"code":1},"secret_key":"123"}
    
    • SetMarginLevel फ्यूचर लीवर सेट करें
      {"access_key":"123","method":"io","nonce":1623308734966939000,"params":{"args":[12],"code":0},"secret_key":"123"}
    
    • GetPosition फ्यूचर होल्डिंग प्राप्त करें जबexchange.GetPosition()कॉल करने परः
      {"access_key":"123","method":"io","nonce":1623308734967442000,"params":{"args":[],"code":3},"secret_key":"123"}
    

    जबexchange.GetPosition("swap")कॉल करने परः

      {"access_key":"123","method":"io","nonce":1623308734967442000,"params":{"args":["swap"],"code":3},"secret_key":"123"}
    

  • ### सामान्य प्रोटोकॉल प्लगइन के लिए पूर्ण Go भाषा का एक उदाहरण

”`go /* GOOS=linux GOARCH=amd64 go build -ldflags ‘-s -w -extldflags -static’ rest_bitgo.go */ package main

import ( “bytes” “crypto/md5” “encoding/hex” “encoding/json” “errors” “flag” “fmt” “io/ioutil” “log” “net/http” “net/url” “sort” “strconv” “strings” “time” )

func toFloat(s interface{}) float64 { var ret float64 switch v := s.(type) { case float64: ret = v case float32: ret = float64(v) case int64: ret = float64(v) case int: ret = float64(v) case int32: ret = float64(v) case string: ret, _ = strconv.ParseFloat(strings.TrimSpace(v), 64) } return ret }

func float2str(i float64) string { return strconv.FormatFloat(i, ‘f’, -1, 64) }

func toInt64(s interface{}) int64 { var ret int64 switch v := s.(type) { case int: ret = int64(v) case float64: ret = int64(v) case bool: if v { ret = 1 } else { ret = 0 } case int64: ret = v case string: ret, _ = strconv.ParseInt(strings.TrimSpace(v), 10, 64) } return ret }

func toString(s interface{}) string { var ret string switch v := s.(type) { case string: ret = v case int64: ret = strconv.FormatInt(v, 10) case float64: ret = strconv.FormatFloat(v, ‘f’, -1, 64) case bool: ret = strconv.FormatBool(v) default: ret = fmt.Sprintf(“%v”, s) } return ret }

type Json struct { data interface{} }

func NewJson(body []byte) (*Json, error) { j := new(Json) err := j.UnmarshalJSON(body) if err != nil { return nil, err } return j, nil }

func (j *Json) UnmarshalJSON(p []byte) error { return json.Unmarshal(p, &j.data) }

func (j *Json) Get(key string) *Json { m, err := j.Map() if err == nil { if val, ok := m[key]; ok { return &Json{val} } } return &Json{nil} }

func (j *Json) CheckGet(key string) (*Json, bool) { m, err := j.Map() if err == nil { if val, ok := m[key]; ok { return &Json{val}, true } } return nil, false }

func (j *Json) Map() (map[string]interface{}, error) { if m, ok := (j.data).(map[string]interface{}); ok { return m, nil } return nil, errors.New(“type assertion to map[string]interface{} failed”) }

func (j *Json) Array() ([]interface{}, error) { if a, ok := (j.data).([]interface{}); ok { return a, nil } return nil, errors.New(“type assertion to []interface{} failed”) }

func (j *Json) Bool() (bool, error) { if s, ok := (j.data).(bool); ok { return s, nil } return false, errors.New(“type assertion to bool failed”) }

func (j *Json) String() (string, error) { if s, ok := (j.data).(string); ok { return s, nil } return “”, errors.New(“type assertion to string failed”) }

func (j *Json) Bytes() ([]byte, error) { if s, ok := (j.data).(string); ok { return []byte(s), nil } return nil, errors.New(“type assertion to []byte failed”) }

func (j *Json) Int() (int, error) { if f, ok := (j.data).(float64); ok { return int(f), nil }

return -1, errors.New("type assertion to float64 failed")

}

func (j *Json) MustArray(args …[]interface{}) []interface{} { var def []interface{}

switch len(args) {
case 0:
case 1:
    def = args[0]
default:
    log.Panicf("MustArray() received too many arguments %d", len(args))
}

a, err := j.Array()
if err == nil {
    return a
}

return def

}

func (j *Json) MustMap(args …map[string]interface{}) map[string]interface{} { var def map[string]interface{}

switch len(args) {
case 0:
case 1:
    def = args[0]
default:
    log.Panicf("MustMap() received too many arguments %d", len(args))
}

a, err := j.Map()
if err == nil {
    return a
}

return def

}

func (j *Json) MustString(args …string) string { var def string

switch len(args) {
case 0:
case 1:
    def = args[0]
default:
    log.Panicf("MustString() received too many arguments %d", len(args))
}

s, err := j.String()
if err == nil {
    return s
}

return def

}

func (j *Json) MustInt64() int64 { var ret int64 var err error switch v := j.data.(type) { case int: ret = int64(v) case int64: ret = v case float64: ret = int64(v) case string: if ret, err = strconv.ParseInt(v, 10, 64); err != nil { panic(err) } default: ret = 0 //panic(“type assertion to int64 failed”) } return ret }

func (j *Json) MustFloat64() float64 { var ret float64 var err error switch v := j.data.(type) { case int: ret = float64(v) case int64: ret = float64(v) case float64: ret = v case string: v = strings.Replace(v, “,”, “”, -1) if ret, err = strconv.ParseFloat(v, 64); err != nil { panic(err) } default: ret = 0 //panic(“type assertion to float64 failed”) } return ret }

type iBitgo struct { accessKey string secretKey string currency string opCurrency string baseCurrency string secret string secretExpires int64 apiBase string step int64 newRate float64 timeout time.Duration timeLocation *time.Location }

type MapSorter []Item

type Item struct { Key string Val string }

func NewMapSorter(m map[string]string) MapSorter { ms := make(MapSorter, 0, len(m))

for k, v := range m {
    if strings.HasPrefix(k, "!") {
        k = strings.Replace(k, "!", "", -1)
    }
    ms = append(ms, Item{k, v})
}

return ms

}

func (ms MapSorter) Len() int { return len(ms) }

func (ms MapSorter) Less(i, j int) bool { //return ms[i].Val < ms[j].Val // 按值排序 return ms[i].Key < ms[j].Key // 按键排序 }

func (ms MapSorter) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] }

func encodeParams(params map[string]string, escape bool) string { ms := NewMapSorter(params) sort.Sort(ms)

v := url.Values{}
for _, item := range ms {
    v.Add(item.Key, item.Val)
}
if escape {
    return v.Encode()
}
var buf bytes.Buffer
keys := make([]string, 0, len(v))
for k := range v {
    keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
    vs := v[k]
    prefix := k + "="
    for _, v := range vs {
        if buf.Len() > 0 {
            buf.WriteByte('&')
        }
        buf.WriteString(prefix)
        buf.WriteString(v)
    }
}
return buf.String()

}

func newBitgo(accessKey, secretKey string) *iBitgo { s := new(iBitgo) s.accessKey = accessKey s.secretKey = secretKey s.apiBase = “https://www.bitgo.cn” s.timeout = 20 * time.Second s.timeLocation = time.FixedZone(“Asia/Shanghai”, 8*60*60)

return s

}

func (p *iBitgo) apiCall(method string) (*Json, error) { req, err := http.NewRequest(“POST”, fmt.Sprintf(“%s/appApi.html?%s”, p.apiBase, method), nil) if err != nil { return nil, err } req.Header.Set(“Content-Type”, “application/x-www-form-urlencoded”) resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } return NewJson(b) }

func (p *iBitgo) GetTicker(symbol string) (ticker interface{}, err error) { var js *Json js, err = p.apiCall(“action=market&symbol=” + symbol) if err != nil { return } dic := js.Get(“data”) ticker = map[string]interface{}{ “time”: js.Get(“time”).MustInt64(), “buy”: dic.Get(“buy”).MustFloat64(), “sell”: dic.Get(“sell”).MustFloat64(), “last”: dic.Get(“last”).MustFloat64(), “high”: dic.Get(“high”).MustFloat64(), “low”: dic.Get(“low”).MustFloat64(), “vol”: dic.Get(“vol”).MustFloat64(), } return }

func (p *iBitgo) GetDepth(symbol string) (depth interface{}, err error) { var js *Json js, err = p.apiCall(“action=depth&symbol=” + symbol) if err != nil { return } dic := js.Get(“data”)

asks := [][2]float64{}
bids := [][2]float64{}

for _, pair := range dic.Get("asks").MustArray() {
    arr := pair.([]interface{})
    asks = append(asks, [2]float64{toFloat(arr[0]), toFloat(arr[1])})
}

for _, pair := range dic.Get("bids").MustArray() {
    arr := pair.([]interface{})
    bids = append(bids, [2]float64{toFloat(arr[0]), toFloat(arr[1])})
}
depth = map[string]interface{}{
    "time": js.Get("time").MustInt64(),
    "asks": asks,
    "bids": bids,
}
return

}

func (p *iBitgo) GetTrades(symbol string) (trades interface{}, err error) { var js *Json js, err = p.apiCall(“action=trades&symbol=” + symbol) if err != nil { return } dic := js.Get(“data”) items := []map[string]interface{}{} for _, pair := range dic.MustArray() { item := map[string]interface{}{} arr := pair.(map[string]interface{}) item[“id”] = toInt64(arr[“id”]) item[“price”] = toFloat(arr[“price”]) item[“amount”] = toFloat(arr[“amount”]) // trade.Time = toInt64(arr[“time”]) * 1000 if toString(arr[“en_type”]) == “bid” { item[“type”] = “buy” } else { item[“type”] = “sell” } items = append(items, item) } trades = items return }

func (p *iBitgo) GetRecords(step int64, symbol string) (records interface{}, err error) { var js *Json js, err = p.apiCall(fmt.Sprintf(“action=kline&symbol=%s&step=%d”, symbol, step*60)) if err != nil { return } items := []interface{}{} for _, pair := range js.Get(“data”).MustArray() { arr := pair.([]interface{}) if len(arr) < 6 { err = errors.New(“response format error”) return } item := [6]interface{}{} item[0] = toInt64(arr[0]) item[1] = toFloat(arr[1]) item[2] = toFloat(arr[2]) item[3] = toFloat(arr[3]) item[4] = toFloat(arr[4]) item[5] = toFloat(arr[5])

    items = append(items, item)
}
records = items
return

}

func (p *iBitgo) tapiCall(method string, params map[string]string) (js *Json, err error) { if params == nil { params = map[string]string{} } params[“api_key”] = p.accessKey h := md5.New() h.Write([]byte(encodeParams(params, false) + “&secret_key=” + p.secretKey)) params[“sign”] = strings.ToUpper(hex.EncodeToString(h.Sum(nil))) params[“action”] = method qs := encodeParams(params, false)

req, err := http.NewRequest("POST", fmt.Sprintf("%s/appApi.html?%s", p.apiBase, qs), nil)
if err != nil {
    return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := http.DefaultClient.Do(req)
if err != nil {
    return nil, err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
    return nil, err
}
js, err = NewJson(b)
if js != nil {
    if code := js.Get("code").MustInt64(); code != 200 {
        s := js.Get("msg").MustString()
        if s == "" {
            s = fmt.Sprintf("%v", toString(js.data))
        }
        return nil, errors.New(s)
    }
}
return js, err

}

func (p *iBitgo) GetAccount(symbol string) (account interface{}, err error) { var js *Json js, err = p.tapiCall(“userinfo”, nil) if err != nil { return } mp := js.Get(“data”) assets := map[string]map[string]interface{}{} for k := range mp.MustMap() { dic := mp.Get(k) if k == “free” { for c := range dic.MustMap() { if _, ok := assets[c]; !ok { assets[c] = map[string]interface{}{} } assets[c][“currency”] = c assets[c][“free”] = dic.Get©.MustFloat64() } } else if k == “frozen” { for c := range dic.MustMap() { if _, ok := assets[c]; !ok { assets[c] = map[string]interface{}{} } assets[c][“currency”] = c assets[c][“frozen”] = dic.Get©.MustFloat64() } } } accounts := []map[string]interface{}{} for _, pair := range assets { accounts = append(accounts, pair) }

account = accounts
return

}

func (p *iBitgo) Trade(side string, price, amount float64, symbol string) (orderId interface{}, err error) { var js *Json js, err = p.tapiCall(“trade”, map[string]string{ “symbol”: symbol, “type”: side, “price”: float2str(price), “amount”: float2str(amount), }) if err != nil { return } orderId = map[string]int64{“id”: js.Get(“orderId”).MustInt64()} return }

func (p *iBitgo) GetOrders(symbol string) (orders interface{}, err error) { var js *Json js, err = p.tapiCall(“entrust”, map[string]string{“symbol”: symbol}) if err != nil { return } items := []map[string]interface{}{} for _, ele := range js.Get(“data”).MustArray() { mp := ele.(map[string]interface{}) item := map[string]interface{}{} item[“id”] = toInt64(mp[“id”]) item[“amount”] = toFloat(mp[“count”]) if _, ok := mp[“prize”]; ok { item[“price”] = toFloat(mp[“prize”]) } else { item[“price”] = toFloat(mp[“price”]) } item[“deal_amount”] = toFloat(mp[“success_count”])

    if toInt64(mp