Beberapa Pemikiran mengenai Logik Dagangan Futures Mata Wang Digital

Penulis:Lydia, Dicipta: 2022-11-30 17:12:20, Dikemas kini: 2023-09-11 19:59:55

img

Beberapa Pemikiran mengenai Logik Dagangan Futures Mata Wang Digital

Senario masalah

Untuk masa yang lama, masalah kelewatan data antara muka API kedudukan bursa mata wang digital selalu mengganggu saya. Saya belum menemui cara yang betul untuk menangani masalah ini. Izinkan saya menghasilkan semula adegan masalah. Biasanya, pesanan harga pasaran yang disediakan oleh pertukaran kontrak sebenarnya adalah harga lawan, jadi kadang-kadang tidak boleh dipercayai untuk menggunakan apa yang disebut perintah harga pasaran. Oleh itu, apabila kita menulis strategi perdagangan niaga hadapan mata wang digital, kita menggunakan pesanan had yang paling banyak. Selepas setiap pesanan diletakkan, kita perlu memeriksa kedudukan untuk melihat sama ada pesanan ditutup dan kedudukan yang sesuai dipegang. Masalahnya terletak pada kedudukan maklumat ini. Jika pesanan ditutup, pertukaran data yang dikembalikan oleh antara muka maklumat kedudukan bursa (iaitu antara muka yang sebenarnya diakses oleh lapisan bawah ketika kita mengisi pertukaran. Dapatkan kedudukan yang sangat serius) harus termasuk maklumat kedudukan baru. Walau bagaimanapun, jika kedudukan lama selesai, pertukaran pesanan akan kembali. Apabila pesanan ditempatkan dan kedudukan yang sesuai ditutup, ini mungkin menyebabkan satu masalah yang tidak dapat dijawab.

Pengalaman praktikal

Oleh kerana masalah ini, saya telah melihat strategi terbuka penuh dengan kedudukan panjang dengan gila. Mujurlah, pasaran melonjak pada masa itu, dan keuntungan terapung melebihi 10BTC. Mujurlah, pasaran meningkat dengan mendadak. Jika menurun dengan mendadak, kita boleh bayangkan hasilnya.

Penyelesaian

  • Penyelesaian 1 Strategi ini boleh direka untuk meletakkan hanya satu pesanan, dan harga pesanan adalah harga lawan dagangan semasa ditambah dengan harga bergerak yang besar, untuk mengambil kedalaman tertentu dari pesanan lawan. Kelebihan ini adalah bahawa hanya satu pesanan akan diletakkan, dan ia tidak akan dinilai berdasarkan maklumat kedudukan. Ini dapat mengelakkan masalah pesanan berulang, tetapi kadang-kadang meletakkan pesanan boleh mencetuskan mekanisme had harga bursa apabila perubahan harga agak besar, dan mungkin untuk meningkatkan harga bergerak dan masih gagal membuat perjanjian, dengan itu kehilangan peluang.

  • Penyelesaian 2 Dengan fungsi pesanan harga pasaran bursa, harga dipindahkan ke - 1 di FMZ sebagai pesanan harga pasaran.

  • Penyelesaian 3 Kami masih menggunakan logik dagangan sebelumnya dan meletakkan pesanan dengan pesanan had harga, tetapi kami menambah beberapa pengesanan dalam logik dagangan untuk cuba menyelesaikan masalah yang disebabkan oleh kelewatan data kedudukan. Semak sama ada pesanan telah hilang secara langsung dari senarai pesanan yang menunggu tanpa pembatalan (ada dua kemungkinan untuk hilang dari senarai pesanan yang menunggu: 1. Pembatalan dan 2. Diisi). Jika situasi seperti itu dikesan, dan kuantiti pesanan yang diletakkan lagi adalah sama dengan pesanan terakhir, penting untuk diperhatikan sama ada data kedudukan tertunda. Biarkan program memasukkan logik menunggu untuk mendapatkan semula maklumat kedudukan, atau bahkan terus mengoptimumkan dan meningkatkan jumlah masa menunggu untuk mencetuskan masa menunggu, jika melebihi bilangan masa kedudukan tertentu, ia menunjukkan bahawa kelewatan data antara muka adalah serius, yang menyebabkan logik perdagangan dihentikan.

Reka bentuk berdasarkan penyelesaian 3

// Parameters
/*
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);
            }
            // Check directBreak and the position remains unchanged
            if (preNeedOpen == needOpen && directBreak) {
                Log("Suspected position data is delayed, wait for 30 seconds", "#FF0000")
                Sleep(30000)
                nowPosition = GetPosition(e, contractType, direction);
                if (nowPosition) {
                    needOpen = opAmount - (nowPosition.Amount - initAmount);
                }
                /*
                timeoutCount++
                if (timeoutCount > 10) {
                    Log("Suspected position is delayed for 10 consecutive times, and the order is failed!", "#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, "open long positions", contractType, ticker);
        } else {
            orderId = e.Sell(ticker.Buy - SlidePrice, amount, "open short positions", 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, "close long positions", contractType, ticker);
        } else if (position.Type == PD_SHORT) {
            e.SetDirection("closesell");
            e.Buy(ticker.Sell + SlidePrice, amount, "close short positions", 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

Antara muka templat dipanggil dengan cara yang sama seperti$.OpenLong, $.CoverLongdalam fungsi utama di atas. Templat ini adalah versi beta, dan anda dialu-alukan untuk membuat cadangan. Kami akan terus mengoptimumkannya supaya kita boleh menangani masalah kelewatan data kedudukan.


Berkaitan

Lebih lanjut