Artikel berkaitan:https://www.fmz.com/bbs-topic/7457Artikel berkaitan:https://www.fmz.com/digest-topic/8902
// OKEX V5 获取总权益 function getTotalEquity_OKEX_V5() { var totalEquity = null var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT") if (ret) { try { totalEquity = parseFloat(ret.data[0].details[0].eq) } catch(e) { Log("获取账户总权益失败!") return null } } return totalEquity } // 币安期货 function getTotalEquity_Binance() { var totalEquity = null var ret = exchange.GetAccount() if (ret) { try { totalEquity = parseFloat(ret.Info.totalWalletBalance) } catch(e) { Log("获取账户总权益失败!") return null } } return totalEquity } // dYdX function getTotalEquity_dYdX() { var totalEquity = null var ret = exchange.GetAccount() if (ret) { totalEquity = ret.Balance } return totalEquity } // BitMEX function getTotalEquity_BitMEX() { var currency = exchange.GetCurrency() var arr = currency.split("_") if (arr.length != 2) { throw "交易对配置错误" } var baseCurrency = arr[0] var quoteCurrency = arr[1] var coinName = "" var scale = 0.0 if (quoteCurrency == "USDT") { coinName = "USDt" scale = 6 } else if (quoteCurrency == "USD") { coinName = "XBt" scale = 8 } else { throw "不支持" } var ret = exchange.IO("api", "GET", "/api/v1/user/margin", "currency=all") if (ret) { for (var i = 0 ; i < ret.length ; i++) { if (coinName == ret[i].currency) { var equity = ret[i]["marginBalance"] if (equity) { return parseFloat(equity) / Math.pow(10, scale) } } } } else { Log("获取账户总权益失败!") return null } } function getTotalEquity() { var exName = exchange.GetName() if (exName == "Futures_OKCoin") { return getTotalEquity_OKEX_V5() } else if (exName == "Futures_Binance") { return getTotalEquity_Binance() } else if (exName == "Futures_dYdX") { return getTotalEquity_dYdX() } else if (exName == "Futures_BitMEX") { return getTotalEquity_BitMEX() } else { throw "不支持该交易所" } } function cancelAll() { while (1) { var orders = _C(exchange.GetOrders) if (orders.length == 0) { break } for (var i = 0 ; i < orders.length ; i++) { exchange.CancelOrder(orders[i].Id, orders[i]) Sleep(500) } Sleep(500) } } function trade(distance, price, amount) { var tradeFunc = null if (distance == "buy") { tradeFunc = exchange.Buy } else if (distance == "sell") { tradeFunc = exchange.Sell } else if (distance == "closebuy") { tradeFunc = exchange.Sell } else { tradeFunc = exchange.Buy } exchange.SetDirection(distance) return tradeFunc(price, amount) } function openLong(price, amount) { return trade("buy", price, amount) } function openShort(price, amount) { return trade("sell", price, amount) } function coverLong(price, amount) { return trade("closebuy", price, amount) } function coverShort(price, amount) { return trade("closesell", price, amount) } var buyOrderId = null var sellOrderId = null var chartUpdateTS = 0 function riskControl() { var ts = new Date().getTime() var data = _G("riskControData") if (!data) { // 没有风控数据,初始化 data = {timeStamp : ts, tradeTimes : 0} _G("riskControData", data) } if (ts - data.timeStamp > 1000 * 60 * 60 * 24) { data.tradeTimes = 0 data.timeStamp = ts Log("风控模块重置时间:", data) } data.tradeTimes++ _G("riskControData", data) if (data.tradeTimes > 10) { Log("触发风控:", data) return false } return true } function main() { var exName = exchange.GetName() // 切换OKEX V5模拟盘 if (isSimulate && exName == "Futures_OKCoin") { exchange.IO("simulate", true) } if (isReset) { _G(null) LogReset(1) LogProfitReset() LogVacuum() Log("重置所有数据", "#FF0000") } Log("当前模式:", ["双向", "只做多", "只做空"][mode]) exchange.SetContractType("swap") exchange.SetPrecision(pricePrecision, amountPrecision) Log("设置精度", pricePrecision, amountPrecision) if (totalEq == -1 && !IsVirtual()) { var recoverTotalEq = _G("totalEq") if (!recoverTotalEq) { var currTotalEq = getTotalEquity() if (currTotalEq) { totalEq = currTotalEq _G("totalEq", currTotalEq) } else { throw "获取初始权益失败" } } else { totalEq = recoverTotalEq } } var n = 1 // 加仓系数 while (1) { // 风控 /* if (!riskControl()) { Sleep(1000 * 60 * 30) continue } */ var ticker = _C(exchange.GetTicker) var pos = _C(exchange.GetPosition) if (pos.length > 1) { Log(pos) throw "同时有多空持仓" } // 根据状态而定 if (pos.length == 0) { // 未持仓了,统计一次收益 if (!IsVirtual()) { var currTotalEq = getTotalEquity() if (currTotalEq) { LogProfit(currTotalEq - totalEq, "当前总权益:", currTotalEq) } } if (mode == 0) { buyOrderId = openLong(ticker.Last - targetProfit, amount) sellOrderId = openShort(ticker.Last + targetProfit, amount) } else if (mode == 1) { buyOrderId = openLong(ticker.Last - targetProfit, amount) } else if (mode == 2) { sellOrderId = openShort(ticker.Last + targetProfit, amount) } n = 1 // 初始为1 } else if (pos[0].Type == PD_LONG) { // 有多头持仓 n += increment var price = ticker.Last buyOrderId = openLong(price - targetProfit * n, amount) sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount) } else if (pos[0].Type == PD_SHORT) { // 有空头持仓 n += increment var price = ticker.Last buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount) sellOrderId = openShort(price + targetProfit * n, amount) } if (mode == 0 && (!sellOrderId || !buyOrderId)) { cancelAll() buyOrderId = null sellOrderId = null continue } else if (mode == 1 && pos.length == 0 && !buyOrderId) { cancelAll() buyOrderId = null sellOrderId = null continue } else if (mode == 2 && pos.length == 0 && !sellOrderId) { cancelAll() buyOrderId = null sellOrderId = null continue } else if (pos.length != 0 && (!sellOrderId || !buyOrderId)) { cancelAll() buyOrderId = null sellOrderId = null continue } while (1) { // 监控订单 var isFindBuyId = false var isFindSellId = false var buyOrder = null var sellOrder = null var orders = _C(exchange.GetOrders) var t = exchange.GetTicker() for (var i = 0 ; i < orders.length ; i++) { if (buyOrderId == orders[i].Id) { isFindBuyId = true buyOrder = orders[i] } if (sellOrderId == orders[i].Id) { isFindSellId = true sellOrder = orders[i] } } if (!isFindSellId && !isFindBuyId) { // 买卖单都成交了 cancelAll() break } else if (!isFindBuyId && (mode == 0 || (mode == 2 && pos.length != 0))) { // 买单成交 // 双向模式,只做空模式有持仓,找不到买单时 Log("买单成交") cancelAll() break } else if (!isFindSellId && (mode == 0 || (mode == 1 && pos.length != 0))) { // 卖单成交 // 双向模式,只做多模式有持仓,找不到卖单时 Log("卖单成交") cancelAll() break } else if (mode == 1 && pos.length == 0 && isFindBuyId && t && buyOrder && t.Last - buyOrder.Price > maxPendingDiff) { // 只做多模式,没有持仓,查询到买单存在,订单价格超出 Log("当前价格超出最大距离,撤销买单订单!当前价格:", t.Last, "订单价格:", buyOrder.Price, "最大距离:", maxPendingDiff) cancelAll() break } else if (mode == 2 && pos.length == 0 && isFindSellId && t && sellOrder && sellOrder.Price - t.Last > maxPendingDiff) { // 只做空模式,没有持仓,查询到卖单存在,订单价格超出 Log("当前价格超出最大距离,撤销卖单订单!当前价格:", t.Last, "订单价格:", buyOrder.Price, "最大距离:", maxPendingDiff) cancelAll() break } else if (!isFindBuyId && pos.length != 0) { // 有持仓,找不到买单时,条件可以合并 Log("买单成交") cancelAll() break } else if (!isFindSellId && pos.length != 0) { // 有持仓,找不到卖单时 Log("卖单成交") cancelAll() break } if (!IsVirtual()) { var currTotalEq = getTotalEquity() var pos = exchange.GetPosition() if (currTotalEq && pos) { // LogStatus(_D(), "当前总权益:", currTotalEq, "持仓:", pos) var tblPos = { "type" : "table", "title" : "持仓", "cols" : ["持仓数量", "持仓方向", "持仓均价", "持仓盈亏", "合约代码", "自定义字段 / " + SpecifyPosField], "rows" : [] } var descType = ["多头仓位", "空头仓位"] for (var posIndex = 0 ; posIndex < pos.length ; posIndex++) { tblPos.rows.push([pos[posIndex].Amount, descType[pos[posIndex].Type], pos[posIndex].Price, pos[posIndex].Profit, pos[posIndex].ContractType, SpecifyPosField == "" ? "--" : pos[posIndex].Info[SpecifyPosField]]) } var tbl = { "type" : "table", "title" : "数据", "cols" : ["当前总权益", "实际盈亏", "当前价格", "买单价格/数量", "卖单价格/数量"], "rows" : [] } /* var buyOrder = null var sellOrder = null for (var orderIndex = 0 ; orderIndex < orders.length ; orderIndex++) { if (orders[orderIndex].Type == ORDER_TYPE_BUY) { buyOrder = orders[orderIndex] } else { sellOrder = orders[orderIndex] } } */ var realProfit = currTotalEq - totalEq if (exchange.GetName() == "Futures_Binance") { _.each(pos, function(p) { realProfit += parseFloat(p.Info.unRealizedProfit) }) } // var t = exchange.GetTicker() tbl.rows.push([currTotalEq, realProfit, t ? t.Last : "--", buyOrder ? (buyOrder.Price + "/" + buyOrder.Amount) : "--/--", sellOrder ? (sellOrder.Price + "/" + sellOrder.Amount) : "--/--"]) // 更新图表数据 if (t && showLine) { var ts = new Date().getTime() if (ts - chartUpdateTS > 60 * 1000 * 5) { chartUpdateTS = ts $.PlotLine("当前价格", t.Last) } } // 更新状态栏数据 LogStatus("时间:" + _D() + "\n" + "`" + JSON.stringify(tblPos) + "`" + "\n" + "`" + JSON.stringify(tbl) + "`") } } Sleep(5000) } Sleep(500) } } function onexit() { Log("扫尾,撤销所有挂单") cancelAll() }
xyiiJika anda mempunyai keadaan yang lebih baik, maka anda akan mempunyai keadaan yang lebih baik jika anda mempunyai keadaan yang lebih baik.
Turgay75Hi, ini adalah bot yang sangat baik. Saya menggunakannya tetapi saya mesti melakukan stoploss sendiri. Bolehkah anda menambah parameter stoploss ke bot ini sila. Saya akan sangat gembira dengan stoploss automatik. Terima kasih terlebih dahulu. turgay75@gmx.de Maaf bahasa Inggeris saya
PengemisTarik masa yang lama, mod dua hala akan memberi kesalahan.
DekolarSaya hanya cuba untuk menguji mengapa jumlah unit tidak boleh ditetapkan kepada 0.1.
xjjJadi, jika anda mempunyai peluang untuk membeli Bitcoin dengan harga yang lebih rendah, anda mungkin akan mempunyai peluang untuk membeli Bitcoin dengan harga yang lebih rendah.
Hanya untuk mendapatkan wang.Tuhan, bolehkah saya menulis strategi dan bagaimana saya boleh menghubungi anda?
LvdaleiBerapa kali levera?
Pencipta Kuantiti - Impian KecilSelamat datang.
Turgay75Terima kasih untuk kerja anda, tetapan stoploss akan membantu saya banyak
Pencipta Kuantiti - Impian KecilTerima kasih banyak untuk menyokong FMZ kuantiti. Saya mengambil masa untuk menambah fungsi stop loss.
Pencipta Kuantiti - Impian KecilMungkin parameter yang tidak sesuai ditetapkan, target keuntungan ditetapkan besar, mungkin tetapan terlalu kecil, menyebabkan pegangan dua hala. Tidak, kontrak kekal dalam pasaran boleh ditetapkan sebagai pegangan satu hala, tidak memegang kedudukan dua hala.
PengemisApabila kita mengkaji semula sepanjang tahun, pengkaji semula bulan pertama terjebak dengan laporan kesalahan, mesej adalah dua arah memegang; menukar mata wang juga seolah-olah tidak dapat mengkaji semula sepanjang tahun
Pencipta Kuantiti - Impian KecilOh, apa sebenarnya yang salah?
Pencipta Kuantiti - Impian KecilBagus.
DekolarSaya akan cuba lagi, mungkin itu masalah saya.
Pencipta Kuantiti - Impian KecilJika anda mempunyai parameter yang ditetapkan dengan tepat, anda mungkin salah menetapkan parameter.
DekolarKontrak kekal ETH_USDT, menunjukkan jumlah pesanan seterusnya adalah 0
Pencipta Kuantiti - Impian KecilJika anda boleh menetapkannya kepada 0.1, apakah pasangan transaksi yang sedang berjalan, kontrak?
Pencipta Kuantiti - Impian KecilPerhatikan parameternya.
xy5335Pendapatan yang tetap, levera yang berbeza