Beberapa pemikiran tentang logik perdagangan niaga hadapan mata wang digital

Dicipta dalam: 2020-06-01 09:52:45, dikemas kini pada: 2023-10-08 19:41:25
comments   6
hits   2068

Beberapa pemikiran tentang logik perdagangan niaga hadapan mata wang digital

Beberapa pemikiran tentang logik perdagangan niaga hadapan mata wang digital

Senario masalah

Untuk masa yang lama, masalah kelewatan data antara muka API kedudukan pertukaran mata wang digital sentiasa mengganggu saya. Saya belum menemui penyelesaian yang sesuai lagi, jadi saya akan menghasilkan semula masalah ini. Biasanya pesanan pasaran yang disediakan oleh bursa kontrak sebenarnya adalah harga rakan niaga, jadi kadang-kadang menggunakan apa yang dipanggil “pesanan pasaran” ini tidak boleh dipercayai. Oleh itu, apabila kita menulis strategi perdagangan niaga hadapan mata wang digital, kebanyakan kita menggunakan pesanan had. Selepas membuat setiap pesanan, kita perlu menyemak kedudukan untuk melihat sama ada pesanan telah dilaksanakan dan sama ada jawatan yang sepadan dipegang. Masalahnya terletak pada maklumat kedudukan ini Jika pesanan dilaksanakan, data yang dikembalikan oleh antara muka maklumat kedudukan pertukaran (iaitu, antara muka pertukaran yang sebenarnya diakses apabila kami memanggil pertukaran.GetPosition) harus memasukkan maklumat kedudukan yang baru dibuka data yang dikembalikan oleh pertukaran adalah data lama, iaitu maklumat kedudukan sebelum pesanan baru dibuat dilaksanakan, maka akan berlaku masalah. Logik perdagangan mungkin berfikir bahawa pesanan itu belum dilaksanakan dan terus membuat pesanan. Walau bagaimanapun, antara muka penempatan pesanan bursa tidak mengalami sebarang kelewatan Sebaliknya, urus niaga diselesaikan dengan sangat cepat, dan pesanan dilaksanakan sebaik sahaja ia dibuat. Ini akan mengakibatkan akibat yang serius bahawa strategi akan membuat pesanan berulang kali apabila operasi pembukaan dicetuskan.

Pengalaman sebenar

Kerana masalah ini, saya telah melihat strategi yang membuka kedudukan panjang penuh yang gila Mujurlah pasaran sedang berkembang pesat pada masa itu dan keuntungan terapung sekali melebihi 10BTC. Nasib baik, pasaran sedang berkembang pesat, jika ia telah menjunam, hasilnya akan diramalkan.

Cuba selesaikan

  • Penyelesaian 1 Logik pesanan strategi boleh direka untuk membuat hanya satu pesanan, dan harga pesanan ialah harga lawan pada masa itu ditambah dengan gelinciran yang lebih besar, supaya dapat menerima pesanan lawan pada kedalaman tertentu. Kelebihan melakukan ini ialah anda hanya membuat satu pesanan dan ia tidak berdasarkan maklumat kedudukan. Ini boleh mengelakkan masalah pesanan pendua, tetapi kadangkala membuat pesanan apabila harga berubah dengan ketara boleh mencetuskan mekanisme had harga pertukaran, dan ada kemungkinan walaupun dengan kegelinciran yang besar, pesanan itu masih tidak akan dilaksanakan, justeru terlepas peluang .

  • Penyelesaian 2 Gunakan fungsi pesanan pasaran bursa dan lulus -1 pada FMZ sebagai harga, yang merupakan pesanan pasaran Pada masa ini, antara muka hadapan OKEX telah dinaik taraf untuk menyokong pesanan pasaran sebenar.

  • Penyelesaian 3 Kami masih menggunakan logik dagangan sebelumnya dan membuat pesanan menggunakan pesanan had, tetapi kami menambah beberapa pengesanan pada logik dagangan untuk cuba menyelesaikan masalah yang disebabkan oleh kelewatan data kedudukan. Semak sama ada pesanan itu hilang daripada senarai pesanan yang belum selesai tanpa dibatalkan selepas membuat pesanan (terdapat dua kemungkinan untuk hilang dari senarai pesanan yang belum selesai: 1 pembatalan dan 2 pemenuhan Jika keadaan sedemikian dikesan dan kuantiti pesanan dan pesanan itu volum adalah sama seperti kali terakhir Pada masa ini, anda harus memberi perhatian kepada sama ada data kedudukan ditangguhkan Biarkan program memasuki logik menunggu dan memperoleh semula maklumat kedudukan daripada mencetuskan menunggu Jika ia melebihi bilangan tertentu, ini bermakna data antara muka kedudukan tertangguh Masalahnya serius dan logik transaksi ini ditamatkan.

Reka bentuk berdasarkan Skim 3

// 参数
/*
var MinAmount = 1
var SlidePrice = 5
var Interval = 500
*/

function GetPosition(e, contractType, direction) {
    e.SetContractType(contractType)
    var positions = _C(e.GetPosition);
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType == contractType && positions[i].Type == direction) {
            return positions[i]
        }
    }

    return null
}

