가격 상승평균 -3년 33만배 수익

저자:시아오데123, 날짜: 2023-03-23 14:02:44
태그:


/*backtest
start: 2020-01-01 00:00:00
end: 2023-03-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","fee":[0.018,0.036]}]
*/

//地址https://www.fmz.com/strategy/405725

const QuotePrecision = 10;//下单价格精度
const BasePrecision = 10;//下单量精度

const long = 'long';//做多-期货
const closelong = 'closelong';//做多-平仓
const short = 'short';//做空-期货
const closeshort = 'closeshort';//做空-平仓
const isTest = true;//是不是币安测试API

const minPriceNum = 2;//保留几位小数点(买卖价格最低设置类似1660.17usdt)
const marginLevel = 1;//杆杠大小

let lastKLineTime = 0;//最后一个结束的k线时间戳(比如现在10:30,那就是9点时间戳)

const priceAdd = 0.01;//交易时改变1%设置价格
let lastOrderTime = 0;//最后一次下订单时间戳-秒

const serviceCharge = 0.0004;//手续费0.04%
let signalData = {};//订单数据-用于订单交易成功时使用
let maintMarginPro = 0.005;//维持保证金比率0.50%
let maintMarginNum = 0;//维持保证金速算额 (USDT)

const cfgName1 = "k线图表";
var registerInfo = {};
var chart = null;
var arrCfg = [];
const maxBufferLen = 10;//

let beginMoney = 0;//启动时的总资产
let exchangeNum = 0;//本次交易次数(开仓+平仓算2次)
const lastNumPro_MarketPrice = 0.02;//因为用市价不好把握价格,空间留大点
const buyMinPro = 0.02;//剩余钱不到总钱2%,不操作,避免小额交易

let period = 0;//K线周期-秒

const atrNum = 6;
const stopKLineNum = 0;//出现止损,休息()个K线
const pp = 12;//数值越大,格子差距越小
const StopGrid = 16;//止损网格价格倍数

let lastStopTime = 0;

const checkTime = 1500;//每隔多少秒检测一下代码-1小时
let lastCheckTime = 0;//上次检测时间戳-秒

let currency;
let nowMarkPrice = 0;
let nowPosition;
let nowAccount;

function main() {
    testLog("调用main");
    let extension = {
        layout: 'single',//single:图表不会叠加(不会以分页标签方式显示),会单独显示(平铺显示),默认为分组 'group'
        col: 12,//设置图表的页面宽度,1-12
        height: '700px'//图表的高度
    }
    Sleep(1000);

    while (true) {
        setNowData();
        let bars = _C(exchange.GetRecords);//只能获得最近300个周期的数据?
        PlotMultRecords(bars, cfgName1, "k线", extension);//画k线图
        drawLine(bars);//画sma线,策略

        Sleep(1000 * 10);//每秒运行下代码
    }

}

/** 活动最新数据 */
function setNowData() {
    setMarkPrice();
    setNowPosition();
    setNowAccount();
}

// 初始化函数
function init() {
    _CDelay(1000 * 10);// 调整_C()函数重试时间间隔为n秒

    testLog("初始化!");
    // 设置精度(小数点位数,回测不支持)
    exchange.SetPrecision(QuotePrecision, BasePrecision);

    exchange.SetContractType("swap");//永续合约
    if (isTest) {
        exchange.SetBase("https://testnet.binancefuture.com");// 切换为测试的地址
    }
    let arr = exchange.GetCurrency().split('_');//ETH_USDT=>ETH_USDT
    currency = arr[0] + arr[1];
    Log('交易对:' + currency);

    setNowData();
    log_ticker("初始化");
    log_account("初始化");

    beginMoney = getAllMoney();

    chart = Chart(arrCfg);

    period = _C(exchange.GetPeriod);//K线周期
    let periodTxt = getTimeTxt(period);
    testLog("K线周期:" + periodTxt);
}


