2021-08-05 16:35:33 +08:00
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Name
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
数字货币期货类马丁策略
|
|
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Author
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
2025-04-30 11:10:28 +08:00
|
|
|
|
发明者量化-小小梦
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Strategy Description
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
## 数字货币期货类马丁策略
|
|
|
|
|
|
|
2022-03-09 16:09:19 +08:00
|
|
|
|
相关文章1:https://www.fmz.com/bbs-topic/7457
|
|
|
|
|
|
相关文章2:https://www.fmz.com/digest-topic/8902
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Strategy Arguments
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
|Argument|Default|Description|
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|----|----|----|
|
|
|
|
|
|
|targetProfit|10|目标利润|
|
|
|
|
|
|
|amount|true|下单量|
|
|
|
|
|
|
|totalEq|-1|初始总权益|
|
|
|
|
|
|
|isReset|false|重置|
|
|
|
|
|
|
|pricePrecision|2|价格精度|
|
|
|
|
|
|
|amountPrecision|2|下单量精度|
|
|
|
|
|
|
|isSimulate|false|OKEX_V5模拟盘选项|
|
2022-03-09 16:09:19 +08:00
|
|
|
|
|SpecifyPosField||指定显示的持仓字段|
|
|
|
|
|
|
|showLine|false|显示曲线图表|
|
2023-01-11 17:10:25 +08:00
|
|
|
|
|mode|0|模式: 双向|只做多|只做空|
|
|
|
|
|
|
|maxPendingDiff|60|最大挂单距离|
|
|
|
|
|
|
|increment|false|加仓系数增量|
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Source (javascript)
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
``` javascript
|
|
|
|
|
|
// 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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-07 00:45:45 +08:00
|
|
|
|
// dYdX
|
|
|
|
|
|
function getTotalEquity_dYdX() {
|
|
|
|
|
|
var totalEquity = null
|
|
|
|
|
|
var ret = exchange.GetAccount()
|
|
|
|
|
|
if (ret) {
|
|
|
|
|
|
totalEquity = ret.Balance
|
|
|
|
|
|
}
|
|
|
|
|
|
return totalEquity
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-11 09:35:59 +08:00
|
|
|
|
// 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
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-05 16:35:33 +08:00
|
|
|
|
function getTotalEquity() {
|
|
|
|
|
|
var exName = exchange.GetName()
|
|
|
|
|
|
if (exName == "Futures_OKCoin") {
|
|
|
|
|
|
return getTotalEquity_OKEX_V5()
|
|
|
|
|
|
} else if (exName == "Futures_Binance") {
|
|
|
|
|
|
return getTotalEquity_Binance()
|
2021-12-07 00:45:45 +08:00
|
|
|
|
} else if (exName == "Futures_dYdX") {
|
|
|
|
|
|
return getTotalEquity_dYdX()
|
2023-12-11 09:35:59 +08:00
|
|
|
|
} else if (exName == "Futures_BitMEX") {
|
|
|
|
|
|
return getTotalEquity_BitMEX()
|
2021-08-05 16:35:33 +08:00
|
|
|
|
} 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
|
2023-01-11 17:10:25 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-11 17:10:25 +08:00
|
|
|
|
Log("当前模式:", ["双向", "只做多", "只做空"][mode])
|
|
|
|
|
|
|
2021-08-05 16:35:33 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-11 17:10:25 +08:00
|
|
|
|
var n = 1 // 加仓系数
|
2021-08-05 16:35:33 +08:00
|
|
|
|
while (1) {
|
2023-01-11 17:10:25 +08:00
|
|
|
|
// 风控
|
|
|
|
|
|
/*
|
|
|
|
|
|
if (!riskControl()) {
|
|
|
|
|
|
Sleep(1000 * 60 * 30)
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2021-08-05 16:35:33 +08:00
|
|
|
|
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)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-11 17:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
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
|
2021-08-05 16:35:33 +08:00
|
|
|
|
} else if (pos[0].Type == PD_LONG) { // 有多头持仓
|
2023-01-11 17:10:25 +08:00
|
|
|
|
n += increment
|
2021-08-05 16:35:33 +08:00
|
|
|
|
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) { // 有空头持仓
|
2023-01-11 17:10:25 +08:00
|
|
|
|
n += increment
|
2021-08-05 16:35:33 +08:00
|
|
|
|
var price = ticker.Last
|
|
|
|
|
|
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
|
|
|
|
|
|
sellOrderId = openShort(price + targetProfit * n, amount)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-11 17:10:25 +08:00
|
|
|
|
if (mode == 0 && (!sellOrderId || !buyOrderId)) {
|
2021-08-05 16:35:33 +08:00
|
|
|
|
cancelAll()
|
|
|
|
|
|
buyOrderId = null
|
|
|
|
|
|
sellOrderId = null
|
|
|
|
|
|
continue
|
2023-01-11 17:10:25 +08:00
|
|
|
|
} 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
|
|
|
|
|
|
}
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
while (1) { // 监控订单
|
|
|
|
|
|
var isFindBuyId = false
|
|
|
|
|
|
var isFindSellId = false
|
2023-01-11 17:10:25 +08:00
|
|
|
|
var buyOrder = null
|
|
|
|
|
|
var sellOrder = null
|
2021-08-05 16:35:33 +08:00
|
|
|
|
var orders = _C(exchange.GetOrders)
|
2023-01-11 17:10:25 +08:00
|
|
|
|
var t = exchange.GetTicker()
|
2021-08-05 16:35:33 +08:00
|
|
|
|
for (var i = 0 ; i < orders.length ; i++) {
|
|
|
|
|
|
if (buyOrderId == orders[i].Id) {
|
|
|
|
|
|
isFindBuyId = true
|
2023-01-11 17:10:25 +08:00
|
|
|
|
buyOrder = orders[i]
|
2021-08-05 16:35:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (sellOrderId == orders[i].Id) {
|
|
|
|
|
|
isFindSellId = true
|
2023-01-11 17:10:25 +08:00
|
|
|
|
sellOrder = orders[i]
|
2021-08-05 16:35:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!isFindSellId && !isFindBuyId) { // 买卖单都成交了
|
|
|
|
|
|
cancelAll()
|
|
|
|
|
|
break
|
2023-01-11 17:10:25 +08:00
|
|
|
|
} else if (!isFindBuyId && (mode == 0 || (mode == 2 && pos.length != 0))) { // 买单成交
|
|
|
|
|
|
// 双向模式,只做空模式有持仓,找不到买单时
|
2021-08-05 16:35:33 +08:00
|
|
|
|
Log("买单成交")
|
|
|
|
|
|
cancelAll()
|
|
|
|
|
|
break
|
2023-01-11 17:10:25 +08:00
|
|
|
|
} else if (!isFindSellId && (mode == 0 || (mode == 1 && pos.length != 0))) { // 卖单成交
|
|
|
|
|
|
// 双向模式,只做多模式有持仓,找不到卖单时
|
2021-08-05 16:35:33 +08:00
|
|
|
|
Log("卖单成交")
|
|
|
|
|
|
cancelAll()
|
|
|
|
|
|
break
|
2023-01-11 17:10:25 +08:00
|
|
|
|
} 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
|
|
|
|
|
|
}
|
2022-03-09 16:09:19 +08:00
|
|
|
|
|
2021-12-07 00:45:45 +08:00
|
|
|
|
if (!IsVirtual()) {
|
|
|
|
|
|
var currTotalEq = getTotalEquity()
|
|
|
|
|
|
var pos = exchange.GetPosition()
|
|
|
|
|
|
if (currTotalEq && pos) {
|
2022-03-09 16:09:19 +08:00
|
|
|
|
// 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" : []
|
|
|
|
|
|
}
|
2023-01-11 17:10:25 +08:00
|
|
|
|
|
|
|
|
|
|
/*
|
2022-03-09 16:09:19 +08:00
|
|
|
|
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]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-11 17:10:25 +08:00
|
|
|
|
*/
|
2022-03-09 16:09:19 +08:00
|
|
|
|
var realProfit = currTotalEq - totalEq
|
|
|
|
|
|
if (exchange.GetName() == "Futures_Binance") {
|
|
|
|
|
|
_.each(pos, function(p) {
|
|
|
|
|
|
realProfit += parseFloat(p.Info.unRealizedProfit)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2023-01-11 17:10:25 +08:00
|
|
|
|
// var t = exchange.GetTicker()
|
|
|
|
|
|
tbl.rows.push([currTotalEq, realProfit, t ? t.Last : "--", buyOrder ? (buyOrder.Price + "/" + buyOrder.Amount) : "--/--", sellOrder ? (sellOrder.Price + "/" + sellOrder.Amount) : "--/--"])
|
2022-03-09 16:09:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新图表数据
|
|
|
|
|
|
if (t && showLine) {
|
2023-01-11 17:10:25 +08:00
|
|
|
|
var ts = new Date().getTime()
|
|
|
|
|
|
if (ts - chartUpdateTS > 60 * 1000 * 5) {
|
|
|
|
|
|
chartUpdateTS = ts
|
|
|
|
|
|
$.PlotLine("当前价格", t.Last)
|
|
|
|
|
|
}
|
2022-03-09 16:09:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新状态栏数据
|
|
|
|
|
|
LogStatus("时间:" + _D() + "\n" + "`" + JSON.stringify(tblPos) + "`" + "\n" + "`" + JSON.stringify(tbl) + "`")
|
2021-12-07 00:45:45 +08:00
|
|
|
|
}
|
2022-03-09 16:09:19 +08:00
|
|
|
|
}
|
2021-12-07 00:45:45 +08:00
|
|
|
|
Sleep(5000)
|
2021-08-05 16:35:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
Sleep(500)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onexit() {
|
|
|
|
|
|
Log("扫尾,撤销所有挂单")
|
|
|
|
|
|
cancelAll()
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Detail
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
|
|
|
|
|
https://www.fmz.com/strategy/294957
|
|
|
|
|
|
|
2023-07-14 18:39:48 +08:00
|
|
|
|
> Last Modified
|
2021-08-05 16:35:33 +08:00
|
|
|
|
|
2023-12-11 09:35:59 +08:00
|
|
|
|
2023-12-01 10:57:21
|