Our professional Customer Supports waiting for you! Contact now
Everyday: 09:00am - 10:00pm
By Invezto in Trading Insight on 14 Nov, 2025

Berhenti Cek Order Pakai `OnTick()`! Lo Kuno! Ini Cara Pakai `OnTradeTransaction` di MQL5 Biar EA Lo Nggak Kayak Siput

Parafrase Artikel MQL5 OnTradeTransaction

Berhenti Cek Order Pakai `OnTick()`! Lo Kuno! Ini Cara Pakai `OnTradeTransaction` di MQL5 Biar EA Lo Nggak Kayak Siput

Mari kita mulai dengan sesi terapi dan pengakuan dosa. Kalau Anda seorang *coder* Expert Advisor (EA) yang hijrah dari MQL4 ke MQL5, atau (lebih parah lagi) belajar MQL5 tapi masih bawa "kebiasaan buruk" dari MQL4, kemungkinan besar Anda melakukan dosa kardinal ini: Anda mengecek status order dan posisi di dalam fungsi `OnTick()`.

Ayo ngaku aja. Anda pasti punya kode yang kira-kira begini:

void OnTick() {
    // ...logika sinyal...
    if (SinyalBuy) {
        if (PositionsTotal() == 0) { // Nah, ini dia dosanya
            trade.Buy(...);
        }
    }
}

Terlihat polos? Terlihat logis? SALAH. Ini adalah praktik barbar. Ini adalah resep untuk bencana. Ini sama kunonya dengan Anda mengecek email setiap 5 detik dengan menekan tombol "Refresh" di browser, padahal Anda bisa menunggu notifikasi *push* datang sendiri.

Di setiap *tick*—yang di pasar normal bisa terjadi 5-20 kali per DETIK—EA Anda yang "polos" itu menginterogasi server: "Gue punya posisi nggak? Gue punya posisi nggak? Gue punya posisi nggak? Order gue udah dieksekusi? Order gue gimana?" Bayangkan betapa borosnya itu! Belum lagi masalah *timing* dan kondisi *race condition* (balapan) yang akan kita bahas.

Artikel MQL5 (No. 15352) yang kita "bedah" ini pada dasarnya adalah "obat" dari penyakit kuno ini. MetaQuotes akhirnya memberi kita alat yang canggih, alat yang "dewasa", untuk menangani aktivitas trading. Namanya adalah *Event Handling*, dan bintang utamanya adalah `OnTrade()` dan (yang lebih gila lagi) `OnTradeTransaction()`.

Jika Anda serius ingin EA Anda responsif, cepat, efisien, dan tidak dibenci oleh server broker Anda, buang kebiasaan `OnTick()` Anda ke tempat sampah. Mari kita pelajari cara kerja yang "waras".


Dosa Warisan MQL4: Kenapa `OnTick()` Adalah Ide Buruk (Banget)

Sebelum kita ke solusi, Anda harus paham dulu kenapa cara lama itu adalah sampah. Anda harus merasakan "sakit"-nya dulu biar Anda mau berubah.

1. CPU Anda Menangis (Beban Kinerja Gila-gilaan)

Setiap. Satu. *Tick*. EA Anda menjalankan *loop* untuk mengecek semua order dan posisi. Jika Anda punya 10 EA di 10 *chart* berbeda, bayangkan beban CPU Anda. Terminal MT5 Anda akan "ngos-ngosan" hanya untuk melakukan pengecekan berulang-ulang yang 99.9% tidak ada gunanya, karena 99.9% *tick* itu tidak ada hubungannya dengan perubahan status *trade* Anda.

Analogi sarkasnya: Anda menyuruh seorang asisten untuk lari bolak-balik ke kantor pos setiap detik hanya untuk mengecek apakah ada surat baru. Padahal Anda bisa menyuruh dia duduk manis dan baru bereaksi kalau pak pos *datang mengantar surat*. `OnTick()` adalah asisten bodoh itu. *Event Handler* adalah asisten yang pintar.

2. "Loh, Kok Order-nya Belum Masuk?" (Masalah Fatal Asinkronus)

Ini masalah yang lebih mematikan. Anda harus paham: `OrderSend()` atau `trade.Buy()` itu sifatnya ASINKRONUS (Asynchronous).

Artinya: Ketika Anda menjalankan `trade.Buy()`, fungsi itu HANYA "mengirimkan permintaan" Anda ke server. Dia tidak menunggu sampai order itu dieksekusi. Dia langsung lanjut ke baris kode berikutnya. Status eksekusinya? Mungkin 10 milidetik lagi, mungkin 500 milidetik lagi. Anda tidak tahu.