/** 画sma均线 */
function drawLine(bars) {
    // 使用现货交易所对象测试,获取K线数据。如果使用期货交易所对象测试,需要先设置合约
    if (!bars) {
        return;
    }

    if (lastKLineTime == 0) {//第一次启动,从头开始
        var begin = atrNum - 1;
    } else {
        begin = bars.length - 2;//理论上只看最新一个数据就行,但为了防止误差,看2个
    }
    if (begin < 0) {
        return;
    }

    let atr = talib.ATR(bars, atrNum);//计算平均价格振幅

    for (let i = begin; i < bars.length; i++) {
        let bar = bars[i];
        if (bar.Time <= lastKLineTime) {//已经计算、画图过的
            continue;
        }

        let avg_pra = atr[i] / bar.Close

        let hl2 = (bar.High + bar.Low) / 2;
        //计算网格
        let grid = hl2 * avg_pra / pp;
        let p1 = hl2 + grid * StopGrid;
        let p2 = hl2 + grid * 2;
        let p0 = hl2;
        let p3 = hl2 - grid * 2;
        let p4 = hl2 - grid * StopGrid;

        //------------画k线图等
        if (i < bars.length - 1) {
            lastKLineTime = bar.Time;
            //最后一条数据不完整,结束画
            PlotMultLine(cfgName1, "p1", p1, bar.Time, '#FF9800');
            PlotMultLine(cfgName1, "p2", p2, bar.Time, '#265ec5');
            PlotMultLine(cfgName1, "p0", p0, bar.Time, '#7c7c7c');
            PlotMultLine(cfgName1, "p3", p3, bar.Time, '#265ec5');
            PlotMultLine(cfgName1, "p4", p4, bar.Time, '#FF9800');
            continue;
        }

        //------------以最后一条数据获得的sma值进行交易判断(for循环只进最后一次)
        // ======================== 策略操作 - 开始 ============================
        if (hasOrder()) {//有未完成的订单
            return;
        }

        let nowTime = getNowTime();
        if ((lastCheckTime + checkTime) <= nowTime) {
            lastCheckTime = nowTime;//每隔多少秒检测一下代码
        } else {
            return;
        }

        if ((lastStopTime + stopKLineNum * period * 1000) > bar.Time) {
            return;
        }

        //只做多
        if (bar.Close < p4) {
            let funTxt = 'Fun_止损';
            let isSuccess = ExchangeFun(closelong, funTxt);
            if (isSuccess) {
                lastStopTime = bar.Time;
            }
        } else if (bar.Close < p3) {
            let funTxt = 'Fun_做多';
            ExchangeFun(long, funTxt);
        } else if (bar.Close > p2) {
            let funTxt = 'Fun_止盈';
            ExchangeFun(closelong, funTxt);
        }
    }
}


/** 有没有未完成的订单 */
function hasOrder() {
    let orders = _C(exchange.GetOrders);//获取所有未完成的订单
    if (!orders) {
        return true;
    }
    if (orders.length == 0 && signalData && signalData.FunTxt) {
        let order = _C(exchange.GetOrder, signalData.Id);
        if (order) {
            exchangeNum++;
            let nowTime = getNowTime();

            let timeTxtxt = getTimeTxt(nowTime - lastOrderTime);
            let txt = signalData.FunTxt + ',报价:' + order.Price + ',均价:' + order.AvgPrice
                + ',量:' + order.Amount + '%' + ",次数:" + exchangeNum
                + ",Action:" + signalData.Action + ",耗时:" + timeTxtxt;
            Log("end订单成功----" + txt);
            log_account("end----");
            PlotMultFlag(cfgName1, "flag1", new Date().getTime(), txt, signalData.FunTxt);
            signalData = {};
        }
    }
    if (orders.length > 0) {
        return true;
    } else {
        return false;
    }
}



