Skip to content

Latest commit

 

History

History
1229 lines (1194 loc) · 48.1 KB

(币安)多产品趋势马丁与逆势马丁【策略分享】.md

File metadata and controls

1229 lines (1194 loc) · 48.1 KB

策略名称

(币安)多产品趋势马丁与逆势马丁【策略分享】

策略作者

高频量化

策略描述

策略定制 vx:18826683356 策略来源:FMZ网站 由于比较多人找我写马丁类型的策略。 那么我在网站上找了一个可以运行的分享给大家。 希望对大家投资活动有所帮助 实盘测试可以跑起来 私有地址: https://www.fmz.com/robot/1fa0aeff0dfdd66645a198f28766aa0c

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

策略参数

参数 默认值 描述
OpType 0 操作类型: 做多
M 20 杠杆倍数
P 100 下单价值
IsAuto false 启用趋势
IsHt true 启用回调
Z true 回撤止盈触发阀值(%)
K4 8 利润回撤止盈百分比(%)
E1 0.6 1-2补仓间距
E2 true 3-4补仓间距
E3 1.5 5-6补仓间距
E4 2 6+补仓间距
HcK4 8 回调补仓百分比(%)
C1 0.5 保本平仓线
longAddRate true 多单加仓倍数
shortAddRate true 空单加仓倍数
Jt true 是否自动解套
maxLAC 10 多单磨损仓
maxSAC 10 空单磨损仓
Zs false 是否止损
ZsLong false 单币浮亏多单止损
ZsShort false 单币浮亏空单止损
T0 600 转账/清仓阀值
T1 100 转账/清仓值
S 10 轮询时间(s)
按钮 默认值 描述
清空日志 button 清空日志
一键平仓 button 一键平仓
重置收益 button 重置收益
转到合约 100 转到合约
转到现货 100 转到现货

源码 (javascript)

/*
 * @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:18826683356
 */

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 long1 = false;
let short1 = false;
let qsL = false;
let qsS = false;
let followCoins = [];
let exs = "";
let trade_info = {};
let loop_start2 = Date.now();

let acc = null;
let list1 = [];
let list2 = [];
let longAddCount = [];
let shortAddCount = [];
let lSubP = [];
let sSubP = [];
let mlist = 0;
let initMacd30 = { isSame: null, flag: '', coin: '' }
//2
let init_Balance = null;
let FSTTime = null;
//3
let k = 0;
//4
let BV1 = 0;
let CV1 = 0;
//5
let n1 = 0;
let account1 = null;
let position1 = null;
//6
let walletbalance = 0;
let walletB = 0;
let unrealizedProfit = 0;
let pft = 0;
let ir = 0;

