avatar of 我想量化躺着挣钱 我想量化躺着挣钱
关注 私信
9
关注
16
关注者

永续无限合约网格多空双向持仓下单精度和执行交易混乱的问题,弄了半个月了实在不会了,有偿求解决办法。各位大佬

创建于: 2025-12-08 11:00:34, 更新于: 2025-12-08 11:27:50
comments   11
hits   511

lines.push(‘字段 | 值’); lines.push(‘—- | —-’); for (var i = 0; i < rows.length; i++) { lines.push(rows[i][0] + ‘ | ’ + rows[i][1]); } lines.push(“); // 空行分隔 };

    addTextSection('📊 基础', [
        ['初始化时间', initTimeStr],
        ['运行时长', runTime],
        ['当前价格', ticker ? ticker.Last.toFixed(2) : '-'],
        ['做多爆仓价', liquidationPrices.long ? liquidationPrices.long.toFixed(2) : '-'],
        ['做空爆仓价', liquidationPrices.short ? liquidationPrices.short.toFixed(2) : '-'],
        ['参数迁移', isMigrating ? '迁移中' : '正常'],
        isMigrating && oldConfig ? ['旧多头间距', oldConfig.longGridSpacing + '%'] : null,
        isMigrating && oldConfig ? ['旧空头间距', oldConfig.shortGridSpacing + '%'] : null
    ].filter(Boolean));

    addTextSection('💰 账户', [
        ['初始余额', INITIAL_BALANCE.toFixed(2)],
        ['钱包余额', (account.Balance || 0).toFixed(2)],
        ['保证金余额', (account.Margin || 0).toFixed(2)],
        ['可用保证金', (account.Available || 0).toFixed(2)],
        ['已用杠杆', leverage + 'x']
    ]);

    addTextSection('📈 收益', [
        ['总收益', profitInfo.totalProfit.toFixed(2)],
        ['总收益率', (profitInfo.totalProfitRate * 100).toFixed(2) + '%'],
        ['当日收益', profitInfo.dailyProfit.toFixed(2)],
        ['平均日化', (profitInfo.avgDailyReturn * 100).toFixed(2) + '%'],
        ['预估月化', (profitInfo.estimatedMonthlyReturn * 100).toFixed(2) + '%'],
        ['预估年化', (profitInfo.estimatedYearlyReturn * 100).toFixed(2) + '%']
    ]);

    addTextSection('🔲 网格', [
        ['多头持仓数', MANY_ORDER_LIST.length],
        ['下一个买入价', MANY_NEXT_BUY_PRICE > 0 ? MANY_NEXT_BUY_PRICE.toFixed(2) : '-'],
        ['多头间距', config.longGridSpacing + '%'],
        ['空头持仓数', SHORT_ORDER_LIST.length],
        ['下一个卖出价', SHORT_NEXT_BUY_PRICE > 0 ? SHORT_NEXT_BUY_PRICE.toFixed(2) : '-'],
        ['空头间距', config.shortGridSpacing + '%'],
        ['单网格金额', config.orderAmount.toFixed(2)]
    ]);

    var posRows = [];
    if (positionInfo.length > 0) {
        for (var i = 0; i < positionInfo.length; i++) {
            var pos = positionInfo[i];
            posRows.push(['持仓' + (i + 1) + ' (' + (pos.direction === 'long' ? '多' : '空') + ')', '']);
            posRows.push(['数量', pos.quantity.toFixed(2)]);
            posRows.push(['持仓价', pos.positionPrice.toFixed(2)]);
            posRows.push(['当前价', pos.currentPrice.toFixed(2)]);
            posRows.push(['持仓价值', pos.positionValue.toFixed(2)]);
            posRows.push(['未实现盈亏', pos.unrealizedPnl.toFixed(2)]);
            if (i < positionInfo.length - 1) {
                posRows.push(['---', '---']);
            }
        }
    } else {
        posRows.push(['暂无持仓', '']);
    }
    addTextSection('📦 持仓', posRows);

    addTextSection('⚙️ 系统', [
        ['循环延时', cycleDelay.toFixed(0) + 'ms'],
        ['状态保存', LAST_SAVE_TIME > 0 ? new Date(LAST_SAVE_TIME * 1000).toLocaleTimeString() : '-'],
        ['收益记录数', PROFIT_HISTORY.length]
    ]);

    LogStatus(lines.join('\n'));

    // 记录收益曲线(使用LogProfit,FMZ平台会自动显示收益曲线)
    var currentProfit = profitInfo.totalProfit;
    LogProfit(currentProfit);

    // 保存收益历史
    PROFIT_HISTORY.push({
        time: Unix(),
        profit: currentProfit
    });

    // 只保留最近1000条记录
    if (PROFIT_HISTORY.length > 1000) {
        PROFIT_HISTORY.shift();
    }

    // 定期保存状态(每5分钟)
    if (Unix() - LAST_SAVE_TIME >= SAVE_INTERVAL) {
        safeSaveState();
    }

} catch (e) {
    Log("更新状态信息失败:", e);
}

}