//做多做空等实际功能
function ExchangeFun(action, funTxt, percent = 1) {
    let amount;
    let tradeInfo;
    let markPrice = getMarkPrice();//标记价格
    if (action == long || action == closeshort) {//买
        var price = markPrice * (1 + priceAdd);
    } else if (action == short || action == closelong) {//卖
        price = markPrice * (1 - priceAdd);
    }
    price = _floor(markPrice, minPriceNum);

    let min = getMinNum();//eth最小操作0.001个
    if (action == long) {//做多
        if (!canBuy()) {//避免小额交易
            return false;
        }
        amount = getBuyNum(price, 0);//购买多少个eth
        if (amount >= min) {
            beginTrans();
            exchange.SetMarginLevel(marginLevel);//设置杆杠大小
            exchange.SetDirection("buy");
            tradeInfo = exchange.Buy(-1, amount);//市价
        }
    } else if (action == short) {//做空
        if (!canBuy()) {//避免小额交易
            return false;
        }
        amount = getBuyNum(price, 1);//做空卖多少个eth
        if (amount >= min) {
            beginTrans();
            exchange.SetMarginLevel(marginLevel);//设置杆杠大小
            exchange.SetDirection("sell");
            tradeInfo = exchange.Sell(-1, amount);
        }
    } else if (action == closelong) {//平仓-做多
        amount = getCoinNum(0) * percent;//卖掉多少个期货eth
        if (amount >= min) {
            beginTrans();
            exchange.SetDirection("closebuy");
            tradeInfo = exchange.Sell(-1, amount);
        }
    } else if (action == closeshort) {//平仓-做空
        amount = getCoinNum(1) * percent;
        if (amount >= min) {
            beginTrans();
            exchange.SetDirection("closesell");
            tradeInfo = exchange.Buy(-1, amount);
        }
    }

    if (tradeInfo) {
        signalData = { 'Action': action, 'Id': tradeInfo, 'FunTxt': funTxt };
        log_ticker("end----,订单Action:" + action + ",price:" + price);
        return true;
    }
    return false;
}


/** 开始交易 */
function beginTrans() {
    lastOrderTime = getNowTime();
    log_account("bengin----");
}

function log_account(txt) {
    let acc = GetAcc();
    let markPrice = getMarkPrice();

    testLog(txt + ",可用余额:" + acc.Balance + ",标记价格:" + markPrice + ",账户:" + JSON.stringify(acc));

    let position = getNowPosition();
    if (position.length > 0) {
        let data = position[0];//默认持仓就1个
        let typeTxt = '';
        if (data.Type == 0) {
            typeTxt = '做多';
        } else if (data.Type == 1) {
            typeTxt = '做空';
        }
        let leverageTxt = '';
        if (data.Info) {//回测时没有?
            leverageTxt = ",杠杆:" + data.Info.leverage;
        }
        testLog("持仓信息 eth:" + data.Amount + ",Price:" + data.Price
            // , ",利润:", data.Profit
            + ",Type:" + typeTxt + leverageTxt + ",详情:" + JSON.stringify(data));
    }
}

/** 获得账号信息 */
function GetAcc() {
    return nowAccount;
}
/** 设置账号信息 */
function setNowAccount() {
    let acc = _C(exchange.GetAccount);
    if (acc.Info) {
        acc.Info.assets = null;
        acc.Info.positions = null;
    }
    nowAccount = acc;
}

function log_ticker(txt) {
    testLog(txt);
}



