Die Ressourcen sind geladen. Beförderung...

Die Strategie von Martin für digitale Währungstermine

Schriftsteller:Die Erfinder quantifizieren - Kleine Träume, Datum: 2021-06-30 11:50:40 Uhr
Tags:Weichweizen

Die Strategie von Martin für digitale Währungstermine

Artikel 1 dazu:https://www.fmz.com/bbs-topic/7457Artikel 2 dazu: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()
}

Verwandt

Mehr

xyiiWenn wir die Stoppbedingungen hinzufügen, ist es besser.

Turgay75Hallo, das ist ein sehr guter Bot. Ich benutze ihn, aber ich muss selbst Stoploss machen. Kannst du diesem Bot bitte Stoploss-Parameter hinzufügen. Ich werde sehr glücklich mit automatischem Stoploss sein. Vielen Dank im Voraus. turgay75@gmx.de Entschuldigung für mein Englisch

Die BettlerWenn man die Zeit zurückzieht, gibt es Fehler im BIP-Modus.

Der DekolorHey, ich habe gerade getestet, warum ich die Einheitsmenge nicht auf 0.1 setzen kann.

xjjIch habe eine Frage, die ich mir gestellt habe: Warum ist der Anschluss zwischen 20 Dollar, ETH und BNB?

Ich will nur Geld verdienen.Gott, können Sie mir eine Strategie schreiben, wie kann ich Sie kontaktieren?

Ich habe ihn gesehen.Wie viel ist der Hebel?

Die Erfinder quantifizieren - Kleine Träume- Ich bin froh, dass Sie kommen.

Turgay75Danke für Ihre Arbeit, Stoploss-Einstellung wird mir sehr helfen.

Die Erfinder quantifizieren - Kleine TräumeIch habe mir die Zeit genommen, eine Stop-Loss-Funktion hinzuzufügen.

Die Erfinder quantifizieren - Kleine TräumeEs kann sein, dass die Parameter nicht richtig eingestellt sind, dass das Ziel für die Gewinnspanne groß eingestellt ist, oder dass es zu klein eingestellt ist, was zu einer zweiseitigen Positionierung führt.

Die BettlerBei der Rückrechnung für das ganze Jahr, die Rückrechnung in den ersten Monat stecken Fehler, die Nachricht ist, dass die Zwei-Wege-Haltung; Wechseln Währungen scheinen auch nicht das ganze Jahr zurückzuweisen.

Die Erfinder quantifizieren - Kleine TräumeWas genau ist ein Fehler?

Die Erfinder quantifizieren - Kleine TräumeDas ist gut.

Der DekolorDie Präzision ist auch eingestellt, nein, ich sehe es noch einmal, das sollte mein Problem sein.

Die Erfinder quantifizieren - Kleine TräumeDie Parameter sind genau eingestellt, aber die Präzision ist falsch eingestellt.

Der DekolorETH_USDT-Permanentvertrag, der folgende Betrag ist 0

Die Erfinder quantifizieren - Kleine TräumeWenn ich das nicht tun kann, dann kann ich es auf 0.1 setzen.

Die Erfinder quantifizieren - Kleine TräumeDie Parameter sind hier.

xy5335Das ist eine sehr schwierige Sache.