Sumber daya yang dimuat... Pemuatan...

Strategi Trading Frekuensi Tinggi Komoditas Berjangka yang ditulis oleh C++

Penulis:Kebaikan, Dibuat: 2020-05-22 15:28:11, Diperbarui: 2023-11-02 19:54:28

img

Penny Jump Komoditas Futures High Frequency Trading Strategy ditulis oleh C++

Ringkasan

Pasar adalah medan perang, pembeli dan penjual selalu dalam permainan, yang juga merupakan tema abadi dari bisnis perdagangan.

Klasifikasi strategi frekuensi tinggi

Dalam perdagangan frekuensi tinggi, ada dua jenis strategi utama. Strategi sisi pembeli dan strategi sisi penjual. Strategi sisi penjual biasanya merupakan strategi pembuatan pasar, dan kedua sisi strategi ini adalah lawan. Misalnya, strategi pembeli arbitrase frekuensi tinggi untuk meratakan semua fenomena yang tidak wajar di pasar dengan kecepatan tercepat, mengambil inisiatif untuk menyerang harga dengan cepat, atau makan harga yang salah dari pembuat pasar lainnya.

Ada juga cara untuk menganalisis data historis atau aturan pemesanan pasar, untuk mengirim pesanan tertunda dengan harga yang tidak masuk akal sebelumnya, dan untuk mengirim pesanan penarikan dengan perubahan harga pasar yang cepat. Strategi semacam itu umum dalam pembuatan pasar pasif, setelah pesanan tertunda dieksekusi, dan setelah keuntungan tertentu atau setelah mencapai kondisi stop-loss, posisi akan ditutup. Strategi pembuatan pasar pasif biasanya tidak memerlukan terlalu banyak kecepatan, tetapi membutuhkan logika dan struktur strategi yang kuat.

Apa strategi Penny Jump?

Penny Jump diterjemahkan ke dalam bahasa Inggris adalah arti dari kenaikan harga mikro. Prinsipnya adalah untuk melacak harga beli dan harga jual pasar. Kemudian, sesuai dengan harga pasar, ditambah atau dikurangi kenaikan harga mikro dari harga pelacakan, jelas bahwa ini adalah strategi perdagangan pasif, itu milik strategi pembuatan pasar sisi penjual. Model bisnis dan logisannya adalah untuk melakukan transaksi bilateral pada pesanan batas yang terdaftar di bursa untuk memberikan likuiditas.

Strategi pembuatan pasar membutuhkan jumlah persediaan tertentu di tangan, dan kemudian diperdagangkan baik di sisi pembeli maupun penjual. Pendapatan utama dari strategi ini adalah pengembalian biaya komisi yang disediakan oleh bursa, serta perbedaan harga yang diperoleh dengan membeli rendah dan menjual tinggi.

Prinsip strategi Penny Jump

Kami tahu bahwa ada banyak investor ritel di pasar perdagangan, dan juga ada banyak investor besar, seperti: hot money, dana publik, dana swasta, dan sebagainya. investor ritel biasanya memiliki dana yang lebih sedikit, pesanan mereka memiliki dampak yang sangat kecil di pasar, mereka dapat dengan mudah membeli dan menjual target perdagangan kapan saja.

Jika investor besar ingin membeli 500 lot minyak mentah, tidak ada begitu banyak pesanan dengan harga saat ini untuk dijual, dan investor tidak ingin membelinya dengan harga yang lebih tinggi. Jika mereka bersikeras untuk mengirim pesanan pembelian dengan harga saat ini, Biaya titik slippage akan terlalu tinggi. oleh karena itu, ia harus mengirim pesanan yang sedang menunggu dengan harga yang diinginkan. Semua peserta di pasar akan melihat pesanan pembelian hugh yang menunjukkan harga tertentu.

Karena pesanan yang sangat besar, itu terlihat canggung di pasar, kadang-kadang kita menyebutnya "pesanan gajah".

Selling Price 400.3, Order volume 50; buying price 400.1, Order volume 10. 

Tiba-tiba gajah yang rumit ini melompat ke pasar, dan harga penawaran dikirim pada harga 400.1.

Selling Price 400.3, Order volume 50; Buying price 400.1, Order volume 510.