/** 预计可以购买多少个eth 0做多,1做空 */
function getBuyNum(price, type) {
    let acc = GetAcc();
    let balance = acc.Balance;//有多少usdt
    if (balance < 100000) {
        maintMarginPro = 0.005;//维持保证金比率
        maintMarginNum = 0;//维持保证金速算额 (USDT)
    } else if (balance < 250000) {
        maintMarginPro = 0.0065;
        maintMarginNum = 150;
    } else if (balance < 2000000) {
        maintMarginPro = 0.01;
        maintMarginNum = 1025;
    } else if (balance < 10000000) {
        maintMarginPro = 0.02;
        maintMarginNum = 21025;
    } else {
        //暂不处理
    }
    balance -= maintMarginNum;

    let markPrice = getMarkPrice();//标记价格
    let lossType;//开仓亏损:订单方向
    //尽量多买,避免小额多次交易
    if (type == 0) {//做多
        lossType = 1;
    } else if (type == 1) {//做空
        lossType = -1;
    }
    if (type == 0) {//做多
        var usePrice = price;
    } else if (type == 1) {//做空
        usePrice = Math.max(price, markPrice);
    }

    // 开仓亏损=合约数量* 绝对值{min[0, 订单方向* (标记价格- 订单价格)]}
    let losePro = Math.abs(Math.min(0, lossType * (markPrice - price)));

    // 订单价格: 限价单:我挂的价格 市价单:卖一
    // 买单(做多),最大可用资金可用/{订单价格/杠杆倍数+绝对值(min0,标记价格-订单价格)}
    // 卖单(做空),最大可用资金可用/{max(标记价,订单价格)/杠杆倍数+绝对值(min0,订单价格-标记价)}
    let amount = balance / (usePrice / marginLevel + losePro);//计算开仓亏损

    //扣的钱按全部购买算
    amount /= (1 + serviceCharge);//计算手续费
    amount /= (1 + maintMarginPro);//计算维持保证金
    amount *= (1 - lastNumPro_MarketPrice);//保留点
    amount = _floor(amount);

    return amount;
}

/** 期货仓库里有多少个eth,type:0做多的仓,1做空的仓 */
function getCoinNum(type) {
    var position = getNowPosition();
    if (position.length > 0) {
        let data = position[0];//默认持仓就1个
        // let num = _floor(data.Amount);
        let num = data.Amount;
        if (data.Type == type) {
            return num;
        }
    }
    return 0;
}


/** 剩余钱不到总钱2%,不操作,避免小额交易 */
function canBuy() {
    var position = getNowPosition();
    if (position.length > 0) {
        let acc = GetAcc();
        let allMoney = getAllMoney();
        if (acc.Balance / allMoney < (buyMinPro + maintMarginPro)) {
            return false;
        }
    }
    return true;
}

/** 估计当前总资产 */
function getAllMoney() {
    let acc = GetAcc();
    let allMoney = acc.Balance;//可用余额
    allMoney += acc.FrozenBalance;//冻结余额
    var position = getNowPosition();
    if (position.length > 0) {
        let data = position[0];//默认持仓就1个
        let markPrice = getMarkPrice();

        if (data.Type == 0) {//做多
            allMoney += data.Amount * markPrice;
        } else if (data.Type == 1) {//做空
            allMoney += data.Amount * data.Price;//做空前的本金
            allMoney += (data.Price - markPrice) * data.Amount;//做空的收益
        }
    }
    return allMoney;
}


/** 获得标记价格 */
function getMarkPrice() {
    return nowMarkPrice;
}
/** 获得标记价格 */
function setMarkPrice() {
    //模拟回测
    let ticker = _C(exchange.GetTicker);//获得行情数据最多10分钟
    nowMarkPrice = ticker.Last;//最后一次交易价格
}

/** 最少买0.001个eth */
function getMinNum() {
    return 0.001;
}

/** 向下取整,保留3位小数点(开仓手数:最低设置0.001个ETH) */
function _floor(num, min = 3) {
    num = Math.floor(num * Math.pow(10, min)) / Math.pow(10, min);
    num = parseFloat(num);//string转Float
    return num;
}

/** 返回当前时间戳-秒 */
function getNowTime() {
    return Unix();
}