//获取合约面值
function GetCtVal(coin1) {
    let coin = `${coin1.split('_')[0]}-${coin1.split('_')[1]}-SWAP`;
    let ctVal = 1;
    SymbolsEx.map((v, i) => {
        if (v.instId == coin) {
            ctVal = Number(v.ctVal);
        }
    });
    return ctVal;
}
//获取交易所精度 算首仓
function accuracyOk() {
    exchanges[k].SetContractType('swap');
    let coin = '';
    let coin1 = _C(exchanges[k].GetCurrency);
    coin = `${coin1.split('_')[0]}-${coin1.split('_')[1]}-SWAP`;
    let ticker1 = _C(exchanges[k].GetTicker)
    let quantityPrecision = 0;
    account1 = _C(exchanges[k].GetAccount)
    let minSz = 0;
    let ctVal = 1;
    SymbolsEx.map((v, i) => {
        if (v.instId == coin) {
            quantityPrecision = Number(v.lotSz);//下单数量精度
            minSz = Number(v.minSz) * Number(v.ctVal);
            ctVal = Number(v.ctVal);
        }
    });
    n1 = _N(P / ticker1.Last, quantityPrecision)
    let msg = ''
    if (n1 <= 0 || n1 < minSz) {
        n1 = 0;
        msg = `当前下单面值可开单个数${n1},${coin}=>最小下单数量:${minSz}`
    }

    n1 = _N(n1 / ctVal, 0)
    let data = { coin: coin1, amount: n1, msg: msg }
    Log(coin, '下单价值', P, 'U', '开单张数', n1, '合约面值', ctVal)
    return data;
}
//binance
function accuracyBinance() {
    exchanges[k].SetContractType('swap');
    let coin = '';
    let coin1 = _C(exchanges[k].GetCurrency);
    coin = coin1.split('_')[0] + coin1.split('_')[1];
    let ticker1 = _C(exchanges[k].GetTicker)
    let quantityPrecision = 0;
    account1 = _C(exchanges[k].GetAccount)
    SymbolsEx.map((v, i) => {
        if (v.symbol == coin) {
            quantityPrecision = v.quantityPrecision;
        }
    });
    n1 = _N(P / ticker1["Last"], quantityPrecision)
    let msg = ''
    if (n1 <= 0) {
        msg = `${coin},当前下单面值可开单个数${n1}`
    }
    let data = { coin: coin1, amount: n1, msg: msg }
    Log(coin, n1, '下单价值', P, 'U', '开单个数', n1)
    return data;
}
//
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;
    //获取账户基本信息
    position1 = _C(exchange.GetPosition)
    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(init_Balance) + parseFloat(toxh) - parseFloat(toHy)), 6);
    //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": ["币种名称", "趋势", "开仓价格", "持仓方向", "持仓数量", "持仓价值", "未实现盈亏", "L | S | I ", "操作"],
        "rows": []
    }
    let tab2 = {
        "type": "table",
        "title": "时间",
        "cols": ["初始时间", "当前时间"],
        "rows": []
    }
    let tab4 = {
        "type": "table",
        "title": "联系方式",
        "cols": ["微信", "QQ", "Telegram", "说明"],
        "rows": []
    }
    let jieshao1 = ''
    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`, `${M}`, `${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}`, "", "https://", `${jieshao2}`])
    for (let i = 0; i < pos.length; i++) {
        let v = pos[i];
        let ir = followCoins.indexOf(v.symbol);
        let qs = Qs[ir] == "Long" ? "Long #00FF00" : Qs[ir] == "Short" ? "Short #FF0000" : "震荡中 #3299cc"
        button0[i] = { "type": "button", "name": "平仓", "cmd": `${v.symbol}:平仓:${v.positionSide}:${v.positionAmt}`, "description": "平仓" }
        let pc = 0;
        let pc2 = 0;
        let tj = 0;
        if (ir != -1) {
            lSubP[ir] = _N(lSubP[ir], 4)
            tj = lSubP[ir] > 0 ? `${lSubP[ir]} #00FF00` : `${lSubP[ir]} #FF0000`;
            pc = _N(list1[ir], 4)
            pc2 = _N(list2[ir], 4)
        }
        tabc.rows.push([v.symbol, qs, _N(Number(v.entryPrice), 4), v.positionSide == "LONG" ? `${v.positionSide}#32CD32` : `${v.positionSide}#FF0000`, Math.abs(Number(v.positionAmt)), `${_N(Number(v.initialMargin), 2)}U[${v.leverage}]X`, Number(v.unrealizedProfit) < 0 ? `${_N(Number(v.unrealizedProfit), 4)} #FF0000` : `${_N(Number(v.unrealizedProfit), 4)} #32CD32`, `${pc} | ${pc2} | ${tj}`, button0[i]])
    }
    //打印栏
    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() {
    account1 = _C(exchange.GetAccount)
    if (isOk) {
        walletbalance = account1.Info.data[0].details[0].cashBal;
        unrealizedProfit = account1.Info.data[0].details[0].upl;
    }
    if (isBinance) {
        walletbalance = account1.Info.totalWalletBalance;
        unrealizedProfit = account1.Info.totalUnrealizedProfit;
    }
    for (let i = 0; i < exchanges.length; i++) {
        exchanges[i].SetContractType("swap")
        let _position1 = _C(exchanges[i].GetPosition)
        let position1 = []
        let sPos = "";
        let lPos = "";
        for (let i = 0; i < _position1.length; i++) {
            let v = _position1[i];
            if (v.Type == 0) {
                lPos = v;
            }
            if (v.Type == 1) {
                sPos = v;
            }
        }
        if (lPos != "") {
            position1.push(lPos)
        }
        if (sPos != "") {
            position1.push(sPos)
        }
        if (position1.length == 1) {
            if (position1[0]["Type"] == 0) {
                exchanges[i].SetDirection("closebuy")
                exchanges[i].Sell(-1, position1[0].Amount)
                let ticker1 = _C(exchanges[i].GetTicker)
                CalLsAmount(position1[0].Amount, ticker1.Last)
            }
            if (position1[0]["Type"] == 1) {
                exchanges[i].SetDirection("closesell")
                exchanges[i].Buy(-1, position1[0].Amount)
                let ticker1 = _C(exchanges[i].GetTicker)
                CalLsAmount(position1[0].Amount, ticker1.Last)
            }
        }
        if (position1.length == 2) {
            exchanges[i].SetDirection("closebuy")
            exchanges[i].Sell(-1, position1[0].Amount)
            let ticker1 = _C(exchanges[i].GetTicker)
            CalLsAmount(position1[0].Amount, ticker1.Last)
            exchanges[i].SetDirection("closesell")
            exchanges[i].Buy(-1, position1[1].Amount)
            CalLsAmount(position1[1].Amount, ticker1.Last)
        }
    }
    _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('longAddCount', null);
    _G('shortAddCount', null);
    Log('您的账户已经全部清仓@')
}
//
function CancelOrderAll(e) {
    let orders = e.GetOrders()
    if (orders.length > 0) {
        for (let i = 0; i < orders.length; i++) {
            let order = orders[i];
            e.CancelOrder(order.Id)
        }
        Log("撤销所有未成功订单")
    }
}
//
//
function GetE(ir, type) {
    let count = 0;
    let rate = E1;
    if (type == 0) {
        count = longAddCount[ir]
    }
    if (type == 1) {
        count = longAddCount[ir]
    }
    if (count > 0 && count < 2) {
        rate = E1
    } else if (count >= 2 && count < 4) {
        rate = E2
    }
    else if (count >= 4 && count < 6) {
        rate = E3
    }
    else if (count >= 6) {
        rate = E4
    } else {
        rate = E1
    }
    rate = rate * 0.01;
    return rate;
}
//
//trade
function trade() {
    let currency = _C(exchanges[ir].GetCurrency)
    position1 = _C(exchanges[ir].GetPosition)
    let ticker1 = _C(exchanges[ir].GetTicker)
    let ctVal = 1;

    let quantityPrecision = 0;
    if (isBinance) {
        let _currency = currency.split("_")[0] + currency.split("_")[1]
        SymbolsEx.map((v, i) => {
            if (v.symbol == _currency) {
                quantityPrecision = v.quantityPrecision;
            }
        });
    }
    if (!IsAuto || OpType == 0 || OpType == 1) {
        long1 = true;
        short1 = true;
    }
    if (OpType == 0) {
        doLong = true;
    } else if (OpType == 1) {
        doShort = true;
    } else {
        if (IsAuto) {
            //趋势判断
            if (Date.now() - loop_start2 > 60000) {
                loop_start2 = Date.now();
                let r = exchanges[ir].GetRecords(PERIOD_M1)
                let kdj = TA.KDJ(r, 9, 3, 3)
                let k = kdj[0][kdj[0].length - 1];
                let k2 = kdj[0][kdj[0].length - 2];
                let d = kdj[1][kdj[1].length - 1];
                let d2 = kdj[1][kdj[1].length - 2];
                let emaFast = TA.EMA(r, 7);
                let emaSlow = TA.EMA(r, 12);
                let kdj2 = TA.KDJ(r, 9, 3, 3)
                let k3 = kdj2[0][kdj2[0].length - 1];
                let d3 = kdj2[1][kdj2[1].length - 1];
                qsL = emaFast[emaFast.length - 1] > emaSlow[emaSlow.length - 1] && k3 > d3;
                qsS = emaFast[emaFast.length - 1] < emaSlow[emaSlow.length - 1] && k3 < d3;
                doLong = qsL;
                doShort = qsS;
                let boll = TA.BOLL(r, 75, 2)
                let upLine = boll[0][boll[0].length - 1]
                let downLine = boll[2][boll[2].length - 1]
                if (ticker1.Last >= upLine) {
                    long1 = k2 <= d2 && k > d
                } else if (ticker1.Last <= downLine) {
                    short1 = k2 >= d2 && k < d
                } else {
                    long1 = true;
                    short1 = true;
                }
            }
        } else {
            doLong = true;
            doShort = true;
        }
    }
    Qs[ir] = IsAuto ? doLong ? "Long" : doShort ? "Short" : "" : ""
    //止损
    if (Zs) {
        if (position1.length == 2) {
            if (ZsLong != 0 && position1[0].Profit < -ZsLong && longAddCount[ir] >= maxLAC) {
                exchanges[ir].SetDirection('closebuy')
                exchanges[ir].Sell(-1, position1[0].Amount)
                CalLsAmount(position1[0].Amount, ticker1.Last)
                list1[ir] = 0
                _G('list1', list1)
                longAddCount[ic] = 0;
                _G('longAddCount', longAddCount)
                lSubP[ir] = 0;
                _G('lSubP', lSubP);
                Log(currency, '多单止损 卖出平多 清仓')
                LogProfit(pft)
            }
            if (ZsShort != 0 && position1[1].Profit < -ZsShort && shortAddCount[ir] >= maxSAC) {
                exchanges[ir].SetDirection('closesell')
                exchanges[ir].Buy(-1, position1[1].Amount)
                CalLsAmount(position1[1].Amount, ticker1.Last)
                list2[ir] = 0
                _G('list2', list2)
                shortAddCount[ir] = 0;
                _G('shortAddCount', shortAddCount)
                sSubP[ir] = 0;
                _G('sSubP', sSubP);
                Log(currency, '空单止损 买入平空 清仓')
                LogProfit(pft)
            }
        }
        if (position1.length == 1) {
            if (ZsLong != 0 && position1[0].Type == 0) {
                if (position1[0].Profit < -ZsLong && longAddCount[ir] >= maxLAC) {
                    exchanges[ir].SetDirection('closebuy')
                    exchanges[ir].Sell(-1, position1[0].Amount)
                    CalLsAmount(position1[0].Amount, ticker1.Last)
                    list1[ir] = 0
                    _G('list1', list1)
                    longAddCount[ic] = 0;
                    _G('longAddCount', longAddCount)
                    lSubP[ir] = 0;
                    _G('lSubP', lSubP);
                    Log(currency, '多单止损 卖出平多 清仓')
                    LogProfit(pft)
                }
            }
            if (ZsShort != 0 && position1[0].Type == 1) {
                if (position1[0].Profit < -ZsShort && shortAddCount[ir] >= maxSAC) {
                    exchanges[ir].SetDirection('closesell')
                    exchanges[ir].Buy(-1, position1[0].Amount)
                    CalLsAmount(position1[0].Amount, ticker1.Last)
                    list2[ir] = 0
                    _G('list2', list2)
                    shortAddCount[ir] = 0;
                    _G('shortAddCount', shortAddCount)
                    sSubP[ir] = 0;
                    _G('sSubP', sSubP);
                    Log(currency, '空单止损 买入平空 清仓')
                    LogProfit(pft)
                }
            }
        }
    }
    //解套

    //保本平仓

    //大周期上升
    if (doLong && longAddCount[ir] < maxLAC) {
        if (position1.length == 0) {
            //1分钟金叉开多
            if (long1) {
                exchanges[ir].SetDirection('buy')
                exchanges[ir].Buy(-1, acc[ir])
                list1[ir] = ticker1.Last;
                _G('list1', list1)
                Log(currency, '进场开多,首单进场价格1:', list1[ir])
                LogProfit(pft)
            }
        }
        if (position1.length > 0) {
            // 只持有1单
            if (position1.length == 1) {
                // 只持有多单
                if (position1[0].Type == 0) {
                    if ((position1[0].Profit + lSubP[ir]) > 0.01 * Z * ticker1.Last * position1[0].Amount * ctVal) {
                        listpft[ir].push(position1[0].Profit)
                        _G('listpft', listpft)
                        let maxpft = Math.max(...listpft[ir])
                        if (position1[0].Profit < (1 - 0.01 * K4) * maxpft) {
                            exchanges[ir].SetDirection('closebuy')
                            exchanges[ir].Sell(-1, position1[0].Amount)
                            CalLsAmount(position1[0].Amount, ticker1.Last)
                            listpft[ir] = []
                            _G('listpft', listpft)
                            longAddCount[ir] = 0;
                            _G('longAddCount', longAddCount);
                            list1[ir] = 0
                            _G('list1', list1)
                            lSubP[ir] = 0;
                            _G('lSubP', lSubP);
                            Log(currency, '止盈信号达到1:', K4, ',平多止盈')
                            LogProfit(pft)
                            return;
                        }
                    }
                    //金叉给多单补仓
                    if (position1[0].Profit < 0) {
                        if (list1[ir].Price == 0 || list1[ir] == undefined) {
                            list1[ir] = position1[0].Price
                        }
                        if (ticker1.Last < (1 - GetE(ir, 0)) * list1[ir]) {
                            listpft[ir].push(position1[0].Profit)
                            _G('listpft', listpft)
                            let maxpft = Math.min(...listpft[ir])
                            if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft) {
                                exchanges[ir].SetDirection('buy')
                                let amount = acc[ir] * Math.pow(2, longAddCount[ir])
                                exchanges[ir].Buy(-1, amount);
                                list1[ir] = ticker1.Last;
                                _G('list1', list1)
                                longAddCount[ir] = longAddCount[ir] + 1;
                                _G('longAddCount', longAddCount);
                                Log(`1.${currency},补仓信号${HcK4},多单补仓,补仓价格:${list1[ir]},补仓次数:${longAddCount[ir]}`)
                                LogProfit(pft)
                            }
                        }
                    }
                }
                //只持有空单
                if (position1[0].Type == 1) {
                    //1分钟金叉开多
                    if (long1) {
                        exchanges[ir].SetDirection('buy')
                        exchanges[ir].Buy(-1, acc[ir])
                        list1[ir] = ticker1.Last;
                        _G('list1', list1)
                        Log(currency, '进场开多,首单进场价格2:', list1[ir])
                        LogProfit(pft);
                    }
                    //空单补仓
                    if (position1[0].Profit < 0) {
                        if (list2[ir].Price == 0 || list2[ir] == undefined) {
                            list2[ir] = position1[0].Price
                        }
                        if (ticker1.Last > (1 + 3 * GetE(ir, 1)) * list2[ir]) {
                            listpft2[ir].push(position1[0].Profit)
                            _G('listpft2', listpft2)
                            let maxpft2 = Math.min(...listpft2[ir])
                            if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft2) {
                                exchanges[ir].SetDirection('sell')
                                let amount = acc[ir] * Math.pow(2, shortAddCount[ir])
                                exchanges[ir].Sell(-1, amount)
                                list2[ir] = ticker1.Last;
                                _G('list2', list2)
                                shortAddCount[ir] = shortAddCount[ir] + 1;
                                _G('shortAddCount', shortAddCount);
                                Log(`${currency},补仓信号${HcK4},空单补仓,补仓价格:${list2[ir]},补仓次数:${shortAddCount[ir]}`)
                                LogProfit(pft)
                            }
                        }
                    } else {
                        //空单止盈
                        if ((position1[0].Profit + sSubP[ir]) > 0.01 * C1 * ticker1.Last * position1[0].Amount * ctVal) {
                            exchanges[ir].SetDirection('closesell')
                            exchanges[ir].Buy(-1, position1[0].Amount)
                            CalLsAmount(position1[0].Amount, ticker1.Last)
                            list2[ir] = 0
                            _G('list2', list2)
                            shortAddCount[ir] = 0;
                            _G('shortAddCount', shortAddCount);
                            sSubP[ir] = 0;
                            _G('sSubP', sSubP);
                            Log(currency, '空单盈利,平空止盈1')
                            LogProfit(pft);
                        }
                    }
                }
            }
            if (position1.length == 2) {
                //多单模块
                if ((position1[0].Profit + lSubP[ir]) > 0.01 * Z * ticker1.Last * position1[0].Amount * ctVal) {
                    listpft[ir].push(position1[0].Profit)
                    _G('listpft', listpft)
                    let maxpft = Math.max(...listpft[ir])
                    if (position1[0].Profit < (1 - 0.01 * K4) * maxpft) {
                        exchanges[ir].SetDirection('closebuy')
                        exchanges[ir].Sell(-1, position1[0].Amount)
                        CalLsAmount(position1[0].Amount, ticker1.Last)
                        listpft[ir] = []
                        _G('listpft', listpft)
                        longAddCount[ir] = 0;
                        _G('longAddCount', longAddCount);
                        lSubP[ir] = 0;
                        _G('lSubP', lSubP);
                        list1[ir] = 0
                        _G('list1', list1)
                        Log(currency, '止盈信号达到2:', K4, ',平多止盈')
                        LogProfit(pft)
                    }
                } else {
                    //金叉给多单补仓
                    if (position1[0].Profit < 0) {
                        if (list1[ir] == 0 || list1[ir] == undefined) {
                            list1[ir] = position1[0].Price
                        }
                        if (ticker1.Last < (1 - GetE(ir, 0)) * list1[ir]) {
                            listpft[ir].push(position1[0].Profit)
                            _G('listpft', listpft)
                            let maxpft = Math.min(...listpft[ir])
                            if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft) {
                                exchanges[ir].SetDirection('buy')
                                let amount = acc[ir] * Math.pow(2, longAddCount[ir])
                                exchanges[ir].Buy(-1, amount)
                                list1[ir] = ticker1.Last;
                                _G('list1', list1)
                                longAddCount[ir] = longAddCount[ir] + 1;
                                _G('longAddCount', longAddCount);
                                Log(`2.${currency},补仓信号${HcK4},多单补仓,补仓价格:${list1[ir]},补仓次数:${longAddCount[ir]}`)
                                LogProfit(pft)
                            }
                        }
                    }
                }
                //空单补仓
                if (position1[1].Profit < 0) {
                    if (list2[ir] == 0 || list2[ir] == undefined) {
                        list2[ir] = position1[1].Price
                    }
                    if (ticker1.Last > (1 + 3 * GetE(ir, 1)) * list2[ir]) {
                        listpft2[ir].push(position1[1].Profit)
                        _G('listpft2', listpft2)
                        let maxpft2 = Math.min(...listpft2[ir])
                        if (position1[1].Profit > (1 - 0.01 * HcK4) * maxpft2) {
                            exchanges[ir].SetDirection('sell')
                            let amount = acc[ir] * Math.pow(2, shortAddCount[ir]);
                            exchanges[ir].Sell(-1, amount)
                            list2[ir] = ticker1.Last;
                            _G('list2', list2)
                            shortAddCount[ir] = shortAddCount[ir] + 1;
                            _G('shortAddCount', shortAddCount);
                            Log(`${currency},补仓信号${HcK4},空单补仓,补仓价格:${list2[ir]},补仓次数:${shortAddCount[ir]}`)
                            LogProfit(pft)
                        }
                    }
                } else {
                    if ((position1[1].Profit + sSubP[ir]) > 0.01 * C1 * ticker1.Last * position1[1].Amount * ctVal) {
                        exchanges[ir].SetDirection('closesell')
                        exchanges[ir].Buy(-1, position1[1].Amount)
                        CalLsAmount(position1[1].Amount, ticker1.Last)
                        list2[ir] = 0
                        _G('list2', list2)
                        shortAddCount[ir] = 0;
                        _G('shortAddCount', shortAddCount);
                        sSubP[ir] = 0
                        _G('sSubP', sSubP);
                        Log(currency, '空单盈利,平空止盈2')
                        LogProfit(pft)
                    }
                }
            }
        }
    }
    //大周期下降
    if (doShort && shortAddCount[ir] < maxSAC) {
        if (position1.length == 0) {
            //1分钟死叉开空
            if (short1) {
                exchanges[ir].SetDirection('sell')
                exchanges[ir].Sell(-1, acc[ir])
                list2[ir] = ticker1.Last;
                _G('list2', list2)
                Log(currency, '进场开空,首单进场价格1:', list2[ir])
                LogProfit(pft)
            }
        }
        if (position1.length > 0) {
            // 只持有1单
            if (position1.length == 1) {
                // 只持有空
                if (position1[0].Type == 1) {
                    if ((position1[0].Profit + sSubP[ir]) > 0.01 * Z * ticker1.Last * position1[0].Amount * ctVal) {
                        listpft2[ir].push(position1[0].Profit)
                        _G('listpft2', listpft2)
                        let maxpft2 = Math.max(...listpft2[ir])
                        if (position1[0].Profit < (1 - 0.01 * K4) * maxpft2) {
                            exchanges[ir].SetDirection('closesell')
                            exchanges[ir].Buy(-1, position1[0].Amount)
                            CalLsAmount(position1[0].Amount, ticker1.Last)
                            Log(currency, '止盈信号1:', K4, ',平空止盈')
                            LogProfit(pft)
                            listpft2[ir] = []
                            _G('listpft2', listpft2)
                            shortAddCount[ir] = 0;
                            _G('shortAddCount', shortAddCount);
                            sSubP[ir] = 0;
                            _G('sSubP', sSubP);
                            list2[ir] = 0
                            _G('list2', list2)
                        }
                    } else {
                        //死叉给空单补仓
                        if (position1[0].Profit < 0) {
                            if (list2[ir] == 0 || list2[ir] == undefined) {
                                list2[ir] = position1[0].Price
                            }
                            if (ticker1.Last > (1 + GetE(ir, 1)) * list2[ir]) {
                                listpft2[ir].push(position1[0].Profit)
                                _G('listpft2', listpft2)
                                let maxpft2 = Math.min(...listpft2[ir])
                                if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft2) {
                                    exchanges[ir].SetDirection('sell')
                                    let amount = acc[ir] * Math.pow(2, shortAddCount[ir]);
                                    exchanges[ir].Sell(-1, amount)
                                    list2[ir] = ticker1.Last;
                                    _G('list2', list2)
                                    shortAddCount[ir] = shortAddCount[ir] + 1;
                                    _G('shortAddCount', shortAddCount);
                                    Log(`1.${currency},补仓信号${HcK4},空单补仓,补仓价格:${list2[ir]},补仓次数:${shortAddCount[ir]}`)
                                    LogProfit(pft)
                                }
                            }
                        }
                    }
                }
                //只持有多单
                if (position1[0].Type == 0) {
                    //1分钟死叉开空
                    if (short1) {
                        exchanges[ir].SetDirection('sell')
                        exchanges[ir].Sell(-1, acc[ir])
                        list2[ir] = ticker1.Last;
                        _G('list2', list2)
                        Log(currency, '进场开空,首单进场价格2:', list2[ir])
                        LogProfit(pft)
                    }
                    //多单补仓
                    if (position1[0].Profit < 0) {
                        if (list1[ir] == 0 || list1[ir] == undefined) {
                            list1[ir] = position1[0].Price
                        }
                        if (ticker1.Last < (1 - 3 * GetE(ir, 0)) * list1[ir]) {
                            listpft[ir].push(position1[0].Profit)
                            _G('listpft', listpft)
                            let maxpft = Math.min(...listpft[ir])
                            if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft) {
                                exchanges[ir].SetDirection('buy')
                                let amount = acc[ir] * Math.pow(2, longAddCount[ir]);
                                exchanges[ir].Buy(-1, amount);
                                list1[ir] = ticker1.Last;
                                _G('list1', list1)
                                longAddCount[ir] = longAddCount[ir] + 1;
                                _G('longAddCount', longAddCount);
                                Log(`${currency},补仓信号${HcK4},多单补仓,补仓价格:${list1[ir]},补仓次数:${longAddCount[ir]}`)
                                LogProfit(pft)
                            }
                        }
                    } else {
                        if ((position1[0].Profit + lSubP[ir]) > 0.01 * C1 * ticker1.Last * position1[0].Amount * ctVal) {
                            exchanges[ir].SetDirection('closebuy')
                            exchanges[ir].Sell(-1, position1[0].Amount)
                            CalLsAmount(position1[0].Amount, ticker1.Last)
                            list1[ir] = 0
                            _G('list1', list1)
                            longAddCount[ir] = 0;
                            _G('longAddCount', longAddCount);
                            lSubP[ir] = 0;
                            _G('lSubP', lSubP);
                            Log(currency, `多单盈利,平多止盈1`)
                            LogProfit(pft)
                        }
                    }
                }
            }
            if (position1.length == 2) {
                //空单模块
                if ((position1[1].Profit + sSubP[ir]) > 0.01 * Z * ticker1.Last * position1[1].Amount * ctVal) {
                    listpft2[ir].push(position1[1].Profit)
                    _G('listpft2', listpft2)
                    let maxpft2 = Math.max(...listpft2[ir])
                    if (position1[1].Profit < (1 - 0.01 * K4) * maxpft2) {
                        exchanges[ir].SetDirection('closesell')
                        exchanges[ir].Buy(-1, position1[1].Amount)
                        CalLsAmount(position1[1].Amount, ticker1.Last)
                        Log(currency, '止盈信号:', K4, ',平空止盈')
                        LogProfit(pft)
                        listpft2[ir] = []
                        _G('listpft2', listpft2)
                        shortAddCount[ir] = 0;
                        _G('shortAddCount', shortAddCount);
                        sSubP[ir] = 0;
                        _G('sSubP', sSubP);
                        list2[ir] = 0
                        _G('list2', list2)
                    }
                } else {
                    //死叉给空单补仓
                    if (position1[1].Profit < 0) {
                        if (list2[ir] == 0 || list2[ir] == undefined) {
                            list2[ir] = position1[1].Price
                        }
                        if (ticker1.Last > (1 + GetE(ir, 1)) * list2[ir]) {
                            listpft2[ir].push(position1[1].Profit)
                            _G('listpft2', listpft2)
                            let maxpft2 = Math.min(...listpft2[ir])
                            if (position1[1].Profit > (1 - 0.01 * HcK4) * maxpft2) {
                                exchanges[ir].SetDirection('sell')
                                let amount = acc[ir] * Math.pow(2, shortAddCount[ir]);
                                exchanges[ir].Sell(-1, amount)
                                list2[ir] = ticker1.Last;
                                _G('list2', list2)
                                shortAddCount[ir] = shortAddCount[ir] + 1;
                                _G('shortAddCount', shortAddCount);
                                Log(`2.${currency},补仓信号${HcK4},空单补仓,补仓价格:${list2[ir]},补仓次数:${shortAddCount[ir]}`)
                                LogProfit(pft)
                            }
                        }
                    }
                }
                //多单补仓
                if (position1[0].Profit < 0) {
                    if (list1[ir] == 0 || list1[ir] == undefined) {
                        list1[ir] = position1[0].Price
                    }
                    if (ticker1.Last < (1 - 3 * GetE(ir, 0)) * list1[ir]) {
                        listpft[ir].push(position1[0].Profit)
                        _G('listpft', listpft)
                        let maxpft = Math.min(...listpft[ir])
                        if (position1[0].Profit > (1 - 0.01 * HcK4) * maxpft) {
                            exchanges[ir].SetDirection('buy')
                            let amount = acc[ir] * Math.pow(2, longAddCount[ir]);
                            exchanges[ir].Buy(-1, amount)
                            list1[ir] = ticker1.Last;
                            _G('list1', list1)
                            longAddCount[ir] = _N(parseFloat(longAddCount[ir]), 0) + 1;
                            _G('longAddCount', longAddCount);
                            Log(`${currency},补仓信号${HcK4},多单补仓,补仓价格:${list1[ir]},补仓次数:${longAddCount[ir]}`)
                            LogProfit(pft)
                        }
                    }
                } else {
                    if ((position1[0].Profit + lSubP[ir]) > 0.01 * C1 * ticker1.Last * position1[0].Amount * ctVal) {
                        exchanges[ir].SetDirection('closebuy')
                        exchanges[ir].Sell(-1, position1[0].Amount)
                        CalLsAmount(position1[0].Amount, ticker1.Last)
                        list1[ir] = 0
                        _G('list1', list1)
                        longAddCount[ir] = 0;
                        _G('longAddCount', longAddCount);
                        lSubP[ir] = 0;
                        _G('lSubP', lSubP);
                        Log(currency, `多单盈利,平多止盈2`)
                        LogProfit(pft)
                    }
                }
            }
        }
    }
}
//
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 (!IsHt) {
        K4 = 0;
        HcK4 = 0;
    }
    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)
    }
    for (let i = 0; i < exchanges.length; i++) {
        k = i
        let data = null;
        if (isOk) {
            data = accuracyOk()
        }
        if (isBinance) {
            data = accuracyBinance()
        }
        acc.push(n1)
        _G('acc', acc)
        if (data.amount <= 0) {
            stoplist.push(data)
        }
    }
}

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] = "";
        exchanges[i].SetContractType('swap')
        exchanges[i].SetMarginLevel(M)
    }
    mainBefor()
    while (true) {
        let loop_start = Date.now();
        try {
            table()
            for (let i = 0; i < exchanges.length; i++) {
                ir = i;
                trade()
                Sleep(1000)
            }
            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[1] == '0') {
                    let a = parseInt(arr[0])
                    currency = exchanges[a].GetCurrency()
                    let data = { coin: currency, amount: n1, msg: '手动停止' }
                    stoplist.push(data)
                    Log('当前停止的币对:', currency)
                }
                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[1] == '平仓') {
                    let ic = followCoins.indexOf(arr[0]);
                    if (ic > -1) {
                        let amount = Number(arr[3]);
                        exchanges[ic].SetContractType("swap")
                        if (arr[2] == 'LONG') {
                            exchanges[ic].SetDirection("closebuy")
                            let ticker1 = _C(exchanges[ic].GetTicker)
                            exchanges[ic].Sell(-1, amount)
                            CalLsAmount(amount, ticker1.Last)
                            longAddCount[ic] = 0;
                            _G('longAddCount', longAddCount)
                            lSubP[ir] = 0;
                            _G('lSubP', lSubP);
                            list1[ic] = 0
                            _G('list1', list1)
                        }
                        if (arr[2] == 'SHORT') {
                            exchanges[ic].SetDirection("closesell")
                            exchanges[ic].Buy(-1, amount)
                            let ticker1 = _C(exchanges[ic].GetTicker)
                            CalLsAmount(amount, ticker1.Last)
                            shortAddCount[ic] = 0;
                            _G('shortAddCount', shortAddCount)
                            sSubP[ir] = 0;
                            _G('sSubP', sSubP);
                            list2[ic] = 0
                            _G('list2', list2)
                        }
                        LogProfit(pft)
                    } else {
                        Log(arr[0], "该交易对未监听请去交易所平仓")
                    }
                }
                if (arr[0] == '清空日志') {
                    LogReset()
                    Log('日志已经清空')
                }
                if (arr[0] == '重置收益') {
                    _G(null)
                    LogReset()
                    stoplist = [];
                    LogProfitReset()
                    mainBefor()
                    Log('已重置收益')
                }
            }
        } catch (e) {
            Log('系统error', e);
            Sleep(S *1000)
        }
        trade_info.loop_delay = Date.now() - loop_start;
    }
}

策略出处

https://www.fmz.com/strategy/348791

更新时间

2022-03-05 16:55:17