Pedagang semua tahu bahwa jika ada sejumlah besar pesanan yang tertunda pada harga tertentu, maka harga ini akan membentuk support (atau resistance) yang kuat.

Selling Price 400.3, Order volume 50; Buying price 400.2, Order volume 1,

harga 400.1 menjadi Buying 2 harga dalam kedalaman buku order. kemudian jika harga naik ke 400.3, pedagang frekuensi tinggi akan mendapatkan keuntungan 0,1.

Bahkan jika harga tidak naik, dalam posisi membeli 2, masih ada gajah yang memegang harga, dan dapat dengan cepat dijual kembali ke gajah dengan harga 400.1. Ini adalah gagasan umum dari strategi Penny Jump. Logikanya sesederhana ini, dengan memantau status pesanan pasar, untuk berspekulasi niat lawan, dan kemudian memimpin dalam membangun posisi yang menguntungkan, dan akhirnya mendapatkan keuntungan dari spread kecil dalam waktu singkat. Untuk gajah ini, karena ia menggantung sejumlah besar pesanan pembelian di pasar, ia mengekspos niat dagangnya, dan secara alami menjadi target yang diburu oleh pedagang frekuensi tinggi.

Penny Jump pelaksanaan strategi

Pertama, amati peluang perdagangan dengan probabilitas pasar yang sangat rendah, dan buat strategi yang sesuai sesuai dengan logika perdagangan. Jika logika itu kompleks, Anda perlu menggunakan pengetahuan matematika yang ada, gunakan model untuk menggambarkan sifat fenomena irasional sebanyak mungkin, dan meminimalkan overfit. Selain itu, itu harus diverifikasi oleh mesin backtest yang dapat memenuhi prinsip Price first then Volume first. Untungnya, kami memiliki platform FMZ Quant yang saat ini mendukung mode backtesting ini.

Apa artinya mendukung Price first then Volume first backtest engine? Anda dapat memahaminya sebagai: Anda mengirim pesanan tertunda pada 400.1 untuk membeli, hanya ketika harga jual dalam kedalaman buku pesanan adalah 400.1 atau lebih rendah, pesanan tertunda Anda dapat ditutup.

Volume first adalah versi yang ditingkatkan dari price first. Ini adalah kedua prioritas harga dan waktu pertama. Bisa dikatakan bahwa mode pencocokan ini persis sama dengan model pertukaran. Dengan menghitung jumlah pesanan yang sedang menunggu, dinilai apakah pesanan yang sedang menunggu saat ini mencapai kondisi transaksi pasif untuk mewujudkan transaksi volume, sehingga mencapai simulasi nyata dari lingkungan pasar nyata.

Selain itu, beberapa pembaca mungkin menemukan bahwa strategi Penny Jump membutuhkan peluang perdagangan pasar, yaitu kebutuhan pasar memiliki setidaknya dua hop kesenjangan harga. Dalam keadaan normal, kontrak perdagangan utama komoditas berjangka relatif sibuk. Perbedaan antara Beli 1 dan Menjual 1hop adalah bahwa hampir tidak ada peluang perdagangan. Jadi kita menempatkan energi kita pada kontrak sub-primary di mana perdagangan tidak terlalu aktif. Jenis kontrak perdagangan ini kadang-kadang memiliki dua atau bahkan tiga hop peluang.

img

Menjual 1 harga 2225 dengan volume 551, Membeli 1 harga 2223 dengan volume 565, melihat ke bawah selama beberapa detik. Setelah ini terjadi, itu akan menghilang setelah beberapa tik. Dalam hal ini, kita menganggap pasar sebagai koreksi diri. Apa yang harus kita lakukan adalah mengejar ketinggalan. Sebelum pasar secara aktif mengoreksinya. jika kita melakukannya secara manual, itu tidak mungkin, dengan bantuan perdagangan otomatis, kita dapat membuatnya mungkin.

Dua hop situasi perbedaan harga muncul sangat sering terjadi, tetapi tiga hop adalah yang paling aman, tetapi tiga hop jarang terjadi, sehingga frekuensi perdagangan terlalu rendah.