/** 画k线图 */
function PlotMultRecords(bars, cfgName, seriesName, extension) {
    var index = -1;
    var eleIndex = -1;

    do {
        var cfgInfo = registerInfo[cfgName];
        if (typeof (cfgInfo) == "undefined") {
            var cfg = {
                name: cfgName,
                __isStock: true,
                title: {
                    text: cfgName
                },
                tooltip: {
                    xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
                },
                legend: {
                    enabled: true,
                },
                plotOptions: {
                    candlestick: {
                        color: '#d75442',
                        upColor: '#6ba583'
                    }
                },
                rangeSelector: {
                    buttons: [{
                        type: 'hour',
                        count: 1,
                        text: '1h'
                    }, {
                        type: 'hour',
                        count: 3,
                        text: '3h'
                    }, {
                        type: 'hour',
                        count: 8,
                        text: '8h'
                    }, {
                        type: 'all',
                        text: 'All'
                    }],
                    selected: 2,
                    inputEnabled: true
                },
                series: [{
                    type: 'candlestick',
                    name: seriesName,
                    id: seriesName,
                    data: []
                }],
            }

            if (typeof (extension) != "undefined") {
                cfg.extension = extension;
            }

            registerInfo[cfgName] = {
                "cfgIdx": arrCfg.length,
                "seriesIdxs": [{
                    seriesName: seriesName,
                    index: arrCfg.length,
                    type: "candlestick",
                    preBarTime: 0
                }],
            };
            arrCfg.push(cfg);
            updateSeriesIdx();
        }

        chart.update(arrCfg);//刷新所有图表

        _.each(registerInfo[cfgName].seriesIdxs, function (ele, i) {
            if (ele.seriesName == seriesName && ele.type == "candlestick") {
                index = ele.index;
                eleIndex = i;
            }
        });
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'candlestick',
                name: seriesName,
                id: seriesName,
                data: []
            });
            registerInfo[cfgName].seriesIdxs.push({
                seriesName: seriesName,
                index: arrCfg.length,
                type: "candlestick",
                preBarTime: 0
            });
            updateSeriesIdx();
        }
    } while (index == -1)

    for (var i = 0; i < bars.length; i++) {
        let bar = bars[i];
        let data = [bar.Time, bar.Open, bar.High, bar.Low, bar.Close];//写入图表的一个周期数据
        let preBarTime = registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime;
        if (bar.Time == preBarTime) {
            chart.add(index, data, -1);//更新当前周期
        } else if (bar.Time > preBarTime) {
            registerInfo[cfgName].seriesIdxs[eleIndex].preBarTime = bar.Time
            chart.add(index, data);//添加历史(不变了)
        }
    }

}

function updateSeriesIdx() {
    var index = 0
    var map = {}
    _.each(arrCfg, function (cfg) {
        _.each(cfg.series, function (series) {
            var key = cfg.name + "|" + series.name
            map[key] = index
            index++
        })
    })

    for (var cfgName in registerInfo) {
        _.each(arrCfg, function (cfg, cfgIdx) {
            if (cfg.name == cfgName) {
                registerInfo[cfgName].cfgIdx = cfgIdx
            }
        })

        for (var i in registerInfo[cfgName].seriesIdxs) {
            var seriesName = registerInfo[cfgName].seriesIdxs[i].seriesName
            var key = cfgName + "|" + seriesName
            if (typeof (map[key]) != "undefined") {
                registerInfo[cfgName].seriesIdxs[i].index = map[key]
            }

            if (registerInfo[cfgName].seriesIdxs[i].type == "candlestick") {
                registerInfo[cfgName].seriesIdxs[i].preBarTime = 0
            } else if (registerInfo[cfgName].seriesIdxs[i].type == "line") {
                registerInfo[cfgName].seriesIdxs[i].preDotTime = 0
            } else if (registerInfo[cfgName].seriesIdxs[i].type == "flag") {
                registerInfo[cfgName].seriesIdxs[i].preFlagTime = 0
            }
        }
    }

    if (!chart) {
        chart = Chart(arrCfg)
    }
    chart.update(arrCfg)
    chart.reset()

    _G("registerInfo", registerInfo)
    _G("arrCfg", arrCfg)

    for (var cfgName in registerInfo) {
        for (var i in registerInfo[cfgName].seriesIdxs) {
            var buffer = registerInfo[cfgName].seriesIdxs[i].buffer
            var index = registerInfo[cfgName].seriesIdxs[i].index
            if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "line" && registerInfo[cfgName].seriesIdxs[i].preDotTime == 0) {
                _.each(buffer, function (obj) {
                    chart.add(index, [obj.ts, obj.dot])
                    registerInfo[cfgName].seriesIdxs[i].preDotTime = obj.ts
                })
            } else if (buffer && buffer.length != 0 && registerInfo[cfgName].seriesIdxs[i].type == "flag" && registerInfo[cfgName].seriesIdxs[i].preFlagTime == 0) {
                _.each(buffer, function (obj) {
                    chart.add(index, obj.data)
                    registerInfo[cfgName].seriesIdxs[i].preFlagTime = obj.ts
                })
            }
        }
    }
}