Sekarang, bayangkan skenario horor ini:

  • Tick 1: Sinyal BUY muncul. `PositionsTotal()` bilang 0. EA kirim `trade.Buy()`.
  • Tick 2 (50 milidetik kemudian): Server *belum* selesai memproses order Anda. `OnTick()` jalan lagi. Sinyal BUY masih ada. EA cek `PositionsTotal()`. Hasilnya? Masih 0! (Karena order tadi belum dieksekusi). Apa yang EA bodoh Anda lakukan? Dia kirim `trade.Buy()` LAGI!
  • Tick 3 (100 milidetik kemudian): Sama. `PositionsTotal()` masih 0. EA kirim `trade.Buy()` LAGI!

Dalam sepersekian detik, Anda sudah mengirim 3 order untuk sinyal yang sama. Anda *spamming* server. Ini adalah mimpi buruk yang disebut *race condition*. Anda akan berakhir dengan 3 posisi terbuka (jika broker mengizinkan), atau serangkaian *error* "Trade context is busy" yang membuat EA Anda lumpuh.

3. Server Broker Membenci Anda (Trade Context Busy)

Setiap kali Anda mengirim permintaan *trade* (`OrderSend`, `OrderModify`, dll.), Anda "mengunci" *trade context* Anda di server. Server sedang sibuk memproses permintaan Anda. Jika pada saat bersamaan (misal di *tick* berikutnya) EA Anda yang barbar itu mengirim permintaan baru, server akan menolaknya mentah-mentah dengan *error* 10019 (`TRADE_RETCODE_CONTEXT_BUSY`).

Menggunakan `OnTick()` untuk mengelola *trade* adalah cara paling gampang untuk masuk ke dalam *loop* neraka *error* ini. EA Anda akan terus mencoba, terus ditolak, dan akhirnya melewatkan momen eksekusi yang tepat.


Selamat Datang di Dunia Per-Event-an: `OnTrade()` vs `OnTradeTransaction()`

Oke, cukup ceramahnya. MetaQuotes tahu masalah ini. Karena itulah di MQL5, mereka memperkenalkan "Asisten Pintar" itu. Mereka memberi kita dua *event handler* (fungsi) khusus yang akan "dipanggil" atau "diberi notifikasi" oleh terminal *hanya jika* ada sesuatu yang *benar-benar terjadi* pada akun trading Anda.

Ini adalah pergeseran paradigma. Dari "Aktif Mengecek" (boros) menjadi "Pasif Menunggu Notifikasi" (efisien).

Ada dua jenis notifikasi yang bisa Anda pilih:

1. Si Pemalas tapi Efisien: `OnTrade()`

Fungsi `OnTrade()` adalah notifikasi level "dasar". Dia akan dipanggil SATU KALI pada akhir dari *seluruh* rangkaian operasi trading.

Contoh: Anda mengirim order *market*. Rangkaian operasinya adalah: 1. Order dikirim, 2. Order dieksekusi (jadi *deal*), 3. Posisi Anda diperbarui, 4. Order lama dipindahkan ke *history*.

Nah, `OnTrade()` baru akan dipanggil setelah semua 4 langkah itu SELESAI. Dia akan datang dan bilang, "Bos, tadi ada operasi trading. Udah kelar. Ini laporannya."

Dia hanya memberi Anda 3 informasi (parameternya): `request` (permintaan asli Anda), `result` (hasil akhirnya), dan `order` (jika operasinya menghasilkan order). Ini berguna untuk sekadar tahu "Oh, order gue GAGAL" atau "Oh, order gue SUKSES". Tapi Anda tidak tahu detail *langkah-per-langkah*-nya.

2. Si Paling 'Kepo' dan Detail: `OnTradeTransaction()` (BINTANG UTAMANYA)

Ini dia "jagoan"-nya. Ini adalah *event handler* yang dibahas tuntas di artikel MQL5 itu. `OnTradeTransaction()` adalah "mata-mata" Anda yang ditanam langsung di server. Dia adalah *control freak* yang Anda butuhkan.

Berbeda dengan `OnTrade()` yang baru lapor setelah semua selesai, `OnTradeTransaction()` akan lapor di SETIAP LANGKAH KECIL dari sebuah operasi trading. Dia akan *live-tweet* semua yang terjadi.