Selanjutnya, kita mengamati perbedaan antara Selling 1 Buying 1 dan Buying 1 Selling 1 sekarang. Untuk mengisi kesenjangan harga antara pasar, jika kecepatan cukup cepat, dapat ditempatkan di garis depan pesanan lain. Juga, waktu pemegang posisi sangat singkat, dengan logika perdagangan ini, setelah realisasi strategi, ambil MA909 sebagai contoh, tes pasar nyata merekomendasikan Esunny bukan antarmuka CTP, mekanisme perubahan posisi dan situasi dana untuk Esunny adalah dengan data push, sangat cocok untuk perdagangan frekuensi tinggi.

Kode Strategi

Setelah membersihkan logika trading, kita bisa menggunakan kode untuk mencapainya. karena platform FMZ Quant menggunakan C++ contoh strategi menulis terlalu sedikit, di sini kita menggunakan C++ untuk menulis strategi ini, yang nyaman bagi semua orang untuk belajar, dan ragamnya adalah komoditas berjangka. pertama terbuka:fmz.com> Login > Dashboard > library strategi > New Strategy > Klik menu drop-down di pojok kiri atas > Pilih C ++ untuk mulai menulis strategi, perhatikan komentar dalam kode di bawah ini.

  • Langkah 1: Pertama-tama membangun kerangka strategi, di mana kelas HFT dan fungsi utama didefinisikan. Baris pertama dalam fungsi utama adalah untuk menghapus log. Tujuan dari ini adalah untuk menghapus informasi log yang sebelumnya berjalan setiap kali strategi dihidupkan kembali. Baris kedua adalah untuk menyaring beberapa pesan kesalahan yang tidak diperlukan, seperti keterlambatan jaringan dan beberapa tip muncul, sehingga log hanya mencatat informasi penting dan terlihat lebih rapi; baris ketiga adalah untuk mencetak pesan Init OK, yang berarti bahwa program telah dimulai. baris keempat adalah untuk membuat objek sesuai dengan kelas HFT, dan nama objek adalah hft; baris kelima program memasuki loop sementara, dan selalu mengeksekusi loop dalam metode hft, dapat dilihat bahwa metode Loop adalah logika dari program ini. Baris 6 adalah pesan inti. Di bawah bukti lain, program tidak akan mengeksekusi baris 6, jika program telah berakhir, metode program akan berakhir.

Selanjutnya, mari kita lihat kelas HFT, yang memiliki lima metode. Metode pertama adalah metode konstruksi; metode kedua adalah untuk mendapatkan hari saat ini dari minggu untuk menentukan apakah itu adalah garis K baru; metode ketiga terutama untuk membatalkan semua pesanan yang belum terisi, dan mendapatkan informasi Posisi terperinci, karena sebelum pesanan ditempatkan, harus terlebih dahulu menentukan status posisi saat ini; metode keempat terutama digunakan untuk mencetak beberapa informasi, untuk strategi ini, metode ini bukan yang utama; yang paling penting adalah metode kelima, Metode ini terutama bertanggung jawab untuk memproses logika perdagangan dan menempatkan pesanan.

/ / Define the HFT class
Class HFT {
     Public:
         HFT() {
             // Constructor
         }
        
         Int getTradingWeekDay() {
             // Get the current day of the week to determine if it is a new K line
         }
        
         State getState() {
             / / Get order data
         }

         Void stop() {
             // Print orders and positions
         }
        
         Bool Loop() {
             // Strategy logic and placing orders
         }
};

// main function
Void main() {
     LogReset(); // clear the log
     SetErrorFilter("ready|timeout"); // Filter error messages
     Log("Init OK"); // Print the log
     HFT hft; // Create HFT object
     While (hft.Loop()); // enter loop
     Log("Exit"); // Program exits, prints the log
}

Jadi mari kita lihat bagaimana masing-masing metode dalam kelas HFT ini diimplementasikan, dan bagaimana metode Loop yang paling inti bekerja. Dari atas ke bawah, kita akan mengimplementasikan implementasi spesifik dari setiap metode satu per satu, dan Anda akan menemukan bahwa strategi frekuensi tinggi asli sangat sederhana. Sebelum berbicara tentang kelas HFT, kita pertama kali mendefinisikan beberapa variabel global untuk menyimpan hasil perhitungan objek hft. Mereka adalah: menyimpan status pesanan, status posisi, memegang posisi panjang, memegang posisi pendek, harga beli, jumlah pembelian, harga jual, jumlah penjualan. Silakan lihat kode di bawah ini:

/ / Define the global enumeration type State
Enum State {
     STATE_NA, // store order status
     STATE_IDLE, // store position status
     STATE_HOLD_LONG, // store long position directions
     STATE_HOLD_SHORT, // store short position direction
};

/ / Define global floating point type variable
Typedef struct {
     Double bidPrice; // store the buying price
     Double bidAmount; // store the buying amount
     Double askPrice; // store the selling price
     Double askAmount; // store the selling amount
} Book;

Dengan variabel global di atas, kita dapat menyimpan hasil yang dihitung oleh objek hft secara terpisah, yang nyaman untuk panggilan berikutnya oleh program. Selanjutnya kita akan berbicara tentang implementasi spesifik dari setiap metode di kelas HFT. Pertama, metode HFT pertama adalah konstruktor yang memanggil metode getTradingWeekDay kedua dan mencetak hasilnya ke log. Metode getTradingWeekDay kedua mendapatkan hari saat ini dari minggu untuk menentukan apakah itu adalah K baris baru.

Selanjutnya, mari kita mendapatkan semua perintah pertama, mengembalikan hasil adalah array normal, kemudian melintasi array ini, satu per satu untuk membatalkan urutan, kemudian mendapatkan data posisi, mengembalikan array, dan kemudian melintasi Array ini, mendapatkan informasi posisi terperinci, termasuk: arah, posisi, kemarin atau posisi saat ini, dll, dan akhirnya mengembalikan hasilnya; metode berhenti keempat adalah untuk mencetak informasi; kode adalah sebagai berikut:

Public:
    // Constructor
    HFT() {
        _tradingDay = getTradingWeekDay();
        Log("current trading weekday", _tradingDay);
    }
    
    // Get the current day of the week to determine if it is a new K line
    Int getTradingWeekDay() {
        Int seconds = Unix() + 28800; // get the timestamp
        Int hour = (seconds/3600)%24; // hour
        Int weekDay = (seconds/(60*60*24))%7+4; // week
        If (hour > 20) {
            weekDay += 1;
        }
        Return weekDay;
    }
    
    / / Get order data
    State getState() {
        Auto orders = exchange.GetOrders(); // Get all orders
        If (!orders.Valid || orders.size() == 2) { // If there is no order or the length of the order data is equal to 2
            Return STATE_NA;
        }
        
        Bool foundCover = false; // Temporary variable used to control the cancellation of all unexecuted orders
        // Traverse the order array and cancel all unexecuted orders
        For (auto &order : orders) {
            If (order.Id == _coverId) {
                If ((order.Type == ORDER_TYPE_BUY && order.Price < _book.bidPrice - _toleratePrice) ||
                    (order.Type == ORDER_TYPE_SELL && order.Price > _book.askPrice + _toleratePrice)) {
                    exchange.CancelOrder(order.Id, "Cancel Cover Order"); // Cancel order based on order ID
                    _countCancel++;
                    _countRetry++;
                } else {
                    foundCover = true;
                }
            } else {
                exchange.CancelOrder(order.Id); // Cancel order based on order ID
                _countCancel++;
            }
        }
        If (foundCover) {
            Return STATE_NA;
        }
        
        // Get position data
        Auto positions = exchange.GetPosition(); // Get position data
        If (!positions.Valid) { // if the position data is empty
            Return STATE_NA;
        }

        // Traverse the position array to get specific position information
        For (auto &pos : positions) {
            If (pos.ContractType == Symbol) {
                _holdPrice = pos.Price;
                _holdAmount = pos.Amount;
                _holdType = pos.Type;
                Return pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT;
            }
        }
        Return STATE_IDLE;
    }
    
    // Print orders and positions information
    Void stop() {
        Log(exchange.GetOrders()); // print order
        Log(exchange.GetPosition()); // Print position
        Log("Stop");
    }

