Loading ...

永续合约对冲套利【策略仅供学习参考】

Author: wkc19891, Date: 2022-02-12 22:20:05
Tags:

策略特性: 1.趋势开单 2.逆势补仓 3.带有磨损解套 4.套利自动划转现货


/*
 * @Author: top.brids 
 * @Date: 2022-02-13 22:12:34 
 * @Last Modified by: top.brids
 * @Last Modified time: 2022-02-14 17:01:14
 * @Last Remark: 策略定制 vx:wkc19891
 */
//1
let isBuy = false;
let isIncome = false;
let blackSymbol = BlackCoin.split('&');// ['NUUSDT'];

let isOk = false;
let isBinance = false;
let SymbolsEx = [];
let button0 = [];
let stoplist = [];
let listpft = [];
let listpft2 = [];
let Qs = [];
let doLong = false;
let doShort = false;
let followCoins = [];
let exs = "";
let trade_info = {};


let acc = null;
let list1 = [];
let list2 = [];
let longAddCount = [];
let shortAddCount = [];
let lSubP = [];
let sSubP = [];
let mlist = 0;
//2
let init_Balance = null;
let FSTTime = null;


//5
let account1 = null;
//6
let walletbalance = 0;
let walletB = 0;
let unrealizedProfit = 0;
let pft = 0;
let ir = 0;

