avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada Pesan pribadi
4
fokus pada
1319
Pengikut

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Dibuat di: 2026-01-22 09:30:47, diperbarui pada: 2026-01-22 18:12:51
comments   8
hits   582

[TOC]

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Kata pengantar

Baru-baru ini, platform kuantitatif FMZ telah resmi diintegrasikan.Lighter DEXJujur saja, saya tidak terlalu memperhatikan berita ini ketika pertama kali melihatnya—lagipula, ada banyak sekali DEX di pasaran. Tetapi setelah mempelajari lebih lanjut, satu fitur menarik perhatian saya: biaya transaksi nol.

Ya, Anda tidak salah baca. Lighter DEX menawarkan biaya komisi nol untuk trader reguler. Ini langsung mengingatkan saya pada sesuatu: bisakah saya akhirnya menghidupkan kembali strategi-strategi yang telah saya “tunda” bertahun-tahun lalu karena biaya komisi? Jadi, saya membuka FMZ…Strategi PersegiMencari strategi dari “zaman kuno” itu…

1. Lighter

Saya tidak akan membahas terlalu detail tentang DEX yang baru ditambahkan ini; mereka yang tertarik dapat mencari informasi lebih lanjut. Saat ini, pengalaman pengguna cukup baik. Dari segi pengalaman pengguna, Lighter menawarkan kinerja yang sebanding dengan bursa terpusat sambil mempertahankan transparansi terdesentralisasi, dan tetap relatif stabil bahkan dengan akses API frekuensi tinggi.

Ringkasan Data

Berikut adalah rangkuman beberapa informasi:

Konfigurasi

Selanjutnya, saya akan memperkenalkan secara singkat cara mengkonfigurasi FMZ.LighterTambahkan informasi konfigurasi KUNCI API Lighter di halaman pertukaran platform FMZ.

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Tiga hal perlu dikonfigurasi:

  • Kunci privat API tanda tangan Ini bukan kunci privat dompet. Kunci privat penandatanganan ini adalah kunci privat yang digunakan untuk melakukan pemesanan dan transaksi, yang dibuat setelah masuk ke Lighter dan menghubungkan dompet Anda di https://app.lighter.xyz.

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

  • Jika Anda masuk ke lingkungan pengujian Lighter, kunci yang dibuat akan menjadi kunci lingkungan pengujian, yang tidak akan dijelaskan lebih lanjut di sini.
  • Saat membuat kunci privat penandatanganan, Anda perlu menentukan indeks. 0~2 adalah bit yang dicadangkan, dan Anda dapat menentukan mulai dari 3 dan seterusnya.
  • Semua langkah login dan pembuatan ini memerlukan penandatanganan dompet, dan saya menggunakan Binance Wallet dan memiliki pengalaman yang baik.