Akhirnya, kita fokus pada bagaimana fungsi Loop mengontrol logika strategi dan urutan. Jika Anda ingin melihat lebih hati-hati, Anda dapat merujuk pada komentar dalam kode. Pertama menentukan apakah transaksi CTP dan server pasar terhubung; kemudian mendapatkan saldo akun yang tersedia dan mendapatkan jumlah minggu; kemudian mengatur kode varietas yang akan diperdagangkan, dengan memanggil fungsi resmi FMZ Set QuantContractType, dan dapat menggunakan fungsi ini untuk mengembalikan rincian varietas perdagangan; kemudian memanggil fungsi GetDepth untuk mendapatkan data kedalaman pasar saat ini. Data kedalaman termasuk: harga beli, volume beli, harga jual, volume jual, dll, dan kita menyimpannya dengan variabel, karena akan digunakan nanti; Kemudian output data ini ke bilah status port untuk memudahkan pengguna untuk melihat status pasar saat ini; kode adalah sebagai berikut:

// Strategy logic and placing order
Bool Loop() {
    If (exchange.IO("status") == 0) { // If the CTP and the quote server are connected
        LogStatus(_D(), "Server not connect ...."); // Print information to the status bar
        Sleep(1000); // Sleep 1 second
        Return true;
    }
    
    If (_initBalance == 0) {
        _initBalance = _C(exchange.GetAccount).Balance; // Get account balance
    }
    
    Auto day = getTradingWeekDay(); // Get the number of weeks
    If (day != _tradingDay) {
        _tradingDay = day;
        _countCancel = 0;
    }
    
    // Set the futures contract type and get the contract specific information
    If (_ct.is_null()) {
        Log(_D(), "subscribe", Symbol); // Print the log
        _ct = exchange.SetContractType(Symbol); // Set futures contract type
        If (!_ct.is_null()) {
            Auto obj = _ct["Commodity"]["CommodityTickSize"];
            Int volumeMultiple = 1;
            If (obj.is_null()) { // CTP
                Obj = _ct["PriceTick"];
                volumeMultiple = _ct["VolumeMultiple"];
                _exchangeId = _ct["ExchangeID"];
            } else { // Esunny
                volumeMultiple = _ct["Commodity"]["ContractSize"];
                _exchangeId = _ct["Commodity"]["ExchangeNo"];
            }
            If (obj.is_null() || obj <= 0) {
                Panic("PriceTick not found");
            }
            If (_priceTick < 1) {
                exchange.SetPrecision(1, 0); // Set the decimal precision of the price and the quantity of the order.
            }
            _priceTick = double(obj);
            _toleratePrice = _priceTick * TolerateTick;
            _ins = _ct["InstrumentID"];
            Log(_ins, _exchangeId, "PriceTick:", _priceTick, "VolumeMultiple:", volumeMultiple); // print the log
        }
        Sleep(1000); // Sleep 1 second
        Return true;
    }
    
    // Check orders and positions to set status
    Auto depth = exchange.GetDepth(); // Get depth data
    If (!depth.Valid) { // if no depth data is obtained
        LogStatus(_D(), "Market not ready"); // Print status information
        Sleep(1000); // Sleep 1 second
        Return true;
    }
    _countTick++;
    _preBook = _book;
    _book.bidPrice = depth.Bids[0].Price; // "Buying 1" price
    _book.bidAmount = depth.Bids[0].Amount; // "Buying 1" amount
    _book.askPrice = depth.Asks[0].Price; // "Selling 1" price
    _book.askAmount = depth.Asks[0].Amount; // "Selling 1" amount
    // Determine the state of the port data assignment
    If (_preBook.bidAmount == 0) {
        Return true;
    }
    Auto st = getState(); // get the order data
    
    // Print the port data to the status bar
    LogStatus(_D(), _ins, "State:", st,
                "Ask:", depth.Asks[0].Price, depth.Asks[0].Amount,
                "Bid:", depth.Bids[0].Price, depth.Bids[0].Amount,
                "Cancel:", _countCancel,
                "Tick:", _countTick);
}

setelah melakukan begitu banyak, kita akhirnya dapat menempatkan pesanan. Sebelum perdagangan, pertama kita menilai status posisi holding saat ini dari program (tidak ada posisi holding, pesanan posisi panjang, pesanan posisi pendek), di sini kita menggunakan jika...jika...jika kontrol logika. Mereka sangat sederhana, Jika tidak ada posisi holding, posisi akan dibuka sesuai dengan kondisi logika. Jika ada posisi holding, posisi akan ditutup sesuai dengan kondisi logika. Untuk memudahkan semua orang memahami, kita menggunakan tiga paragraf untuk menjelaskan logika, Untuk bagian posisi pembukaan:

Pertama mendeklarasikan variabel Boolean, kita menggunakannya untuk mengontrol posisi penutupan; selanjutnya kita perlu mendapatkan informasi akun saat ini, dan mencatat nilai keuntungan, kemudian menentukan status pesanan penarikan, jika jumlah penarikan melebihi maksimum yang ditetapkan, cetak informasi terkait dalam log; kemudian hitung nilai absolut bid saat ini dan perbedaan harga penawaran untuk menentukan apakah ada lebih dari 2 hop antara harga penawaran saat ini dan harga permintaan.

Selanjutnya, kita mendapatkan harga Beli 1 dan harga Jual 1, jika harga beli sebelumnya lebih besar dari harga beli saat ini, dan volume penjualan saat ini lebih kecil dari volume pembelian, itu berarti bahwa harga Beli 1 hilang. harga pembukaan posisi panjang dan jumlah pesanan ditetapkan; sebaliknya, jika harga jual sebelumnya lebih rendah dari harga jual saat ini, dan volume pembelian saat ini lebih kecil dari Volume penjualan membuktikan bahwa harga Jual 1 hilang, harga pembukaan posisi pendek dan jumlah pesanan ditetapkan; pada akhirnya, posisi panjang dan pesanan posisi pendek memasuki pasar pada saat yang sama. kode spesifik adalah sebagai berikut:

Bool forceCover = _countRetry >= _retryMax; // Boolean value used to control the number of closings
If (st == STATE_IDLE) { // if there is no holding position
    If (_holdAmount > 0) {
        If (_countRetry > 0) {
            _countLoss++; // failure count
        } else {
            _countWin++; // success count
        }
        Auto account = exchange.GetAccount(); // Get account information
        If (account.Valid) { // If get account information
            LogProfit(_N(account.Balance+account.FrozenBalance-_initBalance, 2), "Win:", _countWin, "Loss:", _countLoss); // Record profit value
        }
    }
    _countRetry = 0;
    _holdAmount = 0;
    
    // Judging the status of withdrawal
    If (_countCancel > _cancelMax) {
        Log("Cancel Exceed", _countCancel); // Print the log
        Return false;
    }

    Bool canDo = false; // temporary variable
    If (abs(_book.bidPrice - _book.askPrice) > _priceTick * 1) { // If there is more than 2 hops between the current bid and ask price
        canDo = true;
    }
    If (!canDo) {
        Return true;
    }
    
    Auto bidPrice = depth.Bids[0].Price; // Buying 1 price
    Auto askPrice = depth.Asks[0].Price; // Selling 1 price
    Auto bidAmount = 1.0;
    Auto askAmount = 1.0;
    
    If (_preBook.bidPrice > _book.bidPrice && _book.askAmount < _book.bidAmount) { // If the previous buying price is greater than the current buying price and the current selling volume is less than the buying volume
        bidPrice += _priceTick; // Set the opening long position price
        bidAmount = 2; // set the opening long position volume
    } else if (_preBook.askPrice < _book.askPrice && _book.bidAmount < _book.askAmount) { // If the previous selling price is less than the current selling price and the current buying volume is less than the selling volume
        askPrice -= _priceTick; // set the opening short position volume
        askAmount = 2; // set the opening short position volume
    } else {
        Return true;
    }
    Log(_book.bidPrice, _book.bidAmount, _book.askPrice, _book.askAmount); // Print current market data
    exchange.SetDirection("buy"); // Set the order type to buying long
    exchange.Buy(bidPrice, bidAmount); // buying long and open position
    exchange.SetDirection("sell"); // Set the order type to selling short
    exchange.Sell(askPrice, askAmount); // short sell and open position
}