Mari kita pakai contoh yang sama (order *market*):

  1. Anda kirim `trade.Buy()`.
  2. Server terima order -> **PING!** `OnTradeTransaction` dipanggil dengan Tipe: "Bos, ada order baru masuk antrian!" (`TRADE_TRANSACTION_ORDER_ADD`)
  3. Server eksekusi order itu jadi *deal* -> **PING!** `OnTradeTransaction` dipanggil dengan Tipe: "Bos, order tadi udah jadi *deal*! Ini detailnya!" (`TRADE_TRANSACTION_DEAL_ADD`)
  4. Server update *database* posisi Anda -> **PING!** `OnTradeTransaction` dipanggil dengan Tipe: "Bos, posisi Anda sudah berubah! Volumenya sekarang 0.1!" (`TRADE_TRANSACTION_POSITION`)
  5. Server pindahkan order ke *history* -> **PING!** `OnTradeTransaction` dipanggil dengan Tipe: "Bos, order lama udah gue arsipin ke *history*!" (`TRADE_TRANSACTION_HISTORY_ADD`)

Satu kali klik `trade.Buy()` Anda bisa memicu 3-5 kali panggilan `OnTradeTransaction`! Gila? Ya. Canggih? Banget! Kenapa? Karena ini SINKRON dengan server. Anda mendapatkan informasi *real-time* tepat saat server melakukannya, bukan menunggu tebakan dari `OnTick()`.


Praktek! Membedah `OnTradeTransaction` dan Tipe-Tipenya

Artikel MQL5 itu kemudian menjelaskan cara "menjinakkan" si mata-mata ini. Fungsi ini punya 3 parameter penting. Mari kita bedah dengan bahasa manusia.

void OnTradeTransaction(
    const MqlTradeTransaction& trans,
    const MqlTradeRequest& request,
    const MqlTradeResult& result
)

1. `const MqlTradeTransaction& trans` (Si Biang Gosip)

Ini adalah parameter KUNCI. Dia adalah "surat notifikasi"-nya. Di dalam `trans` ini ada semua informasi yang Anda butuhkan. Yang paling penting dari `trans` adalah `trans.type`.

`trans.type` adalah "Judul Berita"-nya. Inilah yang memberi tahu Anda "jenis" notifikasi apa yang sedang terjadi. Apakah ini notifikasi "Order Baru"? "Deal Baru"? "Posisi Berubah"?

Selain `trans.type`, di dalamnya juga ada tiket-tiket penting seperti `trans.order` (tiket order), `trans.deal` (tiket deal), dan `trans.position` (tiket posisi). Anda bisa pakai tiket ini untuk mengambil info lebih detail.

2. `const MqlTradeRequest& request` (Apa yang Anda Minta?)

Parameter ini adalah "salinan" dari permintaan *asli* yang Anda kirim. Misalnya, jika transaksi ini dipicu oleh `trade.Buy(0.1, ...)` Anda, maka `request` ini akan berisi detail permintaan itu (volume 0.1, simbol, harga, dll.).

Ini sangat berguna untuk *cross-check*. Anda bisa mengecek apakah transaksi ini benar-benar berasal dari *magic number* EA Anda (`request.magic`) atau dari EA lain (atau bahkan dari jari gatal Anda).

3. `const MqlTradeResult& result` (Gimana Hasilnya?)

Ini adalah laporan "hasil" dari permintaan yang memicu transaksi ini. Isinya adalah `result.retcode` (kode sukses atau gagal), `result.comment`, dll. Ini mirip dengan parameter di `OnTrade()`.


Struktur Kode "Waras" Menggunakan `switch(trans.type)`

Jadi, bagaimana cara menggunakannya? Anda tidak bisa membiarkan semua 3-5 notifikasi per *trade* itu tumpang tindih. Anda harus memfilternya. Caranya adalah dengan struktur `switch...case` di dalam `OnTradeTransaction` berdasarkan `trans.type`.

Ini adalah "otak" dari logika baru Anda. Anda tidak lagi bertanya "Apakah saya punya posisi?". Anda akan *diberi tahu* "Anda BARU SAJA punya posisi!"

Bayangkan kodenya seperti ini (pseudo-code):

void OnTradeTransaction(...) {
    // Pertama, filter dulu. Apakah ini dari EA kita?
    if (request.magic != MAGIC_NUMBER_SAYA) {
        return; // Bukan urusan saya, keluar.
    }

    // Oke, ini urusan saya. Sekarang, notifikasi apa ini?
    switch(trans.type) {
        // ... Di sinilah keajaiban terjadi ...
    }
}

Sekarang, mari kita isi bagian "keajaiban" itu, berdasarkan artikel MQL5.

Studi Kasus 1: Melacak Order Baru (`TRADE_TRANSACTION_ORDER_ADD`)

case TRADE_TRANSACTION_ORDER_ADD:
Ini adalah notifikasi PERTAMA. Artinya: "Bos, permintaan `OrderSend` Anda sudah diterima server dan dicatat sebagai order baru dengan tiket nomor [trans.order]. Statusnya sekarang [trans.order_type]."