function checkBufferLen(buffer, maxLen) {
    while (buffer.length > maxLen) {
        buffer.shift()
    }
}

/** 画线条 */
function PlotMultLine(cfgName, seriesName, dot, ts, color, extension) {
    var index = -1;
    var eleIndex = -1;

    do {
        var cfgInfo = registerInfo[cfgName]
        if (typeof (cfgInfo) == "undefined") {
            var cfg = {
                name: cfgName,
                __isStock: true,
                title: {
                    text: cfgName
                },
                xAxis: {
                    type: 'datetime'
                },
                series: [{
                    type: 'line',
                    name: seriesName,
                    id: seriesName,
                    color: color,
                    data: [],
                }]
            };

            if (extension) {
                cfg.extension = extension;
            }

            registerInfo[cfgName] = {
                "cfgIdx": arrCfg.length,
                "seriesIdxs": [{
                    seriesName: seriesName,
                    index: arrCfg.length,
                    type: "line",
                    color: color,
                    buffer: [],
                    preDotTime: 0
                }],
            };
            arrCfg.push(cfg);
            updateSeriesIdx();
        }

        chart.update(arrCfg);

        _.each(registerInfo[cfgName].seriesIdxs, function (ele, i) {
            if (ele.seriesName == seriesName && ele.type == "line") {
                index = ele.index;
                eleIndex = i;
            }
        })
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'line',
                name: seriesName,
                id: seriesName,
                color: color,
                data: [],
            });
            registerInfo[cfgName].seriesIdxs.push({
                seriesName: seriesName,
                index: arrCfg.length,
                type: "line",
                color: color,
                buffer: [],
                preDotTime: 0
            });
            updateSeriesIdx();
        }
    } while (index == -1)

    if (typeof (ts) == "undefined") {
        ts = new Date().getTime();
    }

    var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer;
    if (registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime != ts) {
        registerInfo[cfgName].seriesIdxs[eleIndex].preDotTime = ts;
        chart.add(index, [ts, dot]);
        buffer.push({
            ts: ts,
            dot: dot
        });
        checkBufferLen(buffer, maxBufferLen);
    } else {
        chart.add(index, [ts, dot], -1);
        buffer[buffer.length - 1].dot = dot;
    }

}

/** 画flag */
function PlotMultFlag(cfgName, seriesName, ts, text, title, shape, color, onSeriesName) {
    if (typeof (cfgName) == "undefined" || typeof (registerInfo[cfgName]) == "undefined") {
        throw "need cfgName!";
    }

    var index = -1;
    var eleIndex = -1;

    do {
        chart.update(arrCfg);

        _.each(registerInfo[cfgName].seriesIdxs, function (ele, i) {
            if (ele.seriesName == seriesName && ele.type == "flag") {
                index = ele.index;
                eleIndex = i;
            }
        });
        if (index == -1) {
            arrCfg[registerInfo[cfgName].cfgIdx].series.push({
                type: 'flags',
                name: seriesName,
                onSeries: onSeriesName || arrCfg[registerInfo[cfgName].cfgIdx].series[0].id,
                data: []
            });
            registerInfo[cfgName].seriesIdxs.push({
                seriesName: seriesName,
                index: arrCfg.length,
                type: "flag",
                buffer: [],
                preFlagTime: 0
            });
            updateSeriesIdx();
        }
    } while (index == -1)

    if (typeof (ts) == "undefined") {
        ts = new Date().getTime();
    }

    var buffer = registerInfo[cfgName].seriesIdxs[eleIndex].buffer;
    var obj = {
        x: ts,
        color: color,
        shape: shape,
        title: title,
        text: text
    };
    if (registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime != ts) {
        registerInfo[cfgName].seriesIdxs[eleIndex].preFlagTime = ts;
        chart.add(index, obj);
        buffer.push({
            ts: ts,
            data: obj
        });
        checkBufferLen(buffer, maxBufferLen);
    } else {
        chart.add(index, obj, -1);
        buffer[buffer.length - 1].data = obj;
    }

}