Selanjutnya, kita akan berbicara tentang cara menutup posisi panjang, pertama-tama mengatur jenis order sesuai dengan status posisi saat ini, dan kemudian mendapatkan harga Selling 1. Jika harga Selling 1 saat ini lebih besar dari harga pembukaan pembelian panjang, atur harga posisi panjang penutupan. Jika harga selling 1 saat ini kurang dari harga pembukaan posisi panjang, maka atur ulang variabel kuantitas penutupan menjadi benar, lalu tutup semua posisi panjang. Bagian pengkodean seperti di bawah:

Else if (st == STATE_HOLD_LONG) { // if holding long position
     exchange.SetDirection((_holdType == PD_LONG && _exchangeId == "SHFE") ? "closebuy_today" : "closebuy"); // Set the order type, and close position
     Auto sellPrice = depth.Asks[0].Price; // Get "Selling 1" price
     If (sellPrice > _holdPrice) { // If the current "selling 1" price is greater than the long position opening price
         Log(_holdPrice, "Hit #ff0000"); // Print long position opening price 
         sellPrice = _holdPrice + ProfitTick; // Set closing long position price
     } else if (sellPrice < _holdPrice) { // If the current "selling 1" price is less than the long position opening price
         forceCover = true;
     }
     If (forceCover) {
         Log("StopLoss");
     }
     _coverId = exchange.Sell(forceCover ? depth.Bids[0].Price : sellPrice, _holdAmount); // close long position
     If (!_coverId.Valid) {
         Return false;
     }
}

Akhirnya, mari kita lihat cara menutup posisi pendek. Prinsipnya adalah kebalikan dari posisi panjang penutupan yang disebutkan di atas. Pertama, sesuai dengan status posisi saat ini, atur jenis order, dan kemudian dapatkan harga Beli 1, jika harga Beli 1 saat ini kurang dari harga pembukaan posisi pendek, harga posisi pendek penutupan akan ditetapkan. Jika harga Beli 1 saat ini lebih besar dari harga posisi pendek pembukaan, atur ulang variabel kuantitas penutupan menjadi benar, lalu tutup semua posisi pendek.

Else if (st == STATE_HOLD_SHORT) { // if holding short position
     exchange.SetDirection((_holdType == PD_SHORT && _exchangeId == "SHFE") ? "closesell_today" : "closesell"); // Set the order type, and close position
     Auto buyPrice = depth.Bids[0].Price; // Get "buying 1" price
     If (buyPrice < _holdPrice) { // If the current "buying 1" price is less than the opening short position price
         Log(_holdPrice, "Hit #ff0000"); // Print the log
         buyPrice = _holdPrice - ProfitTick; // Set the close short position price
     } else if (buyPrice > _holdPrice) { // If the current "buying 1" price is greater than the opening short position price
         forceCover = true;
     }
     If (forceCover) {
         Log("StopLoss");
     }
     _coverId = exchange.Buy(forceCover ? depth.Asks[0].Price : buyPrice, _holdAmount); // close short position
     If (!_coverId.Valid) {
         Return false;
     }
}

Di atas adalah analisis lengkap dari strategi ini.https://www.fmz.com/strategy/163427) untuk menyalin kode sumber strategi lengkap tanpa mengkonfigurasi lingkungan backtest di FMZ Quant.

Hasil tes balik

img

Logika perdagangan

img

Pernyataan Strategi

Untuk memuaskan rasa ingin tahu perdagangan frekuensi tinggi dan untuk melihat hasilnya dengan lebih jelas, biaya transaksi lingkungan backtest strategi ini ditetapkan menjadi 0, yang mengarah ke logika kecepatan cepat yang sederhana. jika Anda ingin menutupi biaya transaksi untuk mencapai profitabilitas di pasar nyata. Lebih banyak optimasi diperlukan. Seperti menggunakan aliran pesanan untuk melakukan prediksi jangka pendek untuk meningkatkan tingkat kemenangan, ditambah pengembalian biaya pertukaran, Untuk mencapai strategi yang menguntungkan yang berkelanjutan, ada banyak buku tentang perdagangan frekuensi tinggi. Saya harap semua orang dapat berpikir lebih banyak dan pergi ke pasar nyata daripada hanya tinggal pada prinsipnya.

Tentang kami

FMZ Quant adalah tim yang didorong murni oleh teknologi yang menyediakan mekanisme backtest yang tersedia yang sangat efisien untuk penggemar perdagangan kuantitatif.


Berkaitan

Lebih banyak