Apa gunanya? Ini adalah *konfirmasi* bahwa order Anda *diterima* (bukan dieksekusi). Anda bisa menyimpan tiket ordernya (`trans.order`) ke variabel global jika Anda perlu memodifikasinya nanti. Anda bisa berhenti mencoba kirim order yang sama lagi (mengatasi *race condition*).

Studi Kasus 2: Melacak Eksekusi Aktual (`TRADE_TRANSACTION_DEAL_ADD`)

case TRADE_TRANSACTION_DEAL_ADD:
Ini dia "DAGING"-nya! Ini notifikasi yang paling Anda tunggu! Artinya: "Bos, order Anda (atau bagian dari order Anda) SUDAH DIEKSEKUSI! Ini buktinya: sebuah *deal* (transaksi) dengan tiket nomor [trans.deal]."

Apa gunanya? Ini adalah konfirmasi bahwa UANG sudah berpindah. Posisi Anda sudah *benar-benar* terbuka atau tertutup. Di sinilah Anda harusnya menjalankan logika *lanjutan* Anda. Misalnya, jika *deal* ini adalah pembukaan posisi, mungkin Anda harus segera memasang *trailing stop*. Jika *deal* ini adalah *stop loss* yang kena, mungkin Anda harus berhenti trading selama sisa hari itu. Semua logika yang bergantung pada "posisi sudah tereksekusi" harus dimulai dari sini!

Studi Kasus 3: Cek Perubahan Posisi (`TRADE_TRANSACTION_POSITION`)

case TRADE_TRANSACTION_POSITION:
Notifikasi ini memberi tahu Anda bahwa *database* posisi Anda telah diperbarui. Ini biasanya terjadi *setelah* ada `DEAL_ADD`. Dia akan bilang, "Bos, posisi Anda untuk simbol [trans.symbol] sekarang volumenya [trans.volume] lot."

Apa gunanya? Ini adalah konfirmasi akhir. Jika Anda melakukan *partial close*, Anda akan melihat volume posisi Anda berkurang di sini. Ini adalah tempat yang baik untuk memperbarui info internal EA Anda tentang posisi yang sedang terbuka.

Studi Kasus Lainnya (Yang Sering Diabaikan)

  • `TRADE_TRANSACTION_ORDER_DELETE` / `_MODIFY` / `_CANCEL`: Notifikasi saat order *pending* Anda dihapus, dimodifikasi, atau dibatalkan.
  • `TRADE_TRANSACTION_HISTORY_ADD`: Notifikasi saat order atau *deal* sudah "selesai" dan dipindahkan ke tab History.
  • `TRADE_TRANSACTION_BALANCE`: Notifikasi jika ada perubahan *balance* yang bukan dari trading (misal: deposit, withdrawal, atau komisi broker yang dipisah).

Kesimpulan: Berhentilah Jadi 'Coder Kuno', Mulai Berpikir Secara 'Event'

Jadi, begitulah. Artikel di MQL5.com itu pada dasarnya sedang meneriaki Anda untuk berhenti melakukan hal-hal bodoh dengan `OnTick()`.

Cara kuno (`OnTick()`): Anda menelepon server 20 kali per detik, "Udah? Udah? Udah? Gimana? Udah?" Ini boros, lambat, tidak akurat, dan membuat server membenci Anda.

Cara modern (`OnTradeTransaction()`): Anda memberi server sebuah *walkie-talkie* dan bilang, "Kasih tahu saya *langsung* kalau ada apa-apa, sekecil apapun itu." Ini efisien, instan, akurat, dan profesional.

Apakah `OnTradeTransaction` lebih rumit? Tentu saja! Anda harus mengelola `switch...case` yang panjang. Anda harus mengelola "state" (kondisi) EA Anda dengan lebih cerdas. Tapi imbalannya luar biasa. EA Anda akan menjadi sangat ringan, responsif secepat kilat (karena bereaksi terhadap notifikasi server, bukan tebakan *tick*), dan 100% bebas dari *race condition* dan *spamming* order.

Berhentilah menjadi "asisten bodoh" yang lari bolak-balik ke kantor pos. Jadilah "bos" yang menunggu laporan *real-time* dari "mata-mata" Anda di server.

Menguasai *event handling* seperti ini adalah salah satu langkah besar yang memisahkan *coder* amatir dari *coder* profesional. Ini baru satu dari sekian banyak kerumitan di dunia *algorithmic trading*. Kalau Anda mau diskusi lebih 'daging' tentang seluk-beluk MQL5, strategi otomatis, atau *insight* pasar yang tidak cuma di permukaan, Anda tahu harus ke mana. Follow semua akun sosial media **INVEZTO**. Jadilah *coder* yang 'sadar', bukan cuma 'bisa'.

You may also like

Related posts