// ==================== 主循环 ==================== function onTick() { var ticker = exchange.GetTicker(); if (!ticker) return;

// 定期持仓对账,防止本地列表与实际仓位不一致(尤其防止空头被抵消后仍显示)
if (Unix() - LAST_RECONCILE_TIME >= RECONCILE_INTERVAL) {
    reconcilePositions();
    LAST_RECONCILE_TIME = Unix();
}

// 检查价格边界
if (!checkPriceBounds()) {
    Log("价格超出网格边界,暂停交易");
    return;
}

// 检查参数迁移是否完成
checkMigrationComplete();

// 如果多头持仓为空,首次买入
if (MANY_ORDER_LIST.length === 0) {
    firstManyBuy();
} else {
    // 多头加仓和平仓
    manyBuy();
    manySell();
}

// 如果空头持仓为空,首次卖出
if (SHORT_ORDER_LIST.length === 0) {
    firstShortBuy();
} else {
    // 空头加仓和平仓
    shortBuy();
    shortSell();
}

// 更新状态信息
updateStatusInfo();

}

// ==================== 主函数 ==================== function main() { // 设置交易所类型(OKX) exchange.SetContractType(“swap”); // 或 “spot” 根据需求 // 尝试设置双向持仓(对冲)模式,若不支持则忽略,避免 TypeError if (typeof exchange.SetPositionMode === ‘function’) { try { exchange.SetPositionMode(1); Log(“已尝试设置对冲模式 (SetPositionMode=1)”); } catch (e) { Log(“设置对冲模式失败,继续运行(可能交易所/托管者不支持):”, e); } } else { Log(“SetPositionMode 不可用,跳过对冲模式设置”); }

// ✅ 从FMZ界面获取配置参数(禁止硬编码)
// 注意:FMZ平台中,界面设置的参数名称会自动成为JavaScript全局变量
config = getConfigParams();

// 尝试获取交易规则(tickSz/lotSz),以便自动设置步长与精度
loadInstrumentSpec();
// 应用用户手动覆盖(如有)
applyForceLot();
// 最终将精度写回 precision 供后续使用
precision = getPrecision();

// 验证配置
if (!config.symbol) {
    throw new Error("请设置币种选择(界面参数名:symbol)");
}
if (!config.upperPrice || !config.lowerPrice) {
    throw new Error("请设置网格上边界价格和下边界价格(界面参数名:upperPrice, lowerPrice)");
}
if (config.upperPrice <= config.lowerPrice) {
    throw new Error("上边界价格必须大于下边界价格");
}
if (!config.orderAmount || config.orderAmount <= 0) {
    throw new Error("单个网格下单金额必须大于0(界面参数名:orderAmount)");
}
if (!config.longGridSpacing || config.longGridSpacing <= 0) {
    throw new Error("多头网格间距必须大于0(界面参数名:longGridSpacing)");
}
if (!config.shortGridSpacing || config.shortGridSpacing <= 0) {
    throw new Error("空头网格间距必须大于0(界面参数名:shortGridSpacing)");
}

// 尝试恢复状态
Log("========== 策略启动 ==========");
var stateRestored = loadState();
if (stateRestored) {
    Log("✅ 状态恢复成功");
} else {
    Log("ℹ️ 首次运行,使用初始状态");
}

// 检查配置变化(启动参数迁移检测)
checkConfigChange(config);

// 获取精度
precision = getPrecision();

Log("========== 策略配置 ==========");
Log("币种选择:", config.symbol);
Log("多头网格间距:", config.longGridSpacing, "%");
Log("空头网格间距:", config.shortGridSpacing, "%");
Log("单个网格下单金额:", config.orderAmount);
Log("网格上边界价格:", config.upperPrice);
Log("网格下边界价格:", config.lowerPrice);
Log("价格精度:", precision.pricePrecision);
Log("数量精度:", precision.amountPrecision);
Log("合约最小单位: 0.01 (ETH永续合约)");
Log("============================");