DibuatKunci pribadi tanda tanganKonfigurasi dapat dilakukan di kotak edit kontrol yang sesuai pada halaman Tambah Bursa FMZ.

  • Catatan Penting: Anda perlu mengunduh versi terbaru program kustodian untuk mendukung bursa kontrak berjangka Lighter.

  • Indeks API Masukkan indeks yang sesuai dengan kunci privat penandatanganan.

  • Indeks Akun Indeks akun dapat diperoleh melalui API Lighter:

    • Antarmuka API:https://mainnet.zklighter.elliot.ai/api/v1/account?by=l1_address&value={钱包地址} Sebagai contoh, akses alamat tersebut langsung di browser:https://mainnet.zklighter.elliot.ai/api/v1/account?by=l1_address&value=0x123xxxx0x123xxxxIni hanya contoh alamat; ganti konten ini saat menggunakannya dalam praktiknya. Data yang dikembalikan:
    {
      "code": 200,
      "total": 1,
      "accounts": [
        {
          "code": 0,
          "account_type": 0,
          "index": 1234567,
          "l1_address": "0x123xxxx",
    

    di dalam"index": 1234567Itulah indeks akun Anda.

    • Proses pembuatan awal hanya akan dimulai ketika aset (seperti USDC) ditransfer masuk.Lighterakun

    • Perhatikan bahwa antarmuka yang diperoleh menggunakan endpoint mainnet mengambil indeks akun mainnet, sedangkan antarmuka yang diperoleh menggunakan endpoint testnet mengambil indeks akun testnet.

Mengapa kita perlu mengisi indeks akun ini? Karena…LighterTerdapat sistem sub-akun yang membedakan akun yang berbeda berdasarkan indeks akun. Jika Anda perlu menggunakan sub-akun, Anda dapat mengkonfigurasi indeks akun sub-akun di sini (indeks akun sub-akun akan muncul dalam data JSON yang dikembalikan oleh tautan kueri di atas).

2. Strategi kuno di FMZ

Tanpa biaya: sebuah terobosan besar.

Inilah fitur yang paling membuat saya bersemangat. Lighter menawarkan kebijakan tanpa biaya untuk trader biasa.

  • Apa arti biaya transaksi nol?

Strategi perdagangan frekuensi tinggi tidak lagi mengalami keuntungan yang “terkikis” oleh biaya transaksi. Strategi mesh memungkinkan pengaturan jarak mesh yang lebih rapat. Titik impas untuk strategi arbitrase telah berkurang secara signifikan. Strategi-strategi yang “secara teoritis layak tetapi digagalkan oleh biaya transaksi dalam praktiknya” akhirnya menemukan tempat untuk digunakan.

Mengungkap strategi kuno: daya tarik biaya transaksi nol

Strategi Perpustakaan Arkeologi

Dengan pertanyaan di benak saya, “Strategi apa yang dapat dihidupkan kembali tanpa biaya transaksi?”, saya mulai mencari di perpustakaan strategi dan komunitas FMZ. Tak lama kemudian, sebuah strategi yang familiar menarik perhatian saya:

https://www.fmz.com/digest-topic/1211

Strategi ini sederhana dan mudah dipahami, tetapi dalam lingkungan dengan biaya transaksi, hampir selalu berujung pada kerugian. Namun, dalam lingkungan Lighter yang tidak mengenakan biaya transaksi, strategi ini layak dicoba.

Jadi, inilah pertanyaannya:

Jadi, inilah masalahnya: kode tersebut terlalu usang. Jika dilihat dari strateginya, kode tersebut sederhana dan menggunakan pendekatan brute-force, hampir tanpa konten UI dan kurang fitur aksesibilitas. Berikut beberapa contoh dari apa yang hilang:

  • Beberapa antarmuka API sudah usang.
  • Sistem ini tidak memiliki modul pengendalian risiko modern.
  • Informasinya hilang.
  • Data statistik pendapatan tidak tersedia.

Melakukan refactoring kode ini secara manual? Sejujurnya, itu agak menakutkan. Namun, saya telah menemukan solusi “malas”—biarkan AI yang melakukan refactoring untuk saya.

3. Strategi Restrukturisasi

Pertama, mari kita tetapkan pengaman: artikel ini hanyalah upaya eksplorasi untuk merekonstruksi strategi menggunakan AI pada bursa DEX yang sedang berkembang, dan kami tidak menjamin profitabilitas strategi yang direkonstruksi. Jadi, mari kita mulai merekonstruksi strategi lama ini menggunakan Claude. Saya tidak ingin menulis kode dari awal; persyaratan saya adalah:

  • Pertahankan logika inti dari strategi aslinya.
  • Diadaptasi sesuai dengan spesifikasi API terbaru dari FMZ.
  • Tambahkan modul pengendalian risiko dan pencatatan yang diperlukan.
  • Informasi yang ditampilkan relatif lengkap dan jelas.
  • Optimalkan logika kode dengan tepat.

Berikan kode asli ke AI.

Saya menyalin kode strategi asli dan mengirimkannya bersama dengan persyaratan saya ke AI. Setelah beberapa putaran dialog dan penyesuaian, AI menghasilkan kode yang telah direfaktor untuk saya:

bash: while :; do cat PROMPT.md | claude-code ; done
) (Pikiran yang perlu dipelajari)
/*
高频做市策略 - FMZ期货版(带仓位矫正)
策略参数:
- sleeptime: 休眠时间(毫秒) - 默认3500
- floatamountbuy: 买单深度阈值 - 默认20
- floatamountsell: 卖单深度阈值 - 默认20
- diffprice: 最小套利差价 - 默认50
- baseAmount: 基础下单量 - 默认0.1
- maxPosition: 最大单边持仓量 - 默认10
- stopLossRatio: 止损比例 - 默认0.9 (90%)
- closeOnExit: 退出时清仓 - 默认false
*/

// 全局变量
var pricePrecision = 2;
var amountPrecision = 3;
var tickSize = 0.01;
var minQty = 0.001;
var symbol = "ETH_USDT.swap";

// 统计信息
var stats = {
    startTime: 0,
    cycleCount: 0,
    orderCount: 0,
    cancelCount: 0,
    initialEquity: 0,
    currentEquity: 0,
    maxEquity: 0,
    maxDrawdown: 0,
    isStopLoss: false,
    lastLogCleanTime: 0,
    lastEmergencyTime: 0
};

// 日志清理配置
var LOG_CLEAN_INTERVAL = 60 * 60 * 1000;
var LOG_RESERVE_COUNT = 10000;
var EMERGENCY_COOLDOWN = 5000;

// ==================== 精度工具函数 ====================

/**
 * 从数值推断精度(小数位数)
 * 例如: 0.005 -> 3, 0.0001 -> 4, 0.1 -> 1, 1 -> 0
 */
function GetPrecisionFromValue(value) {
    if (!value || value >= 1) return 0;
    
    var str = value.toString();
    
    // 处理科学计数法 (如 1e-4)
    if (str.indexOf('e') !== -1) {
        var match = str.match(/e-(\d+)/);
        return match ? parseInt(match[1]) : 0;
    }
    
    // 处理普通小数
    if (str.indexOf('.') === -1) return 0;
    
    return str.split('.')[1].length;
}

/**
 * 规范化下单量
 * 1. 按精度取整
 * 2. 确保是 minQty 的整数倍
 * 3. 不小于 minQty
 */
function NormalizeAmount(amount) {
    if (amount <= 0) return 0;
    
    // 按精度取整
    var normalized = _N(amount, amountPrecision);
    
    // 确保是 minQty 的整数倍
    if (minQty > 0) {
        normalized = Math.floor(normalized / minQty) * minQty;
        normalized = _N(normalized, amountPrecision);
    }
    
    // 检查最小下单量
    if (normalized < minQty) {
        return 0;
    }
    
    return normalized;
}

/**
 * 规范化价格
 */
function NormalizePrice(price) {
    if (tickSize > 0) {
        price = Math.round(price / tickSize) * tickSize;
    }
    return _N(price, pricePrecision);
}

// 取消全部订单
function CancelPendingOrders() {
    var orders = _C(exchange.GetOrders, symbol);
    var count = 0;
    for (var j = 0; j < orders.length; j++) {
        exchange.CancelOrder(orders[j].Id, orders[j]);
        count++;
    }
    if (count > 0) {
        stats.cancelCount += count;
    }
    return count;
}

// 计算将要下单的价格
function GetPrice(Type, depth) {
    var amountBids = 0;
    var amountAsks = 0;
    
    if (Type == "Buy") {
        for (var i = 0; i < 20 && i < depth.Bids.length; i++) {
            amountBids += depth.Bids[i].Amount;
            if (amountBids > floatamountbuy) {
                return NormalizePrice(depth.Bids[i].Price + tickSize);
            }
        }
    }
    
    if (Type == "Sell") {
        for (var j = 0; j < 20 && j < depth.Asks.length; j++) {
            amountAsks += depth.Asks[j].Amount;
            if (amountAsks > floatamountsell) {
                return NormalizePrice(depth.Asks[j].Price - tickSize);
            }
        }
    }
    
    return NormalizePrice(depth.Asks[0].Price);
}

// 获取持仓信息
function GetPosition() {
    var positions = _C(exchange.GetPositions, symbol);
    var pos = {
        long: { amount: 0, price: 0, profit: 0 },
        short: { amount: 0, price: 0, profit: 0 }
    };
    
    for (var i = 0; i < positions.length; i++) {
        var p = positions[i];
        if (p.Type === PD_LONG || p.Type === 0) {
            pos.long.amount = p.Amount;
            pos.long.price = p.Price;
            pos.long.profit = p.Profit || 0;
        } else {
            pos.short.amount = p.Amount;
            pos.short.price = p.Price;
            pos.short.profit = p.Profit || 0;
        }
    }
    return pos;
}

// 计算账户权益
function GetEquity(account, pos) {
    var equity = account.Balance + account.FrozenBalance + pos.long.profit + pos.short.profit;
    return equity;
}

// 检查资金是否足够下单
function CheckFunds(account, price, amount, leverage) {
    leverage = leverage || 10;
    var requiredMargin = (price * amount) / leverage;
    var availableBalance = account.Balance;
    var safeBalance = availableBalance * 0.9;
    return safeBalance >= requiredMargin;
}

// ==================== 仓位矫正机制 ====================

/**
 * 计算动态开仓量(负反馈机制)
 */
function CalcOpenAmount(pos, direction) {
    var currentPos = (direction === "long") ? pos.long.amount : pos.short.amount;
    var posRatio = currentPos / maxPosition;
    
    if (currentPos >= maxPosition) {
        return 0;
    }
    
    var amount = baseAmount;
    if (posRatio > 0.8) {
        amount = baseAmount * 0.2;
    } else if (posRatio > 0.6) {
        amount = baseAmount * 0.4;
    } else if (posRatio > 0.4) {
        amount = baseAmount * 0.6;
    } else if (posRatio > 0.2) {
        amount = baseAmount * 0.8;
    }
    
    var netPos = pos.long.amount - pos.short.amount;
    if (direction === "long" && netPos > maxPosition * 0.3) {
        amount = amount * 0.5;
    } else if (direction === "short" && netPos < -maxPosition * 0.3) {
        amount = amount * 0.5;
    }
    
    return NormalizeAmount(amount);
}

/**
 * 计算动态平仓量
 */
function CalcCloseAmount(pos, direction) {
    var currentPos = (direction === "long") ? pos.long.amount : pos.short.amount;
    if (currentPos <= 0) return 0;
    
    var posRatio = currentPos / maxPosition;
    var amount = baseAmount;
    
    if (posRatio > 1.0) {
        amount = currentPos;
    } else if (posRatio > 0.8) {
        amount = baseAmount * 3.0;
    } else if (posRatio > 0.6) {
        amount = baseAmount * 2.0;
    } else if (posRatio > 0.4) {
        amount = baseAmount * 1.5;
    }
    
    amount = Math.min(amount, currentPos);
    
    return NormalizeAmount(amount);
}

/**
 * 计算平仓价格(仓位重时更激进)
 */
function CalcClosePrice(pos, depth, direction) {
    var currentPos = (direction === "long") ? pos.long.amount : pos.short.amount;
    var posRatio = currentPos / maxPosition;
    
    if (direction === "long") {
        if (posRatio > 1.0) {
            return NormalizePrice(depth.Bids[0].Price - tickSize * 3);
        } else if (posRatio > 0.8) {
            return NormalizePrice(depth.Bids[0].Price);
        } else if (posRatio > 0.5) {
            var midPrice = (depth.Bids[0].Price + depth.Asks[0].Price) / 2;
            return NormalizePrice(midPrice);
        }
        return NormalizePrice(depth.Asks[0].Price - tickSize);
    } else {
        if (posRatio > 1.0) {
            return NormalizePrice(depth.Asks[0].Price + tickSize * 3);
        } else if (posRatio > 0.8) {
            return NormalizePrice(depth.Asks[0].Price);
        } else if (posRatio > 0.5) {
            var midPrice = (depth.Bids[0].Price + depth.Asks[0].Price) / 2;
            return NormalizePrice(midPrice);
        }
        return NormalizePrice(depth.Bids[0].Price + tickSize);
    }
}

/**
 * 紧急减仓
 */
function EmergencyReduce(pos, depth) {
    var now = new Date().getTime();
    
    if (now - stats.lastEmergencyTime < EMERGENCY_COOLDOWN) {
        return false;
    }
    
    var needReduce = false;
    
    if (pos.long.amount > maxPosition * 1.2) {
        var reduceAmount = NormalizeAmount(pos.long.amount - maxPosition);
        if (reduceAmount > 0) {
            Log("⚠️ 多头严重超标 (" + pos.long.amount + "/" + maxPosition + "),市价减仓: " + reduceAmount, "#FF0000");
            var orderId = exchange.CreateOrder(symbol, "closebuy", -1, reduceAmount);
            if (orderId) {
                stats.orderCount++;
                stats.lastEmergencyTime = now;
            }
            needReduce = true;
        }
    }
    
    if (pos.short.amount > maxPosition * 1.2) {
        var reduceAmount = NormalizeAmount(pos.short.amount - maxPosition);
        if (reduceAmount > 0) {
            Log("⚠️ 空头严重超标 (" + pos.short.amount + "/" + maxPosition + "),市价减仓: " + reduceAmount, "#FF0000");
            var orderId = exchange.CreateOrder(symbol, "closesell", -1, reduceAmount);
            if (orderId) {
                stats.orderCount++;
                stats.lastEmergencyTime = now;
            }
            needReduce = true;
        }
    }
    
    if (needReduce) {
        Sleep(1000);
    }
    
    return needReduce;
}

function IsPositionOverload(pos) {
    return pos.long.amount > maxPosition || pos.short.amount > maxPosition;
}

// ==================== 日志清理 ====================

function CleanLogs() {
    var now = new Date().getTime();
    if (now - stats.lastLogCleanTime > LOG_CLEAN_INTERVAL) {
        LogReset(LOG_RESERVE_COUNT);
        stats.lastLogCleanTime = now;
        Log("日志已清理,保留最近 " + LOG_RESERVE_COUNT + " 条", "#0000FF");
    }
}

// ==================== 清仓相关 ====================

function CloseAllPositions(reason) {
    reason = reason || "手动触发";
    Log("========== 触发清仓 [" + reason + "] ==========", "#FF0000");
    
    CancelPendingOrders();
    Sleep(500);
    
    var pos = GetPosition();
    
    if (pos.long.amount > 0) {
        var orderId = exchange.CreateOrder(symbol, "closebuy", -1, pos.long.amount);
        if (orderId) {
            Log("市价平多: " + pos.long.amount, "#FF0000");
        }
    }
    
    if (pos.short.amount > 0) {
        var orderId = exchange.CreateOrder(symbol, "closesell", -1, pos.short.amount);
        if (orderId) {
            Log("市价平空: " + pos.short.amount, "#FF0000");
        }
    }
    
    Sleep(2000);
    
    var finalPos = GetPosition();
    if (finalPos.long.amount > 0 || finalPos.short.amount > 0) {
        Log("⚠️ 警告:仍有未平仓位!多头: " + finalPos.long.amount + ", 空头: " + finalPos.short.amount, "#FF0000");
        if (finalPos.long.amount > 0) {
            exchange.CreateOrder(symbol, "closebuy", -1, finalPos.long.amount);
        }
        if (finalPos.short.amount > 0) {
            exchange.CreateOrder(symbol, "closesell", -1, finalPos.short.amount);
        }
        Sleep(1000);
    } else {
        Log("✅ 所有仓位已清空", "#00FF00");
    }
    
    Log("========== 清仓完成 ==========", "#FF0000");
}

function CheckStopLoss(equity) {
    if (stats.isStopLoss) {
        return true;
    }
    
    var threshold = stats.initialEquity * stopLossRatio;
    
    if (equity < threshold) {
        stats.isStopLoss = true;
        var lossPercent = ((stats.initialEquity - equity) / stats.initialEquity * 100).toFixed(2);
        Log("⚠️ 触发止损! 当前权益: " + _N(equity, 4) + " USDT, 损失: " + lossPercent + "%", "#FF0000");
        return true;
    }
    
    return false;
}

function UpdateProfitChart(equity) {
    var profit = equity - stats.initialEquity;
    
    if (equity > stats.maxEquity) {
        stats.maxEquity = equity;
    }
    var drawdown = (stats.maxEquity - equity) / stats.maxEquity * 100;
    if (drawdown > stats.maxDrawdown) {
        stats.maxDrawdown = drawdown;
    }
    
    LogProfit(_N(profit, 4), "&");
}

function UpdateStatus(account, pos, depth, buyPrice, sellPrice, equity) {
    var runTime = (new Date().getTime() - stats.startTime) / 1000 / 60;
    var hours = Math.floor(runTime / 60);
    var mins = Math.floor(runTime % 60);
    
    var spread = sellPrice - buyPrice;
    var marketSpread = depth.Asks[0].Price - depth.Bids[0].Price;
    
    var profit = equity - stats.initialEquity;
    var profitPercent = (profit / stats.initialEquity * 100).toFixed(2);
    var drawdown = stats.maxEquity > 0 ? ((stats.maxEquity - equity) / stats.maxEquity * 100).toFixed(2) : 0;
    
    var longRatio = (pos.long.amount / maxPosition * 100).toFixed(1);
    var shortRatio = (pos.short.amount / maxPosition * 100).toFixed(1);
    var netPos = _N(pos.long.amount - pos.short.amount, amountPrecision);
    
    var table1 = {
        type: "table",
        title: "💰 账户信息",
        cols: ["项目", "数值"],
        rows: [
            ["可用余额", _N(account.Balance, 4) + " USDT"],
            ["冻结余额", _N(account.FrozenBalance, 4) + " USDT"],
            ["当前权益", _N(equity, 4) + " USDT"],
            ["初始权益", _N(stats.initialEquity, 4) + " USDT"],
            ["最高权益", _N(stats.maxEquity, 4) + " USDT"]
        ]
    };
    
    var table2 = {
        type: "table",
        title: "📈 收益统计",
        cols: ["项目", "数值"],
        rows: [
            ["累计收益", _N(profit, 4) + " USDT"],
            ["收益率", profitPercent + " %"],
            ["最大回撤", drawdown + " %"],
            ["止损阈值", (stopLossRatio * 100) + " %"],
            ["止损状态", stats.isStopLoss ? "⚠️ 已触发" : "✅ 正常"]
        ]
    };
    
    var longStatus, shortStatus;
    if (longRatio > 120) {
        longStatus = "🔴 紧急减仓";
    } else if (longRatio > 100) {
        longStatus = "🟠 超标";
    } else if (longRatio > 80) {
        longStatus = "🟡 控量";
    } else {
        longStatus = "🟢 正常";
    }
    
    if (shortRatio > 120) {
        shortStatus = "🔴 紧急减仓";
    } else if (shortRatio > 100) {
        shortStatus = "🟠 超标";
    } else if (shortRatio > 80) {
        shortStatus = "🟡 控量";
    } else {
        shortStatus = "🟢 正常";
    }
    
    var table3 = {
        type: "table",
        title: "📊 持仓信息(仓位矫正)",
        cols: ["方向", "数量", "上限", "使用率", "状态", "浮盈"],
        rows: [
            ["多头", pos.long.amount, maxPosition, longRatio + "%", longStatus, _N(pos.long.profit, 4)],
            ["空头", pos.short.amount, maxPosition, shortRatio + "%", shortStatus, _N(pos.short.profit, 4)],
            ["净仓", netPos, "-", "-", netPos > 0 ? "偏多" : (netPos < 0 ? "偏空" : "均衡"), "-"]
        ]
    };
    
    var table4 = {
        type: "table",
        title: "🎯 做市信息",
        cols: ["项目", "数值"],
        rows: [
            ["买一价", _N(depth.Bids[0].Price, pricePrecision)],
            ["卖一价", _N(depth.Asks[0].Price, pricePrecision)],
            ["盘口价差", _N(marketSpread, pricePrecision)],
            ["挂单买价", _N(buyPrice, pricePrecision)],
            ["挂单卖价", _N(sellPrice, pricePrecision)],
            ["做市价差", _N(spread, pricePrecision)]
        ]
    };
    
    var table5 = {
        type: "table",
        title: "⏱️ 运行统计",
        cols: ["项目", "数值"],
        rows: [
            ["运行时间", hours + "时" + mins + "分"],
            ["循环次数", stats.cycleCount],
            ["下单次数", stats.orderCount],
            ["撤单次数", stats.cancelCount],
            ["休眠时间", sleeptime + " ms"]
        ]
    };
    
    var table6 = {
        type: "table",
        title: "⚙️ 精度与参数",
        cols: ["参数", "值"],
        rows: [
            ["交易符号", symbol],
            ["价格精度", pricePrecision],
            ["数量精度", amountPrecision],
            ["最小下单量", minQty],
            ["价格步长", tickSize],
            ["基础下单量", baseAmount],
            ["最大持仓量", maxPosition],
            ["退出时清仓", closeOnExit ? "✅ 是" : "❌ 否"]
        ]
    };
    
    var statusIcon = stats.isStopLoss ? "🛑 已止损" : (IsPositionOverload(pos) ? "⚠️ 仓位超标" : "🤖 运行中");
    var statusStr = statusIcon + " | " + _D() + " | 收益: " + _N(profit, 2) + " USDT (" + profitPercent + "%)\n";
    statusStr += "多仓: " + pos.long.amount + "/" + maxPosition + " (" + longRatio + "%) | ";
    statusStr += "空仓: " + pos.short.amount + "/" + maxPosition + " (" + shortRatio + "%) | 净: " + netPos + "\n";
    statusStr += "`" + JSON.stringify([table1, table2, table3, table4, table5, table6]) + "`";
    
    LogStatus(statusStr);
}

// 主交易逻辑
function onTick() {
    stats.cycleCount++;
    
    CleanLogs();
    
    var depth = _C(exchange.GetDepth);
    if (!depth || !depth.Bids || !depth.Asks || depth.Bids.length < 20 || depth.Asks.length < 20) {
        Log("深度数据不足,跳过本轮");
        Sleep(1000);
        return;
    }
    
    var account = _C(exchange.GetAccount);
    var pos = GetPosition();
    
    var equity = GetEquity(account, pos);
    stats.currentEquity = equity;
    
    if (stats.cycleCount % 10 === 0) {
        UpdateProfitChart(equity);
    }
    
    var buyPrice = GetPrice("Buy", depth);
    var sellPrice = GetPrice("Sell", depth);
    
    if ((sellPrice - buyPrice) <= diffprice) {
        // buyPrice = NormalizePrice(buyPrice - 10 * tickSize);
        // sellPrice = NormalizePrice(sellPrice + 10 * tickSize);

        buyPrice = NormalizePrice(buyPrice - diffprice/2);
        sellPrice = NormalizePrice(sellPrice + diffprice/2);
    }
    
    UpdateStatus(account, pos, depth, buyPrice, sellPrice, equity);
    
    if (CheckStopLoss(equity)) {
        if (pos.long.amount > 0 || pos.short.amount > 0) {
            CloseAllPositions("止损触发");
        } else {
            CancelPendingOrders();
        }
        Log("策略已止损,停止交易。如需继续,请手动重启策略。", "#FF0000");
        return;
    }
    
    CancelPendingOrders();
    
    EmergencyReduce(pos, depth);
    
    pos = GetPosition();
    
    var openLongAmount = CalcOpenAmount(pos, "long");
    var openShortAmount = CalcOpenAmount(pos, "short");
    var closeLongAmount = CalcCloseAmount(pos, "long");
    var closeShortAmount = CalcCloseAmount(pos, "short");
    
    var closeLongPrice = CalcClosePrice(pos, depth, "long");
    var closeShortPrice = CalcClosePrice(pos, depth, "short");
    
    if (openLongAmount > 0 && CheckFunds(account, buyPrice, openLongAmount)) {
        var orderId = exchange.CreateOrder(symbol, "buy", buyPrice, openLongAmount);
        if (orderId) stats.orderCount++;
    }
    
    if (pos.short.amount > 0 && closeShortAmount > 0) {
        var orderId = exchange.CreateOrder(symbol, "closesell", closeShortPrice, closeShortAmount);
        if (orderId) stats.orderCount++;
    }
    
    if (openShortAmount > 0 && CheckFunds(account, sellPrice, openShortAmount)) {
        var orderId = exchange.CreateOrder(symbol, "sell", sellPrice, openShortAmount);
        if (orderId) stats.orderCount++;
    }
    
    if (pos.long.amount > 0 && closeLongAmount > 0) {
        var orderId = exchange.CreateOrder(symbol, "closebuy", closeLongPrice, closeLongAmount);
        if (orderId) stats.orderCount++;
    }
}

// 初始化交易精度
function InitPrecision() {
    try {
        var markets = exchange.GetMarkets();
        if (markets && markets[symbol]) {
            var market = markets[symbol];
            
            // 获取基础精度信息
            pricePrecision = market.PricePrecision || 2;
            tickSize = market.TickSize || 0.01;
            minQty = market.MinQty || 0.001;
            
            // 从 MinQty 推断数量精度
            // 例如: MinQty=0.005 -> 精度3, MinQty=0.0001 -> 精度4
            var minQtyPrecision = GetPrecisionFromValue(minQty);
            
            // 从 TickSize 推断价格精度(作为备选验证)
            var tickSizePrecision = GetPrecisionFromValue(tickSize);
            
            // 数量精度取 AmountPrecision 和 MinQty推断精度 的较小值
            var declaredAmountPrecision = market.AmountPrecision || 8;
            amountPrecision = Math.min(declaredAmountPrecision, minQtyPrecision);
            
            // 价格精度取 PricePrecision 和 TickSize推断精度 的较小值
            pricePrecision = Math.min(pricePrecision, tickSizePrecision);
            
            Log("========== 精度信息 ==========");
            Log("市场返回 - PricePrecision:", market.PricePrecision, ", AmountPrecision:", market.AmountPrecision);
            Log("市场返回 - TickSize:", tickSize, ", MinQty:", minQty);
            Log("推断精度 - TickSize精度:", tickSizePrecision, ", MinQty精度:", minQtyPrecision);
            Log("最终使用 - 价格精度:", pricePrecision, ", 数量精度:", amountPrecision);
            Log("==============================");
            
            // 检查 baseAmount 是否满足最小下单量
            if (baseAmount < minQty) {
                Log("⚠️ 警告: baseAmount(" + baseAmount + ") 小于最小下单量(" + minQty + "),已自动调整", "#FF9900");
                baseAmount = minQty;
            }
            
            // 规范化 baseAmount
            baseAmount = NormalizeAmount(baseAmount);
            if (baseAmount === 0) {
                baseAmount = minQty;
            }
            Log("规范化后 baseAmount:", baseAmount);
        }
    } catch (e) {
        Log("获取精度失败,使用默认值: " + e.message, "#FF9900");
    }
}

// 初始化收益图表
function InitChart() {
    var chart = {
        __isStock: true,
        tooltip: { xDateFormat: '%Y-%m-%d %H:%M:%S, %A' },
        title: { text: '高频做市策略收益曲线' },
        xAxis: { type: 'datetime' },
        yAxis: {
            title: { text: '收益 (USDT)' },
            opposite: false
        },
        series: [{
            name: '收益',
            data: []
        }]
    };
    Chart(chart);
}

// 程序入口
function main() {
    LogReset(LOG_RESERVE_COUNT);
    LogProfitReset();
    
    InitChart();
    
    exchange.SetContractType("swap");
    
    symbol = exchange.GetCurrency() + ".swap";
    Log("交易符号:", symbol);
    
    // 测试是否支持Lighter
    if (!exchange.GetAccount()) {
        Log("账户初始化失败,请检查配置是否正确,托管者是否为最新版本!")
    }

    InitPrecision();
    
    stats.startTime = new Date().getTime();
    stats.lastLogCleanTime = stats.startTime;
    
    var initAccount = _C(exchange.GetAccount);
    var initPos = GetPosition();
    stats.initialEquity = GetEquity(initAccount, initPos);
    stats.maxEquity = stats.initialEquity;
    stats.currentEquity = stats.initialEquity;
    
    Log("========== 策略启动 ==========", "#00FF00");
    Log("初始权益:", _N(stats.initialEquity, 4), "USDT");
    Log("止损阈值:", _N(stats.initialEquity * stopLossRatio, 4), "USDT", "(" + (stopLossRatio * 100) + "%)");
    Log("最大持仓:", maxPosition);
    Log("退出时清仓:", closeOnExit ? "是" : "否");
    Log("初始账户:", initAccount);
    Log("初始持仓:", _C(exchange.GetPositions, symbol));
    
    while (true) {
        try {
            onTick();
        } catch (e) {
            Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message, "#FF0000");
        }
        Sleep(sleeptime);
    }
}

// 退出清理
function onexit() {
    Log("========== 策略停止 ==========", "#FF0000");
    
    if (closeOnExit) {
        Log("closeOnExit=true,执行退出清仓...", "#FF9900");
        CloseAllPositions("策略退出");
    } else {
        Log("closeOnExit=false,保留当前持仓和挂单", "#0000FF");
    }
    
    Log("----------------------------------------");
    Log("总循环: " + stats.cycleCount + ", 下单: " + stats.orderCount + ", 撤单: " + stats.cancelCount);
    Log("初始权益: " + _N(stats.initialEquity, 4) + " USDT");
    Log("最终权益: " + _N(stats.currentEquity, 4) + " USDT");
    Log("总收益: " + _N(stats.currentEquity - stats.initialEquity, 4) + " USDT");
    Log("收益率: " + _N((stats.currentEquity - stats.initialEquity) / stats.initialEquity * 100, 2) + " %");
    Log("最大回撤: " + _N(stats.maxDrawdown, 2) + " %");
    Log("----------------------------------------");
}

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Anda memberi tahu AI aturan pengeditan untuk parameter di FMZ, dan AI bahkan dapat mengkonfigurasi semua parameter antarmuka untuk Anda secara langsung. Demi penjelasan, saya mengkonfigurasi parameter secara manual pada antarmuka strategi, seperti yang ditunjukkan pada gambar di atas.

4. Perdagangan langsung

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Jujur saja, kode yang ditulis oleh AI jauh lebih baik daripada kode saya, dan jarang sekali membuat kesalahan (selama persyaratannya dijelaskan dengan jelas, saya hanya perlu melakukan iterasi 3-4 kali agar berjalan stabil). Saya merasa produktivitas saya meningkat pesat 💥 Meskipun strategi ini tampaknya belum menghasilkan uang saat ini 😂, volume perdagangan telah meningkat cukup banyak.

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

Restart strategi lama tanpa biaya: FMZ + DEX yang lebih ringan + AI dalam praktiknya

5. Ringkasan

Reaksi kimia FMZ + AI + Korek Api

Merenungkan kembali pengalaman ini, saya memiliki beberapa pemikiran:

  • Biaya nol memang benar-benar mengubah segalanya. Banyak strategi yang secara teoritis masuk akal di masa lalu telah dikalahkan oleh biaya transaksi, “pembunuh tak terlihat”. Kebijakan tanpa biaya Lighter telah memberi strategi-strategi ini kesempatan untuk bangkit kembali. Jika Anda memiliki “strategi yang tidak aktif” serupa, Anda mungkin bisa menggali dan mencobanya.

  • AI telah secara signifikan menurunkan hambatan dalam pengembangan strategi. Kali ini, saya hampir tidak menulis kode apa pun secara manual; seluruh restrukturisasi strategi diselesaikan menggunakan AI. Ini tidak terbayangkan sebelumnya. Bagi mereka yang memiliki ide trading tetapi keterampilan pemrograman terbatas, kombinasi AI dan FMZ tidak diragukan lagi merupakan anugerah.

  • Nilai dari integrasi cepat FMZ dengan bursa baru FMZ dapat dengan cepat terintegrasi dengan bursa yang sedang berkembang seperti Lighter, memungkinkan pengguna untuk segera memanfaatkan peluang. API terpadu juga berarti strategi Anda dapat dengan mudah dimigrasikan ke platform baru.

Langkah selanjutnya

Selanjutnya, saya berencana untuk:

  • Lanjutkan mengoptimalkan parameter strategi ini.
  • Cobalah lebih banyak jenis strategi yang cocok untuk lingkungan tanpa biaya.
  • Jelajahi strategi relevan yang dapat diterapkan pada Lighter.

Strategi kuno lainnya meliputi: OK Leek Harvester, dll.

Terima kasih atas dukungan Anda.

Terima kasih telah membaca. Jangan ragu untuk memberikan saran atau permintaan.

6. Penafian

Artikel ini hanya untuk tujuan pertukaran teknis dan pembelajaran dan bukan merupakan saran investasi apa pun.

  • Risiko Strategi: Kode strategi yang ditampilkan dalam artikel ini hanya untuk tujuan demonstrasi teknis dan tidak menjamin profitabilitas. Perdagangan kuantitatif secara inheren melibatkan risiko, dan pengujian historis atau kinerja perdagangan langsung jangka pendek bukanlah indikasi pengembalian di masa mendatang. Harap gunakan strategi ini dengan hati-hati hanya setelah sepenuhnya memahami logikanya.
  • Risiko DEX: Bursa terdesentralisasi (DEX) melibatkan risiko kontrak pintar, risiko likuiditas, dan risiko kemacetan jaringan. Sebagai platform yang sedang berkembang, stabilitas dan keamanan jangka panjang Lighter DEX masih perlu diverifikasi oleh pasar.
  • Kebijakan biaya transaksi nol: Kebijakan biaya pertukaran dapat disesuaikan sewaktu-waktu. Silakan merujuk pada pengumuman resmi terbaru dari Lighter. Meskipun transaksi gratis, biaya gas on-chain mungkin tetap dikenakan.
  • Kode yang dihasilkan AI: Kode strategi dalam artikel ini dihasilkan dengan bantuan AI. Meskipun telah diuji, kemungkinan terdapat bug atau kesalahan logika. Kode ini hanya untuk tujuan pembelajaran dan penelitian.
  • Pengguna menanggung semua risiko: Pengguna sepenuhnya bertanggung jawab atas segala konsekuensi yang timbul dari penggunaan informasi, kode, atau strategi yang disediakan dalam artikel ini. Penulis dan platform FMZ tidak bertanggung jawab atas kerugian langsung maupun tidak langsung.

Perdagangan mata uang kripto memiliki tingkat risiko yang tinggi. Pastikan Anda mengelola risiko dan berdagang secara rasional.