量化現貨合約跟單交易所軟體開發|原始碼搭建模式二開
策略設計成多交易所架構,開發I34-案例I633-演示53I9所以可以在這個策略上配置多個交易所物件,也就是可以控制多個不同賬戶的下單操作。只用在訊號結構中Exchange指定要操作的交易所即可,設定1就是要讓這個訊號操作第一個新增的交易所物件對應的交易所賬戶。如果要操作的是現貨ContractType設定為spot,期貨就寫具體合約,例如永續合約寫swap。市價單價格傳-1就可以了。Action設定對於期貨、現貨、開倉、平倉都是有區別的,不能設定錯。
接下來就可以設計策略程式碼了,完整的策略程式碼:
//訊號結構 var Template = { Flag: "45M103Buy", // 標識,可隨意指定 Exchange: 1, // 指定交易所交易對 Currency: "BTC_USDT", // 交易對 ContractType: "swap", // 合約型別,swap,quarter,next_quarter,現貨填寫spot Price: "{{close}}", // 開倉或者平倉價格,-1為市價 Action: "buy", // 交易型別[ buy:現貨買入 , sell:現貨賣出 , long:期貨做多 , short:期貨做空 , closesell:期貨買入平空 , closebuy:期貨賣出平多] Amount: "0", // 交易量 } var BaseUrl = "api/v1" // 擴充套件API介面地址 var RobotId = _G() // 當前實盤ID var Success = "#5cb85c" // 成功顏色 var Danger = "#ff0000" // 危險顏色 var Warning = "#f0ad4e" // 警告顏色 var buffSignal = [] // 校驗訊號訊息格式 function DiffObject(object1, object2) { const keys1 = Object.keys(object1) const keys2 = Object.keys(object2) if (keys1.length !== keys2.length) { return false } for (let i = 0; i < keys1.length; i++) { if (keys1[i] !== keys2[i]) { return false } } return true } function CheckSignal(Signal) { Signal.Price = parseFloat(Signal.Price) Signal.Amount = parseFloat(Signal.Amount) if (Signal.Exchange <= 0 || !Number.isInteger(Signal.Exchange)) { Log("交易所最小編號為1,並且為整數", Danger) return } if (Signal.Amount <= 0 || typeof(Signal.Amount) != "number") { Log("交易量不能小於0,並且為數值型別", typeof(Signal.Amount), Danger) return } if (typeof(Signal.Price) != "number") { Log("價格必須是數值", Danger) return } if (Signal.ContractType == "spot" && Signal.Action != "buy" && Signal.Action != "sell") { Log("指令為操作現貨,Action錯誤,Action:", Signal.Action, Danger) return } if (Signal.ContractType != "spot" && Signal.Action != "long" && Signal.Action != "short" && Signal.Action != "closesell" && Signal.Action != "closebuy") { Log("指令為操作期貨,Action錯誤,Action:", Signal.Action, Danger) return } return true } function commandRobot(url, accessKey, secretKey, robotId, cmd) { // api/v1?access_key=xxx&secret_key=xxx&method=CommandRobot&args=[xxx,+""] url = url + '?access_key=' + accessKey + '&secret_key=' + secretKey + '&method=CommandRobot&args=[' + robotId + ',+""]' var postData = { method:'POST', data:cmd } var headers = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36\nContent-Type: application/json" var ret = HttpQuery(url, postData, "", headers) Log("模擬TradingView的webhook請求,傳送用於測試的POST請求:", url, "body:", cmd, "應答:", ret) } function createManager() { var self = {} self.tasks = [] self.process = function() { var processed = 0 if (self.tasks.length > 0) { _.each(self.tasks, function(task) { if (!task.finished) { processed++ self.pollTask(task) } }) if (processed == 0) { self.tasks = [] } } } self.newTask = function(signal) { // {"Flag":"45M103Buy","Exchange":1,"Currency":"BTC_USDT","ContractType":"swap","Price":"10000","Action":"buy","Amount":"0"} var task = {} task.Flag = signal["Flag"] task.Exchange = signal["Exchange"] task.Currency = signal["Currency"] task.ContractType = signal["ContractType"] task.Price = signal["Price"] task.Action = signal["Action"] task.Amount = signal["Amount"] task.exchangeIdx = signal["Exchange"] - 1 task.pricePrecision = null task.amountPrecision = null task.error = null task.exchangeLabel = exchanges[task.exchangeIdx].GetLabel() task.finished = false Log("建立任務:", task) self.tasks.push(task) } self.getPrecision = function(n) { var precision = null var arr = n.toString().split(".") if (arr.length == 1) { precision = 0 } else if (arr.length == 2) { precision = arr[1].length } return precision } self.pollTask = function(task) { var e = exchanges[task.exchangeIdx] var name = e.GetName() var isFutures = true e.SetCurrency(task.Currency) if (task.ContractType != "spot" && name.indexOf("Futures_") != -1) { // 非現貨,則設定合約 e.SetContractType(task.ContractType) } else if (task.ContractType == "spot" && name.indexOf("Futures_") == -1) { isFutures = false } else { task.error = "指令中的ContractType與配置的交易所物件型別不匹配" return } var depth = e.GetDepth() if (!depth || !depth.Bids || !depth.Asks) { task.error = "訂單薄資料異常" return } if (depth.Bids.length == 0 && depth.Asks.length == 0) { task.error = "盤口無訂單" return } _.each([depth.Bids, depth.Asks], function(arr) { _.each(arr, function(order) { var pricePrecision = self.getPrecision(order.Price) var amountPrecision = self.getPrecision(order.Amount) if (Number.isInteger(pricePrecision) && !Number.isInteger(self.pricePrecision)) { self.pricePrecision = pricePrecision } else if (Number.isInteger(self.pricePrecision) && Number.isInteger(pricePrecision) && pricePrecision > self.pricePrecision) { self.pricePrecision = pricePrecision } if (Number.isInteger(amountPrecision) && !Number.isInteger(self.amountPrecision)) { self.amountPrecision = amountPrecision } else if (Number.isInteger(self.amountPrecision) && Number.isInteger(amountPrecision) && amountPrecision > self.amountPrecision) { self.amountPrecision = amountPrecision } }) }) if (!Number.isInteger(self.pricePrecision) || !Number.isInteger(self.amountPrecision)) { task.err = "獲取精度失敗" return } e.SetPrecision(self.pricePrecision, self.amountPrecision) // buy:現貨買入 , sell:現貨賣出 , long:期貨做多 , short:期貨做空 , closesell:期貨買入平空 , closebuy:期貨賣出平多 var direction = null var tradeFunc = null if (isFutures) { switch (task.Action) { case "long": direction = "buy" tradeFunc = e.Buy break case "short": direction = "sell" tradeFunc = e.Sell break case "closesell": direction = "closesell" tradeFunc = e.Buy break case "closebuy": direction = "closebuy" tradeFunc = e.Sell break } if (!direction || !tradeFunc) { task.error = "交易方向錯誤:" + task.Action return } e.SetDirection(direction) } else { if (task.Action == "buy") { tradeFunc = e.Buy } else if (task.Action == "sell") { tradeFunc = e.Sell } else { task.error = "交易方向錯誤:" + task.Action return } } var id = tradeFunc(task.Price, task.Amount) if (!id) { task.error = "下單失敗" } task.finished = true } return self } var manager = createManager() function HandleCommand(signal) { // 檢測是否收到互動指令 if (signal) { Log("收到互動指令:", signal) // 收到互動指令,列印互動指令 } else { return // 沒有收到時直接返回,不做處理 } // 檢測互動指令是否是測試指令,測試指令可以由當前策略互動控制元件發出來進行測試 if (signal.indexOf("TestSignal") != -1) { signal = signal.replace("TestSignal:", "") // 呼叫擴充套件API介面,模擬Trading View的webhook,互動按鈕TestSignal傳送的訊息:{"Flag":"45M103Buy","Exchange":1,"Currency":"BTC_USDT","ContractType":"swap","Price":"10000","Action":"buy","Amount":"0"} commandRobot(BaseUrl, _AccessKey, _SecretKey, RobotId, signal) } else if (signal.indexOf("evalCode") != -1) { var js = signal.split(':', 2)[1] Log("執行除錯程式碼:", js) eval(js) } else { // 處理訊號指令 objSignal = JSON.parse(signal) if (DiffObject(Template, objSignal)) { Log("接收到交易訊號指令:", objSignal) buffSignal.push(objSignal) // 檢查交易量、交易所編號 if (!CheckSignal(objSignal)) { return } // 建立任務 manager.newTask(objSignal) } else { Log("指令無法識別", signal) } } } function main() { Log("WebHook地址:", "api/v1?access_key=" + _AccessKey + "&secret_key=" + _SecretKey + "&method=CommandRobot&args=[" + RobotId + ',+""]', Danger) Log("交易型別[ buy:現貨買入 , sell:現貨賣出 , long:期貨做多 , short:期貨做空 , closesell:期貨買入平空 , closebuy:期貨賣出平多]", Danger) Log("指令模板:", JSON.stringify(Template), Danger) while (true) { try { // 處理互動 HandleCommand(GetCommand()) // 處理任務 manager.process() if (buffSignal.length > maxBuffSignalRowDisplay) { buffSignal.shift() } var buffSignalTbl = { "type" : "table", "title" : "訊號記錄", "cols" : ["Flag", "Exchange", "Currency", "ContractType", "Price", "Action", "Amount"], "rows" : [] } for (var i = buffSignal.length - 1 ; i >= 0 ; i--) { buffSignalTbl.rows.push([buffSignal[i].Flag, buffSignal[i].Exchange, buffSignal[i].Currency, buffSignal[i].ContractType, buffSignal[i].Price, buffSignal[i].Action, buffSignal[i].Amount]) } LogStatus(_D(), "\n", "`" + JSON.stringify(buffSignalTbl) + "`") Sleep(1000 * SleepInterval) } catch (error) { Log("e.name:", error.name, "e.stack:", error.stack, "e.message:", error.message) Sleep(1000 * 10) } } }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011332/viewspace-2938679/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 量化現貨合約跟單app軟體開發原始碼(可二開)APP原始碼
- 量化現貨合約跟單社群app軟體開發原始碼功能介紹APP原始碼
- 現成量化合約跟單模式軟體開發原始碼詳情模式原始碼
- 合約量化跟單系統開發搭建丨現成原始碼搭建原始碼
- 合約量化跟單|秒合約|現貨跟單系統開發
- 現貨合約秒合約跟單系統開發(原始碼案例)搭建原始碼
- 現貨量化/原始碼/秒合約/量化跟單交易系統合約開發python技術原始碼Python
- 關於合約跟單交易所模式軟體開發模式
- 量化交易/量化合約/合約量化/秒合約/永續合約/合約跟單/交易所繫統開發(策略及原始碼)原始碼
- 合約量化跟單模式軟體開發邏輯詳情模式
- 現貨跟單量化/合約跟單/系統開發/量化合約交易/永續合約/秒合約解析
- 合約跟單/系統開發/現貨量化跟單/永續合約/秒合約策略
- 量化交易現貨合約對沖跟單app系統開發案例演示(原始碼搭建)APP原始碼
- 量化合約/合約量化/合約跟單/交易所繫統開發實現技術原理及案例原始碼原始碼
- 現貨合約跟單交易所開發(穩定版)丨現貨合約跟單交易所繫統開發(詳情及邏輯)原始碼原始碼
- 合約跟單交易所|現成跟單交易所|現貨合約交易所繫統開發
- 量化合約跟單系統開發(樣式搭建)合約量化原始碼系統開發流程原始碼
- 現貨量化跟單丨合約跟單系統開發丨原始碼丨量化機器人開發技術分析原始碼機器人
- 現貨期權合約量化/量化合約/秒合約/永續合約/交易所繫統開發(開發案例及原始碼)原始碼
- 數字貨幣交易所/合約跟單/秒合約/永續合約/量化合約/合約量化系統開發詳細策略及原始碼原始碼
- 量化現貨交易/合約跟單/現貨合約量化系統設計開發專案
- 關於合約跟單交易所繫統開發(原始碼)|合約交易搭建原始碼
- 合約跟單/現貨量化跟單/永續合約/系統開發技術/應用
- 量化合約/合約量化/秒合約/永續合約/現貨期權期貨/交易所繫統開發案例及原始碼原始碼
- 現貨合約跟單交易所app系統開發原始碼定製功能APP原始碼
- 量化合約系統開發(方案模式)|合約量化系統開發(原始碼搭建)模式原始碼
- 量化合約丨合約量化丨合約跟單丨交易所繫統開發實現技術案例及原始碼(demo)原始碼
- 量化跟單/秒合約/原始碼系統開發/永續合約量化交易開發技術分析原始碼
- 【現貨量化跟單】合約量化策略開發/秒合約系統策略開發(技術詳情)
- 量化跟單丨永續合約丨秒合約丨合約交易模式軟體開發詳情模式
- 交易所合約跟單帶單軟體開發原始碼方案技術詳情原始碼
- 量化跟單/合約量化/秒合約/跟單交易/交易所繫統技術開發(Python策略)Python
- 現成跟單量化合約模式系統開發原始碼搭建(技術介紹)模式原始碼
- 合約跟單交易所開發(案例開發)丨合約跟單交易所繫統開發實現技術方案及原始碼專案原始碼
- 數字貨幣交易所/合約跟單/秒合約/永續合約/合約量化系統開發說明/原始碼案例/運營版原始碼
- 合約跟單系統開發(原始碼搭建方案)_現成原始碼
- 量化合約/合約量化/合約跟單系統開發(策略及詳細)案例原始碼原始碼
- 合約量化/現貨交易/合約跟單/秒合約/系統開發技術分析