// 初始化价格(如果状态未恢复)
if (!stateRestored) {
    var ticker = exchange.GetTicker();
    if (!ticker || !ticker.Last || ticker.Last <= 0) {
        throw new Error("无法获取初始价格");
    }

    var initPrice = ticker.Last;

    // 初始化多头和空头的下一个买入/卖出价格
    MANY_NEXT_BUY_PRICE = formatPrice(
        initPrice * (1 - config.longGridSpacing / 100),
        precision.pricePrecision
    );
    SHORT_NEXT_BUY_PRICE = formatPrice(
        initPrice * (1 + config.shortGridSpacing / 100),
        precision.pricePrecision
    );

    Log("初始价格:", initPrice);
    Log("多头下一个买入价格:", MANY_NEXT_BUY_PRICE);
    Log("空头下一个卖出价格:", SHORT_NEXT_BUY_PRICE);

    // 初始化状态信息
    INIT_TIME = Unix();
    var account = exchange.GetAccount();
    if (account) {
        INITIAL_BALANCE = account.Balance || 0;
        Log("初始余额:", INITIAL_BALANCE);
    }

    // 初始化收益记录
    LogProfit(0);
} else {
    Log("使用恢复的状态继续运行");
}

CYCLE_START_TIME = Unix();
LAST_SAVE_TIME = Unix();

// 保存初始状态
safeSaveState();

Log("========== 策略运行中 ==========");
Log("状态将每5分钟自动保存,支持关机/重启后恢复");

// 主循环
while (true) {
    try {
        onTick();
    } catch (e) {
        if (isEOFError(e)) {
            Log("检测到 EOF,可能是回测数据结束或连接被关闭,保存状态后退出主循环");
            safeSaveState();
            break;
        }
        Log("策略执行错误:", e);
    }

    Sleep(3000);  // 每3秒执行一次
}

} “`

相关推荐
全部留言
avatar of ianzeng123
ianzeng123
```javascript function main(){ const marketinfo = exchange.GetMarkets() const symbolinfo = marketinfo['BTC_USDT.swap'] Log(symbolinfo) //返回币种的各种信息 AmountPrecision 为3 let quantity = 5.776123 quantity = _N(quantity, symbolinfo.AmountPrecision) Log(quantity) //返回数量精度处理后的 5.776 } ```
2025-12-08 14:14:31
avatar of ianzeng123
ianzeng123
```javascript let statusDisplay = '`' + JSON.stringify(accountTable) + '`\n\n'; statusDisplay += '`' + JSON.stringify(positionTable) + '`\n\n'; statusDisplay += '`' + JSON.stringify(analysisTable) + '`\n\n'; statusDisplay += '`' + JSON.stringify(executionTable) + '`'; // 添加更新时间提示 if (lastUpdateTime) { const timeSinceUpdate = Math.floor((Date.now() - lastUpdateTime) / 1000); statusDisplay += `\n\n⏱️ 上次决策: ${timeSinceUpdate}秒前`; } // 显示状态 LogStatus(statusDisplay); ``` 参考一下
2025-12-09 10:04:54
avatar of 我想量化躺着挣钱
我想量化躺着挣钱
/upload/asset/2dfc70258713f23aedc1d.png让状态信息栏变成表格的模式需要引用什么函数,我这搞半天还都是这种字体的,根本看不懂
2025-12-08 18:12:02
avatar of ianzeng123
ianzeng123
可以输入一些成熟的策略喂给他,让它模仿着写
2025-12-08 17:45:56
avatar of 我想量化躺着挣钱
我想量化躺着挣钱
https://www.fmz.com/robot/636663好像能跑了,不知道还会不会出错。
2025-12-08 17:36:57
avatar of 发明者量化-小小梦
发明者量化-小小梦
看起来问题挺多的,可以扔给AI,审核一下策略代码。
2025-12-08 13:05:35
avatar of 我想量化躺着挣钱
我想量化躺着挣钱
ETH在欧易下单精度可以0.001就这一个问题我熬夜五天到现在都不能解决AI也不能解决
2025-12-08 13:26:00
avatar of 我想量化躺着挣钱
我想量化躺着挣钱
扔给AI AI就骗我。半个月了AI我都换冒烟了,还是不能解决。还的是人工,求助各位大佬
2025-12-08 13:20:11
avatar of 发明者量化-小小梦
发明者量化-小小梦
代码看着有点像AI写的。
2025-12-08 11:28:29
avatar of 发明者量化-小小梦
发明者量化-小小梦
精度计算中的变量作用域问题 ```javascript function calculateOrderAmount(price, orderValue, amountPrecision) { // ... Log("计算订单数量 - 对齐到步长: " + amount.toFixed(amtPrecision)); // ↑ amtPrecision 在这行之后才定义 var amtPrecision = Math.max(amountPrecision || ...); } ``` amtPrecision 在使用前未定义,JavaScript会变量提升但值为 undefined。
2025-12-08 13:05:10
avatar of 我想量化躺着挣钱
我想量化躺着挣钱
是的梦老板,我怎么都弄不好下单精度还有多空网格同时运行出现混乱的问题,弄了半个月了太难了
2025-12-08 12:08:11