function Open(e, contractType, direction, opAmount) {
    var initPosition = GetPosition(e, contractType, direction);
    var isFirst = true;
    var initAmount = initPosition ? initPosition.Amount : 0;
    var nowPosition = initPosition;
    var directBreak = false 
    var preNeedOpen = 0
    var timeoutCount = 0
    while (true) {
        var ticker = _C(e.GetTicker)
        var needOpen = opAmount;
        if (isFirst) {
            isFirst = false;
        } else {
            nowPosition = GetPosition(e, contractType, direction);
            if (nowPosition) {
                needOpen = opAmount - (nowPosition.Amount - initAmount);
            }
            // 检测directBreak 并且持仓未变的情况
            if (preNeedOpen == needOpen && directBreak) {
                Log("疑似仓位数据延迟,等待30秒", "#FF0000")
                Sleep(30000)
                nowPosition = GetPosition(e, contractType, direction);
                if (nowPosition) {
                    needOpen = opAmount - (nowPosition.Amount - initAmount);
                }
                /*
                timeoutCount++
                if (timeoutCount > 10) {
                    Log("连续10次疑似仓位延迟,下单失败!", "#FF0000")
                    break
                }
                */
            } else {
                timeoutCount = 0
            }
        }
        if (needOpen < MinAmount) {
            break;
        }
        
        var amount = needOpen;
        preNeedOpen = needOpen
        e.SetDirection(direction == PD_LONG ? "buy" : "sell");
        var orderId;
        if (direction == PD_LONG) {
            orderId = e.Buy(ticker.Sell + SlidePrice, amount, "开多仓", contractType, ticker);
        } else {
            orderId = e.Sell(ticker.Buy - SlidePrice, amount, "开空仓", contractType, ticker);
        }

        directBreak = false
        var n = 0
        while (true) {
            Sleep(Interval);
            var orders = _C(e.GetOrders);
            if (orders.length == 0) {
                if (n == 0) {
                    directBreak = true
                }
                break;
            }
            for (var j = 0; j < orders.length; j++) {
                e.CancelOrder(orders[j].Id);
                if (j < (orders.length - 1)) {
                    Sleep(Interval);
                }
            }
            n++
        }
    }

    var ret = {
        price: 0,
        amount: 0,
        position: nowPosition
    };
    if (!nowPosition) {
        return ret;
    }
    if (!initPosition) {
        ret.price = nowPosition.Price;
        ret.amount = nowPosition.Amount;
    } else {
        ret.amount = nowPosition.Amount - initPosition.Amount;
        ret.price = _N(((nowPosition.Price * nowPosition.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount);
    }
    return ret;
}

function Cover(e, contractType, opAmount, direction) {
    var initPosition = null;
    var position = null;
    var isFirst = true;

    while (true) {
        while (true) {
            Sleep(Interval);
            var orders = _C(e.GetOrders);
            if (orders.length == 0) {
                break;
            }
            for (var j = 0; j < orders.length; j++) {
                e.CancelOrder(orders[j].Id);
                if (j < (orders.length - 1)) {
                    Sleep(Interval);
                }
            }
        }

        position = GetPosition(e, contractType, direction)
        if (!position) {
            break
        }
        if (isFirst == true) {
            initPosition = position;
            opAmount = Math.min(opAmount, initPosition.Amount)
            isFirst = false;
        }

        var amount = opAmount - (initPosition.Amount - position.Amount)
        if (amount <= 0) {
            break
        }

        var ticker = _C(exchange.GetTicker)
        if (position.Type == PD_LONG) {
            e.SetDirection("closebuy");
            e.Sell(ticker.Buy - SlidePrice, amount, "平多仓", contractType, ticker);
        } else if (position.Type == PD_SHORT) {
            e.SetDirection("closesell");
            e.Buy(ticker.Sell + SlidePrice, amount, "平空仓", contractType, ticker);
        }

        Sleep(Interval)
    }

    return position
}

$.OpenLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_LONG, amount);
}

$.OpenShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_SHORT, amount);
};

$.CoverLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_LONG);
};

$.CoverShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_SHORT);
};


function main() {
    Log(exchange.GetPosition())
    var info = $.OpenLong(exchange, "quarter", 100)
    Log(info, "#FF0000")

    Log(exchange.GetPosition())
    info = $.CoverLong(exchange, "quarter", 30)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")

    info = $.CoverLong(exchange, "quarter", 80)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")
}

Alamat templat: https://www.fmz.com/strategy/203258

Cara untuk memanggil antara muka templat adalah sama seperti dalam fungsi utama di atas$.OpenLong$.CoverLong。 Templat adalah versi beta. Cadangan dan komen kami akan terus mengoptimumkannya untuk menyelesaikan masalah kelewatan data kedudukan.