//
function table() {
    account1 = _C(exchange.GetAccount)
    let pos = []
    account1.Info.positions.map(v => {
        if (Number(v.positionAmt) != 0) {
            pos.push(v)
        }
    })
    //USDT保证金余额
    let totalMarginBalance = 0;
    let walletbalance = 0;
    unrealizedProfit = 0;
    if (isOk) {
        totalMarginBalance = account1.Info.data[0].details[0].cashBal;
        walletbalance = account1.Info.data[0].details[0].disEq;
        unrealizedProfit = account1.Info.data[0].details[0].upl;
    }
    if (isBinance) {
        totalMarginBalance = account1.Info.totalMarginBalance;
        walletbalance = account1.Info.totalWalletBalance;
        unrealizedProfit = account1.Info.totalUnrealizedProfit;
    }
    let toxh = _G('ToXh') == null ? 0 : _G('ToXh');
    let toHy = _G('ToHy') == null ? 0 : _G('ToHy');
    let lsAmount = _G("lsAmount") == null ? 0 : _G("lsAmount");
    let fee = _N(lsAmount * 0.01 * 0.075, 4);

    pft = _N((parseFloat(walletbalance) + parseFloat(unrealizedProfit) + parseFloat(toxh) - parseFloat(toHy)), 4);
    //table2内容, USDT
    let NOWTime = _D() //当前时间
    let profit_ratio = 0
    if (init_Balance != 0) {
        profit_ratio = ((parseFloat(walletbalance) + toxh - parseFloat(init_Balance)) / parseFloat(init_Balance)) * 100
    }
    ///两个表格的选项
    let tab1 = {
        "type": "table",
        "title": "账户信息",
        "cols": ["初始资金", "钱包余额", "保证金余额", "划转到现货", "划转到合约", "全部未实现盈亏", "全部净利润", "总收益率", "交易流水", "手续费", "循环延时"],
        "rows": []
    }
    let tabc = {
        "type": "table",
        "title": "交易对信息",
        "cols": ["币种名称", "开仓价格", "杠杆", "持仓方向", "持仓数量", "持仓价值", "未实现盈亏"],
        "rows": []
    }
    let tab2 = {
        "type": "table",
        "title": "时间",
        "cols": ["初始时间", "当前时间"],
        "rows": []
    }
    let tab4 = {
        "type": "table",
        "title": "联系方式",
        "cols": ["微信", "QQ", "Telegram", "说明"],
        "rows": []
    }
    let jieshao1 = 'wkc19891'
    let jieshao2 = '道式量化[合作添加备注FMZ]'
    let str = "✱策略可租用 #32CD32"
    let str2 = "✱实盘风险自担 #007FFF"
    //往表格里加内容
    tab1.rows.push([`${_N(parseFloat(init_Balance), 6)}U`, `${_N(parseFloat(walletbalance), 6)}U`, `${_N(parseFloat(totalMarginBalance), 6)}U`, `${toxh}U`, `${toHy}U`, `${_N(parseFloat(unrealizedProfit), 6)}U`, `${pft}U`, `${_N(profit_ratio, 6)}%`, `${lsAmount}U`, `${fee}U`, `${trade_info.loop_delay}ms #FF0000`])
    tab2.rows.push([`${FSTTime}`, `${NOWTime}`])
    tab4.rows.push([`${jieshao1}`, "2043692042", "https://t.me/aelf_china", `${jieshao2}`])
    for (let i = 0; i < pos.length; i++) {
        let v = pos[i];
        // button0[i] = { "type": "button", "name": "平仓", "cmd": `${v.symbol}:平仓:${v.positionSide}:${v.positionAmt}`, "description": "平仓" }
        tabc.rows.push([v.symbol, _N(Number(v.entryPrice), 4), v.leverage, v.positionSide == "LONG" ? `${v.positionSide}#32CD32` : `${v.positionSide}#FF0000`, Math.abs(Number(v.positionAmt)), `${_N(Number(v.initialMargin) * Number(v.leverage), 2)}U`, Number(v.unrealizedProfit) < 0 ? `${_N(Number(v.unrealizedProfit), 4)} #FF0000` : `${_N(Number(v.unrealizedProfit), 4)} #32CD32`])
    }
    //打印栏
    LogStatus("`" + JSON.stringify(tab2) + "`\n" + "`" + JSON.stringify(tab1) + "`\n" + "`" + JSON.stringify(tabc) + "`\n" + "`" + JSON.stringify(tab4) + "`\n" + "策略启动时间:" + FSTTime + "\n" + str + "\n" + str2)
}
//
function CalLsAmount(amount, price) {
    let lsUsdt = parseFloat(amount) * parseFloat(price) * 2;
    let lsAmount = _G("lsAmount") == null ? 0 : _G("lsAmount");
    lsAmount += lsUsdt;
    lsAmount = _N(lsAmount, 4)
    _G("lsAmount", lsAmount)
}
//
function Coverall() {
    Log('您的账户已经全部清仓@')
}
//
function mainBefor() {
    exchange.SetContractType("swap");
    account1 = exchange.GetAccount();
    if (isOk) {
        let exchangeInfo = exchange.IO("api", "GET", "/api/v5/public/instruments?instType=SWAP");
        SymbolsEx = exchangeInfo.data;
        walletbalance = account1.Info.data[0].details[0].disEq;
    }
    if (isBinance) {
        let exchangeInfo = exchange.IO("api", "GET", `/fapi/v1/exchangeInfo`, ``, ``)
        SymbolsEx = exchangeInfo.symbols;
        walletbalance = account1.Info.totalWalletBalance;
    }
    if (_G('init_Balance') && _G('FSTTime')) {
        Log('成功读取上次进度!')
        init_Balance = _G('init_Balance')
        FSTTime = _G('FSTTime')
    } else {
        Log('程序第一次运行,保存初始资金数据!#3299cc')
        if (isOk) {
            init_Balance = account1.Info.data[0].details[0].disEq;
        }
        if (isBinance) {
            init_Balance = account1.Info.totalWalletBalance;
        }
        FSTTime = _D()
        _G('init_Balance', init_Balance)
        _G('FSTTime', FSTTime)
    }
    if (_G('lSubP') && _G('sSubP') && _G('acc') && _G('listpft') && _G('listpft2') && _G('list1') && _G('list2') && _G('mlist')) {
        acc = _G('acc')
        listpft = _G('listpft')
        listpft2 = _G('listpft2')
        list1 = _G('list1')
        list2 = _G('list2')
        longAddCount = _G('longAddCount')
        shortAddCount = _G('shortAddCount')
        lSubP = _G('lSubP')
        sSubP = _G('sSubP')
        mlist = _G('mlist')
    } else {
        acc = []
        _G('acc', acc)
        listpft = []
        listpft2 = []
        list1 = []
        list2 = []
        shortAddCount = []
        longAddCount = []
        lSubP = []
        sSubP = []
        mlist = T0
        for (let i = 0; i < 100; i++) {
            listpft.push([])
            listpft2.push([])
            longAddCount.push([])
            longAddCount[i] = 0
            shortAddCount.push([])
            shortAddCount[i] = 0
            lSubP.push([])
            lSubP[i] = 0;
            sSubP.push([])
            sSubP[i] = 0;
            list1.push(0)
            list2.push(0)

        }
        _G('listpft', listpft)
        _G('listpft2', listpft2)
        if (!_G('longAddCount')) {
            _G('longAddCount', longAddCount)
        } else {
            longAddCount = _G('longAddCount')
        }
        if (!_G('shortAddCount')) {
            _G('shortAddCount', shortAddCount)
        } else {
            shortAddCount = _G('shortAddCount')
        }
        _G('list1', list1)
        _G('list2', list2)
        _G('mlist', mlist)
        _G('lSubP', lSubP)
        _G('sSubP', sSubP)
    }
}
//
function core() {
    let posCount = 0;
    let posLong = null;
    let posShort = null;
    let time = new Date()
    let hour = time.getHours()
    let minute = time.getMinutes()
    let second = time.getSeconds()
    if ((hour == 23 || hour == 7 || hour == 15) && minute == 59 && second > 58) {
        Log(21)
        let usdtOrderAmount = account1.Info.totalWalletBalance / 8;
        account1.Info.positions.forEach((item1) => {
            if (Number(item1.positionAmt) != 0) {
                posCount++;
                if (Number(item1.positionAmt) > 0) {
                    posLong = item1;
                }
                if (Number(item1.positionAmt) < 0) {
                    posShort = item1;
                }
            }
        });
        if (posCount < 2 && !isBuy) {
            isBuy = true;
            //获取正费率和负费率交易对
            let response = exchange.IO("api", "GET", "/fapi/v1/premiumIndex", "", "");
            let symbolArr = response.data;
            let compare = function (prop) {
                return function (obj1, obj2) {
                    var val1 = obj1[prop];
                    var val2 = obj2[prop];
                    if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
                        val1 = Number(val1);
                        val2 = Number(val2);
                    }
                    if (val1 < val2) {
                        return 1;
                    } else if (val1 > val2) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            }
            symbolArr.sort(compare("lastFundingRate"))
            //黑名单
            blackSymbol.map(v => {
                let index = symbolArr.findIndex(a => a.symbol == v)
                if (index != -1) {
                    symbolArr.splice(index, 1)
                }
            })
            let fristSymbol = symbolArr[0]
            let lastSymbol = symbolArr[symbolArr.length - 1]
            let fristPrice = fristSymbol.markPrice;
            let lastPrice = lastSymbol.markPrice;
            let leverage = 20;
            let leverage1 = 20;
            let leverage2 = 20;
            //确定杠杆
            let leverageRes = exchange.IO("api", "GET", "/fapi/v1/leverageBracket", "", "");
            leverageRes.map(v => {
                if (v.symbol == fristSymbol.symbol) {
                    leverage1 = v.brackets[0].initialLeverage
                }
                if (v.symbol == lastSymbol.symbol) {
                    leverage2 = v.brackets[0].initialLeverage
                }
            });
            leverage = Math.min(leverage1, leverage2, M);
            //修改杠杆
            exchange.IO("api", "POST", "/fapi/v1/leverage", `symbol=${fristSymbol.symbol}&leverage=${leverage}`, "");
            Log(`1.修改杠杆:${fristSymbol.symbol},杠杆:${leverage}`);
            exchange.IO("api", "POST", "/fapi/v1/leverage", `symbol=${lastSymbol.symbol}&leverage=${leverage}`, "");
            Log(`2.修改杠杆:${lastSymbol.symbol},杠杆:${leverage}`);
            //获取精度
            let fQ = 3;
            let lQ = 3;
            let exRes = exchange.IO("api", "GET", "/fapi/v1/exchangeInfo", "", "");
            exRes.symbols.map((v, i) => {
                if (v.symbol == fristSymbol.symbol) {
                    fQ = v.quantityPrecision;
                }
                if (v.symbol == lastSymbol.symbol) {
                    lQ = v.quantityPrecision;
                }
            });
            //下单数量
            let fAmount = Number((usdtOrderAmount * leverage / fristPrice).toFixed(fQ));
            let lAmount = Number((usdtOrderAmount * leverage / lastPrice).toFixed(lQ));
            //正费率进空
            let ex1 = exchange.IO("api", "POST", "/fapi/v1/order", `symbol=${fristSymbol.symbol}&side=SELL&positionSide=SHORT&type=MARKET&quantity=${fAmount}`, "");
            Log('卖出成功1=>', ex1);
            //负费率进多
            let ex2 = exchange.IO("api", "POST", "/fapi/v1/order", `symbol=${lastSymbol.symbol}&side=BUY&positionSide=LONG&type=MARKET&quantity=${lAmount}`, "");
            Log('买入成功2=>', ex2)
            LogProfit(pft)
        }
    } else {
        //条件达到平仓
        let runFlag = false;
        if ((hour == 23 || hour == 7 || hour == 15 || hour == 0 || hour == 8 || hour == 16)) {
            if ((minute != 59 && minute != 0) || (minute == 0 || second > 4)) {
                runFlag = true;
            }
        } else {
            runFlag = true;
        }
        if (runFlag) {
            account1.Info.positions.forEach((item1) => {
                if (Number(item1.positionAmt) != 0) {
                    posCount++;
                    if (Number(item1.positionAmt) > 0) {
                        posLong = item1;
                    }
                    if (Number(item1.positionAmt) < 0) {
                        posShort = item1;
                    }
                }
            });
            //收益持平平仓
            if (posCount >= 2) {
                let unrealizedProfit = 0;
                let fee = 0;
                if (posLong != null) {
                    fee += Number(posLong.positionAmt) * Number(posLong.entryPrice) * 0.01 * 0.1;
                    unrealizedProfit += Number(posLong.unrealizedProfit);
                }
                if (posShort != null) {
                    fee += Number(posShort.positionAmt) * Number(posShort.entryPrice) * 0.01 * 0.1 * -1;
                    unrealizedProfit += Number(posShort.unrealizedProfit);
                }
                //保本清仓
                if (unrealizedProfit >= fee && posLong != null && posShort != null && !isIncome) {
                    isIncome = true;
                    //多单清仓
                    let ex1 = exchange.IO("api", "POST", "/fapi/v1/order", `symbol=${posLong.symbol}&side=SELL&positionSide=LONG&type=MARKET&quantity=${Number(posLong.positionAmt)}`, "");
                    Log('多单清仓成功1=>', ex1)
                    let ex2 = exchange.IO("api", "POST", "/fapi/v1/order", `symbol=${posShort.symbol}&side=BUY&positionSide=SHORT&type=MARKET&quantity=${-Number(posShort.positionAmt)}`, "");
                    //空单清仓
                    if (ex2 != null) {
                        Log('空单清仓成功2=>', ex2);
                        isIncome = false;
                        isBuy = false;
                    }
                    LogProfit(pft)
                }
            }
        }
    }
}
//
function main() {
    let eName = exchange.GetName();
    isOk = eName.indexOf("OKCoin") != -1;
    isBinance = eName.indexOf("Binance") != -1;
    if (!isBinance) {
        throw "该策略只支持币安"
    }
    if (isBinance) {
        let ret = exchange.IO("api", "GET", "/fapi/v1/positionSide/dual")
        if (!ret.dualSidePosition) {
            let ret1 = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true")
            Log('修改持仓成功', ret1)
        }
    }
    followCoins = [];
    for (let i = 0; i < exchanges.length; i++) {
        let coin = exchanges[i].GetCurrency();
        let _coin = coin.split('_');
        let c = _coin[0] + _coin[1];
        followCoins.push(c)
        exs += c;
    }
    Log("run coins:", followCoins)
    let exlengths = _G('exlengths')
    if (exlengths == null) {
        _G('exlengths', exs)
    } else {
        if (exlengths != exs) {
            _G('lSubP', null);
            _G('sSubP', null);
            _G('acc', null);
            _G('listpft', null);
            _G('listpft2', null)
            _G('list1', null);
            _G('list2', null);
            _G('mlist', null);
            _G('exlengths', exs)
            Log(`exs changed...${exs}`)
        }
    }
    if (isOk) {
        longAddRate = _N(longAddRate, 0)
        shortAddRate = _N(shortAddRate, 0)
    }
    for (let i = 0; i < exchanges.length; i++) {
        button0.push(0)
        Qs[i] = "";
    }
    mainBefor()
    if (M > 30) {
        M = 30;
    }
    while (true) {
        let loop_start = Date.now();
        try {
            table()
            core()
            if (isBinance) {
                mlist = T0;
            }
            if (isOk) {
                walletB = account1.Info.data[0].details[0].cashBal;
            }
            if (isBinance) {
                walletB = account1.Info.totalWalletBalance + account1.Info.totalUnrealizedProfit;
            }
            if (walletB > mlist) {
                if (isOk) {
                    mlist += T1
                    _G('mlist', mlist)
                    Log('下次阀值更新为:', mlist)
                }
                if (isBinance) {
                    let amount = T1;
                    if (amount > 5) {
                        let timestamp = new Date().getTime();
                        let base = "https://api.binance.com"
                        exchange.SetBase(base)
                        let res = exchange.IO("api", "POST", "/sapi/v1/futures/transfer", `asset=USDT&amount=${amount}&type=2&timestamp=${timestamp}`, "")
                        Log('划转到现货', res, amount)
                        let toxh = _G('ToXh') == null ? 0 : _G('ToXh')
                        toxh += amount
                        _G('ToXh', toxh)
                        base = "https://fapi.binance.com"
                        exchange.SetBase(base)
                    }
                }
                Log('盈利达到设定值,全部清仓')
                Coverall()
            }
            let cmd = GetCommand()
            if (cmd) {
                arr = cmd.split(':')
                if (arr[0] == '一键平仓') {
                    Coverall()
                    Sleep(100000000000)
                }
                if (arr[0] == '转到合约') {
                    if (isBinance) {
                        let amount = parseInt(arr[1]);
                        let timestamp = new Date().getTime();
                        let base = "https://api.binance.com"
                        exchange.SetBase(base)
                        let res = exchange.IO("api", "POST", "/sapi/v1/futures/transfer", `asset=USDT&amount=${amount}&type=1&timestamp=${timestamp}`, "")
                        Log('现货划转到合约', res, amount)
                        let toHy = _G('ToHy') == null ? 0 : _G('ToHy')
                        toHy += amount
                        _G('ToHy', toHy)
                        base = "https://fapi.binance.com"
                        exchange.SetBase(base)
                    } else {
                        Log('OK暂不支持划转')
                    }
                }
                if (arr[0] == '转到现货') {
                    if (isBinance) {
                        let amount = parseInt(arr[1]);
                        let timestamp = new Date().getTime();
                        let base = "https://api.binance.com"
                        exchange.SetBase(base)
                        let res = exchange.IO("api", "POST", "/sapi/v1/futures/transfer", `asset=USDT&amount=${amount}&type=2&timestamp=${timestamp}`, "")
                        Log('合约划转到现货', res, amount)
                        let toxh = _G('ToXh') == null ? 0 : _G('ToXh')
                        toxh += amount
                        _G('ToXh', toxh)
                        base = "https://fapi.binance.com"
                        exchange.SetBase(base)
                    } else {
                        Log('OK暂不支持划转')
                    }
                }
                if (arr[0] == '清空日志') {
                    LogReset()
                    Log('日志已经清空')
                }
                if (arr[0] == '重置收益') {
                    _G(null)
                    LogReset()
                    stoplist = [];
                    LogProfitReset()
                    mainBefor()
                    Log('已重置收益')
                }
            }
        } catch (e) {
            Log('系统error', e);
            Sleep(S * 10)
        }
        Sleep(S)
        trade_info.loop_delay = Date.now() - loop_start;
    }
}

More

轻轻的云 【赞】!!!【赞】!!!【赞】!!!