function testLog(txt) {
    Log(txt);
}

function getNowPosition() {
    return nowPosition;
}
function setNowPosition() {
    nowPosition = _C(exchange.GetPosition);
}

/** 把时间秒改成天\小时等 */
function getTimeTxt(time) {
    if (time < 60) {
        var timeTxt = time;
        var key = '秒';
    } else if (time < 3600) {
        timeTxt = time / 60;
        key = '分钟';
    } else if (time < 3600 * 24) {
        timeTxt = time / 3600;
        key = '小时';
    } else {
        timeTxt = time / 3600 / 24;
        key = '天';
    }
    timeTxt = Math.floor(timeTxt * 10) / 10 + key;//保留1位小数点
    return timeTxt;
}

더 많은

sxj3388좋은 리뷰, 진짜 손실?

쿠아일레2020복제 K선 정확도가 충분하지 않아서 좋은 결과를 얻었습니다. 실제로 5분 동안 K선을 사용해서 D1의 k선 정확도보다 훨씬 높은 정확도를 얻었습니다.

제가 처음 왔을 때이 재검토를 사용한 후, 비교적 안정적인 손실이 시작되었습니다. /* 백테스트 2022-04-19 00:00:00 end: 2023-04-21 00:00:00 기간: 1h BasePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"LTC_USDT","balance":200, "fee": [0.02,0.04], "balance":1000}] */

제가 처음 왔을 때많은 변수들의 초기화는 약간 이상하게 느껴집니다. 예를 들어 아래와 같이. if (type == 0) {// 더하기 var usePrice = price, var usePrice = price, var usePrice = price, var usePrice = price, var usePrice = price, } else if (type == 1) {// 공백 usePrice = Math.max ((price, markPrice)); ♪ ♪

시아오데1233년 동안 직접 뛰면 실패할 겁니다. 시장이 충분하지 않은 것 같습니다. 만약 한 해가 지나면 20~21년, 49배나 더 많이 21~22년, 수익은 232배가 됩니다. 22-2023-03-24 연봉 89배 이 모든 것이 백만 배나 더 무서운 것입니다.

시아오데123이스트 테스트를 추가하면 비엔안 테스트 웹 리얼 디스크에 갈 수 있습니다. (자신 한 번 실행하면 버그가 정상입니다.)

시아오데123이건 리테스트 버전이고, 실제 비트코인 테스트 네트워크와 공식적인 조정이 아니었기 때문에,

시아오데123fmz 재검토 연령 10W 배의 수익, 너무 무서운, 의심하는 fmz 재검토 메커니즘은 우연히 내 코드를 만났습니다, 버그가 나왔습니다, 정말 실행하지 마세요!

sxj3388때로는 규칙에 따라 안되는 것처럼 보이지만, 단자가 없는 경우 c>p2가 더 많은 것을하고, c

시아오데123Fun_가 많이 하는 것은 지점을 열고, 지점을 멈추는 것은 평형입니다.

sxj3388이럴 때, 이럴 때, 이럴 때, 이럴 때, 이럴 때.

시아오데123하지만 실제로는 달리기에는 별다른 효과가 없습니다.

제가 처음 왔을 때자바로 번역하고, 로컬로 재검토할 준비가 되어있어서