Bermain JavaScript dengan orang tua - membuat mitra kecil untuk membeli dan menjual alat yang berguna untuk mengetahui mengapa itu berguna!

Penulis:Mimpi kecil, Dibuat: 2017-03-16 12:29:51, Diperbarui: 2017-10-11 10:37:54

Alat yang berguna harus tahu mengapa berguna!

Pada hari kerja, menulis strategi adalah hal yang sangat menyenangkan, dan ide-ide kosong bermunculan di editor, mungkin itu adalah hal yang akan Anda lakukan berikutnya. Satu-satunya hal yang mempengaruhi gairah ini adalah penanganan logika jual beli untuk sistem strategi trading, yang memang penting untuk penanganan modul trading ini, tetapi agak membosankan dan logika yang agak rumit.

  • Untungnya ada modul yang ditulis dengan baik yang dapat digunakan langsung (saya telah menggunakannya di beberapa artikel sebelumnya), tetapi selain menggunakan dan memahami bagaimana cara kerjanya, saya mengomentari kode:

/* Interval Interval re-test gagal (millisecond) Format numerik (number) 500 SlideTick Nomor titik harga geser ((jumlah bulat) Jenis angka ((nomor) 1) RiskControl mengaktifkan kontrol angin Boll (true/false) false MaxTrade@RiskControl Jumlah transaksi paling banyak dalam hari kerja MaxTradeAmount@RiskControl Maksimal jumlah yang dapat ditarik satu kali (number) 1000 */

var __orderCount = 0 // Mencatat jumlah satuan berikutnya untuk hari kerja saat ini var __orderDay = 0 // mencatat tanggal hari kerja saat ini

function CanTrade ((tradeAmount) { // Modul pengendalian risiko, parameter: jumlah transaksi if (!RiskControl) { // Tidak mengaktifkan modul kontrol angin secara default, jika tidak, fungsi CanTrade mengembalikan true Kembali benar Aku tidak tahu. if (typeof(tradeAmount) == number && tradeAmount > MaxTradeAmount) { // Masukkan parameter tradeAmount sebagai tipe angka, dan jumlah subunit lebih besar dari jumlah subunit maksimum yang ditetapkan oleh parameter templat Log ((Badai kontrol modul dibatasi, melebihi jumlah maksimum yang diturunkan, MaxTradeAmount, #ff0000 @); // output prompt, interrupt execution. Membuang bola untuk menghentikan bola kembali false; Aku tidak tahu. var nowDay = new Date (().getDate ((); // Dapatkan tanggal saat ini if (nowDay!= __orderDay) { // getDate() Mengembalikan hari tertentu dalam sebulan dari obyek Date (1 ~ 31) ∞. __orderDay = nowDay; // __orderDay Variabel global mencatat tanggal pemicu pertama kali masuk ke modul kontrol angin. __orderCount = 0; // meng-update variabel __orderDay, mengatur ulang variabel __orderCount Aku tidak tahu. __orderCount++; // Variabel global __orderCount Nomor tunggal berikutnya, penjumlahan diri. if (__orderCount > MaxTrade) { // Memutuskan apakah jumlah transaksi maksimum dalam satu hari melebihi jumlah yang ditetapkan oleh parameter Log ((Hormon kontrol modul dibatasi, tidak dapat diperdagangkan, melebihi jumlah satuan terendah maksimum, MaxTrade, #ff0000 @); // melebihi, output prompt, menghentikan pelaksanaan. Membuang bola untuk menghentikan bola kembali false; Aku tidak tahu. return true; // Tidak ada kondisi di atas yang dipicu, kembali true, yaitu dapat ditransfer. Aku tidak tahu.

function init() { // Fungsi initialization template, yang akan dijalankan terlebih dahulu saat template dimuat. if (typeof(SlideTick) === undefined) { // Memeriksa apakah SlideTick belum didefinisikan. SlideTick = 1; // Pengaturan Default 1 } else { // Mengubah string menjadi angka, namun jika string yang dimulai dengan karakter non-nomer akan mengembalikan NaN, mungkin akan menyebabkan kesalahan SlideTick = parseInt (SlideTick); Aku tidak tahu. Log (Log yang berhasil dimuat); Aku tidak tahu.

function GetPosition ((e, contractType, direction, positions) { // Menggabungkan sebuah kontrak dengan posisi sebelumnya dan posisi sekarang pada arah yang sama, dengan parameter sebagai berikut: objek bursa, jenis kontrak, arah, data kepemilikan yang dikembalikan oleh API ((bisa kosong)
var allCost = 0; // contractType Kontrak dalam arah arah total biaya, tidak ada perkalian kontrak satu tangan berapa banyak poin ((karena keseluruhan dapat diartikan) var allAmount = 0; // Jumlah total kontrak var allProfit = 0; // total laba rugi var allFrozen = 0; // Jumlah total beku var pos Margin = 0; // Kontrak Holding Leverage if (typeof(positions) === undefinedᅢ!positions) { // Jika parameter tidak mengirim informasi penyimpanan yang dikembalikan ke API positions = _C ((e.GetPosition); // di mana API dipanggil untuk mendapatkan informasi penyimpanan. Aku tidak tahu. for (var i = 0; i < positions.length; i++) { // melintasi dataset informasi penyimpanan ini. if (positions[i].ContractType == contractType && // kode kontrak informasi kepemilikan indeks saat ini == kode kontrak yang ditentukan oleh parameter (contractType) dan arahnya sama dengan arah parameter yang diteruskan (direction) pada posisi sekarang atau posisi sebelumnya (((positions[i].Type == PD_LONG untuk posisi[i].Type == PD_LONG_YD) && direction == PD_LONG untuk posisi[i].Type == PD_SHORT untuk posisi[i].Type == PD_SHORT_YD) && direction == PD_SHORT)) ) { // Melakukan blok if yang memenuhi syarat posMargin = positions[i].MarginLevel; // Dapatkan nilai leverage Atur nilai ke posMargin allCost += (positions[i].Price * positions[i].Amount); // Total biaya ((Jumlah kontrak yang telah disetujui, harga indeks kepemilikan saat ini * Jumlah kepemilikan) allAmount += positions[i].Amount; // Jumlah tangan kontrak yang terkumpul allProfit += positions[i].Profit; // Kontrak yang mengambang keuntungan dan kerugian akumulasi allFrozen += positions[i].FrozenAmount; // Jumlah kontrak yang dibekukan Aku tidak tahu. Aku tidak tahu. if (allAmount === 0) { // Jika jumlah kontrak yang memenuhi syarat yang terkumpul setelah pelacakan selesai adalah 0, kembali null, yaitu memegang kontrak tanpa batasan kondisi kembali null; Aku tidak tahu. return { // allAmount non-0, mengembalikan informasi penyimpanan setelah penggabungan sebuah objek. MarginLevel: posMargin, situs web yang menyediakan informasi tentang situs web. FrozenAmount: semua beku, Harga: _N (allCost / allAmount), Jumlah: semua Jumlah, Profit: allProfit, Jenis: arah, ContractType: jenis kontrak Aku tidak tahu. Aku tidak tahu.

Open function ((e, contractType, direction, opAmount) { // Operasi kontrak varietas tunggal Fungsi perdagangan terbuka, parameter: objek bursa, kode kontrak, arah, jumlah operasi var initPosition = GetPosition ((e, contractType, direction); // memanggil fungsi GetPosition di bagian atas untuk mendapatkan informasi penyimpanan setelah penggabungan. var isFirst = true; // Mengatur isFirst (menunjukkan bahwa while di bawah ini adalah siklus pertama yang benar) var initAmount = initPosition? initPosition.Amount : 0; // Jika initPosition adalah null, initAmount akan diberi nilai 0, jika tidak, initPosition.Amount var positionNow = initPosition; // menyatakan bahwa variabel positionNow menunjukkan informasi yang saat ini disimpan while (true) { // while lingkaran var needOpen = opAmount; // menyatakan variabel sementara needOpen dan memberikan nilai dengan parameter jumlah transaksi yang dibutuhkan if (isFirst) { // Jika pertama kali dijalankan, hanya memperbarui isFirst yang ditandai sebagai false, karena pembaruan adalah false. isFirst = false; } lainnya { positionNow = GetPosition ((e, contractType, direction); // memperbarui positionNow, informasi penyimpanan saat ini. if (positionNow) { // Jika ada informasi pemegang, jumlah posisi berikutnya yang perlu dibuka needOpen sama dengan jumlah operasi yang diminta parameter dikurangi perbedaan informasi pemegang yang diperoleh saat ini dengan yang sebelumnya (yaitu berapa banyak tangan yang baru dibuka) needOpen = opAmount - (positionNow.Amount - initAmount); Aku tidak tahu. Aku tidak tahu. var insDetail = _C ((e.SetContractType, contractType); // Mengatur jenis kontrak. // Log (yang memiliki tangki penyimpanan awal, initAmount, yang memiliki tangki penyimpanan saat ini, positionNow, yang membutuhkan tangki penyimpanan tambahan, needOpen); if (needOpen < insDetail.MinLimitOrderVolume) { // Jika jumlah tangan yang akan dibuka berikutnya lebih kecil dari jumlah tangan yang paling sedikit untuk daftar harga terbatas kontrak break; // keluar dari lingkaran Aku tidak tahu. if (!CanTrade(opAmount)) { // Modul kontrol angin Deteksi, jika kembali false Lolos dari lingkaran tanpa perdagangan. "Mengenai apa yang terjadi?" Aku tidak tahu. var depth = _C ((e.GetDepth); // Dapatkan informasi tentang kedalaman pasar. var amount = Math.min ((insDetail.MaxLimitOrderVolume, needOpen); // Batasi jumlah pesanan tidak dapat lebih besar dari jumlah pesanan maksimum dalam daftar harga yang dibatasi kontrak e.SetDirection ((direction == PD_LONG? buy: sell); // Setel arah ke bawah sesuai dengan parameter direction. VAR orderId; if (direction == PD_LONG) { // Mengundang API yang berbeda untuk melakukan transaksi ((berbuka atau terbuka) berdasarkan arah parameter direction orderId = e.Buy ((depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), Math.min ((amount, depth.Asks[0].Amount), contractType, Ask, depth.Asks[0]); // Lihat dokumentasi API, CTP komoditas futures harga geser untuk insDetail.PriceTick, harus kali ganda dari nilai ini // Jumlah sub-unit yang sebenarnya untuk panggilan API tidak lebih besar dari volume disk satu baris } lainnya { orderId = e.Sell ((depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), Math.min ((amount, depth.Bids[0].Amount), contractType, Bid, depth.Bids[0]); Aku tidak tahu. // Batalkan PendingOrders while (true) { // Setelah melakukan pesanan, interval waktu Interval, membatalkan pesanan yang belum selesai. Sleep (Interval); var orders = _C ((e.GetOrders); // Mengambil semua pesanan yang belum selesai if (orders.length === 0) { // Jika order adalah himpunan kosong, skip the current while "Mengenai apa yang terjadi?" Aku tidak tahu. for (var j = 0; j < orders.length; j++) { // Menjelajahi array order yang belum selesai e.CancelOrder ((orders[j].Id); // Batalkan pesanan berdasarkan ID dalam informasi pesanan indeks saat ini. if (j < (orders.length - 1)) { // melintasi interval waktu tertentu, satu sisi frekuensi terlalu tinggi. Sleep ((Interval); // Sleep Menangguhkan Interval Millisecond Aku tidak tahu. Aku tidak tahu. Aku tidak tahu. } // Jika lingkaran utama while keluar var ret = { // menyatakan objek yang akan dikembalikan harga: 0, // harga rata-rata transaksi jumlah: 0, // jumlah transaksi position: positionNow // Informasi penyimpanan terbaru dari varietas ini }; if (!positionNow) { // Jika tidak ada informasi penyimpanan, kembali langsung ke ret initialization return ret; Aku tidak tahu. if (!initPosition) { // Jika tidak ada informasi penyimpanan dari jenis ini saat menjalankan fungsi saat ini. ret.price = positionNow.Price; // Informasi Posisi Saat Ini Harga dalam posisi Sekarang adalah harga rata-rata yang dimiliki saat transaksi selesai ret.amount = positionNow.Amount; // di atas } else { // jika ada informasi penyimpanan dari varietas tersebut pada saat awal. ret.amount = positionNow.Amount - initPosition.Amount; // perbedaan adalah jumlah posisi baru yang dibuka ret.price = _N(((positionNow.Price * positionNow.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount); // Biaya yang ditambahkan baru dari transaksi ini dibagi dengan harga rata-rata dari transaksi ini Aku tidak tahu. return ret; // Mengembalikan ret Aku tidak tahu.

function Cover ((e, contractType) { // Fungsi penyeimbang tunggal, parameter: objek bursa, kode kontrak var insDetail = _C ((e.SetContractType, contractType); // Mengatur jenis kontrak while (true) { // lingkaran utama while var n = 0; // Penghitungan operasi perpaduan var opAmount = 0; // Deklarasi Operasi Variabel var positions = _C ((e.GetPosition); // Panggilan API untuk mendapatkan informasi penyimpanan, untuk membedakan fungsi penyimpanan tersebut. Lihat dokumentasi API untuk detailnya. for (var i = 0; i < positions.length; i++) { // menjelajahi Informasi penyimpanan if (positions[i].ContractType!= contractType) { // Jika informasi penyimpanan indeks saat ini Kontrak tidak sama dengan kontrak yang akan dioperasikan yaitu: contractType Continue; // Lolos Aku tidak tahu. var amount = Math.min ((insDetail.MaxLimitOrderVolume, positions[i].Amount); // Mengontrol volume transaksi maksimum yang tidak lebih besar dari invoice var depth; if (positions[i].Type == PD_LONG の の positions[i].Type == PD_LONG_YD) { // Mengatasi beberapa posisi depth = _C ((e.GetDepth); // Panggilan API untuk mendapatkan data saat ini opAmount = Math.min ((amount, depth.Bids[0].Amount); // batasan Jumlah operasi tidak lebih besar dari satu file if (!CanTrade ((opAmount)) { // Deteksi modul kontrol angin kembali; Aku tidak tahu. e.SetDirection ((positions[i].Type == PD_LONG? closebuy_today : closebuy); // pengaturan Arah transaksi, lihat dokumentasi API

            e.Sell(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
                                                                                           // 执行平仓 API ,详细参见 API文档。
            n++;                                                                           // 操作计数累加
        } else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) {    // 处理 空仓 类似多仓处理
            depth = _C(e.GetDepth);
            opAmount = Math.min(amount, depth.Asks[0].Amount);
            if (!CanTrade(opAmount)) {
                return;
            }
            e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
            e.Buy(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
            n++;
        }
    }
    if (n === 0) {                                                                         // 如果n 等于 0 ,即初始为0 ,在遍历时没有累加,没有可平的仓位。
        break;                                                                             // 跳出主while循环
    }
    while (true) {                                                                         // 间隔一定时间后, 取消所有挂单。类似Open函数的  CancelPendingOrders
        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);
            }
        }
    }
}

}

var trans = { // digunakan untuk menampilkan informasi akun rinci di status bar, terjemahan bahasa Cina, dictionary Akun ID: Akun investor yang terdaftar di akun Anda, dan akun yang terdaftar di akun Anda. Yang tersedia: Yang dapat digunakan sebagai mata uang, yang dapat digunakan sebagai mata uang, yang dapat digunakan sebagai mata uang. Di sisi lain, ada juga yang mengatakan bahwa Bitcoin adalah aset yang sangat berharga. Di bawah ini adalah daftar nama perusahaan broker Forex di Indonesia: Di sisi lain, banyak orang yang tidak tahu apa yang mereka lakukan. Yang CloseProfit Yang: Yang flat stock yang untung dan rugi. Yang Commission Yang: Yang biaya prosedur Yang, Yang, Yang, Yang. "Kredit saya naik, saya naik, saya naik, saya naik, saya naik, saya naik, saya naik, saya naik, saya naik". Yang Curr Margin Yang Curr: Yang Curr saat ini memiliki total jaminan yang tinggi. Bitcoin adalah mata uang digital yang digunakan untuk membeli dan menjual berbagai jenis mata uang. Pada tahun 2012, perusahaan yang bergerak di bidang jasa jasa pengiriman barang di Indonesia ini telah merilis produk-produknya di berbagai negara. Di sini, Anda dapat menemukan beberapa tips untuk membuat deposit yang lebih mudah. Pada tahun 2013, perusahaan tersebut telah merilis sebuah video yang berjudul "Show Me Your Money" yang menampilkan video yang berdurasi kurang dari 30 detik yang dipublikasikan di situs resmi perusahaan. Bitcoin Exchange Margin Bitcoin: Bitcoin adalah mata uang yang dijamin oleh bursa, dan Bitcoin adalah mata uang yang dijamin oleh bursa. "FrozenCash" (Kali beku): Kali beku, uang tunai, uang tunai, uang tunai, uang tunai. "Menghilangkan biaya pembekuan", kata juru bicara Komisi Frozen. "Frozen Margin" (Menghancurkan Margin) adalah emas yang dijamin beku. Anda dapat menggunakan akun Instagram Anda untuk mendaftarkan diri ke akun Instagram Anda, atau untuk mendaftarkan diri ke akun Instagram Anda. Di sini, Anda akan menemukan beberapa tips untuk membuat uang Anda lebih berharga. Di sini, Anda akan menemukan beberapa tips untuk membantu Anda mendapatkan uang tunai yang Anda butuhkan. Yang menarik adalah bahwa banyak orang yang tidak tahu apa yang mereka lakukan. Di sini Anda akan menemukan beberapa tips yang dapat Anda gunakan untuk mendapatkan keuntungan dari trading Forex. "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage", "Mortgage" dan "Mortgage", "Mortgage", "Mortgage", "Mortgage" dan "Mortgage" Anda dapat menggunakan dana yang Anda miliki untuk membayar utang Anda, dan Anda dapat menggunakan dana yang Anda miliki untuk membayar utang Anda. Di sisi lain, ada juga yang mengatakan bahwa mereka tidak memiliki uang untuk membeli saham. Yang PreBalance Yang: Yang terakhir kali menyelesaikan cadangan emas, Yang tidak bisa membayarnya. Yang PreCredit Yang: Yang terakhir kali kreditnya naik, saya tidak bisa membayarnya. Anda dapat menggunakan akun Instagram Anda untuk mendaftarkan diri ke akun Instagram Anda, tetapi Anda tidak dapat mendaftarkan diri. Anda dapat memilih untuk tidak menggunakan dana yang Anda miliki untuk membayar hipotek. Pada tanggal 1 Juli, para pengunjuk rasa mengibarkan bendera merah putih di depan Gedung Putih, di mana mereka mengibarkan bendera. Yang terakhir kali menempati saham di Pre-Margin, yang saat ini merupakan saham saham yang berjangka. "Saya tidak tahu apa yang akan terjadi", kata dia. Yang pertama adalah bahwa mereka tidak memiliki kemampuan untuk mengontrol dan memelihara energi mereka. Pemanfaatan Pemanfaatan Pemanfaatan Pemanfaatan Pemanfaatan Pemanfaatan Di sini, Anda akan menemukan beberapa tips yang dapat Anda gunakan untuk membuat keputusan yang tepat. Produk khusus yang disimpan dalam saham menghasilkan laba atau kerugian, dan produk khusus yang disimpan dalam saham menghasilkan laba atau kerugian, dan produk khusus yang disimpan dalam saham menghasilkan laba atau kerugian. Tanda-tanda bahwa produk khusus akan dikenakan biaya khusus, seperti harga, harga, atau harga. BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinSpecProductExchangeMargin: BitcoinMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoneyMoney Spek Produk Frozen Komisi: Spek Produk Frozen Komisi: Spek Produk Frozen Komisi: Spek Produk Frozen Komisi: Spek Produk Frozen Komisi: Spek Produk Frozen Komisi: Spek Produk Topi SpecProductFrozenMargin: Topi yang membekukan produk khusus yang menjamin emas, emas, dan emas. Paduan SpecProduct Margin: Paduan SpecProduct Margin: Paduan SpecProduct Margin adalah bagian dari Paduan SpecProduct Margin, yang merupakan bagian dari Paduan SpecProduct. Tanda-tanda bahwa produk khusus yang disimpan di dalam gudang mengalami kerugian atau keuntungan. SpecProductPositionProfitByAlg: Berbasis pada algoritma laba rugi saham yang dihitung oleh algoritma laba rugi saham produk khusus, laba rugi saham produk khusus yang dihitung oleh algoritma laba rugi saham yang dihitung oleh algoritma laba rugi saham. Di sini Anda akan menemukan beberapa tips yang dapat Anda gunakan untuk memulai bisnis online. "Mengambil uang dengan uang tunai: Mengambil uang tunai dengan uang tunai, mengambil uang tunai dengan uang tunai, mengambil uang tunai dengan uang tunai, mengambil uang tunai dengan uang tunai, mengambil uang tunai dengan uang tunai, mengambil uang tunai dengan uang tunai, dan mengambil uang tunai dengan uang tunai. Anda dapat mengambil uang dari akun Anda, tetapi Anda tidak dapat mengambilnya dari akun Anda. };

function AccountToTable ((jsStr, title) { // Fungsi fungsi untuk mengekspor informasi akun ke bentuk status bar, parameter: string struktur JSON yang akan ditampilkan, judul if (typeof(title) === undefined) { // Jika parameter title tidak masuk, initialize menjadi: Informasi akun title = "Menggunakan akun informasi"; Aku tidak tahu. var tbl = { // Mengisyaratkan objek tabel yang digunakan untuk mengirim fungsi LogStatus, yang ditampilkan pada status bar type: table, // tipe Ditentukan sebagai table title: title, // Parameter title Atur nilai ke bidang title untuk tbl cols: [Templat kolom, Templat deskripsi kolom, Templat ambang batas], // tabel rows: [] // Array field yang menyimpan data per baris tabel, dimulai dengan empty array. }; try { // mendeteksi kesalahan var fields = JSON.parse ((jsStr); // menganalisis string jsStr for (var k in fields) { // Berjalan di properti objek fields, k adalah nilai properti, tidak mengerti dapat melihat tutorial JS. if (k == AccountID k == BrokerID ) { // Jika properti yang sedang dijelajahi adalah kedua properti ini, dilewatkan. lanjutkan Aku tidak tahu. var desc = trans[k]; // Dapatkan deskripsi desc dalam bahasa Cina berdasarkan nama sifat trans var v = fields[k]; // Dapatkan nilai dari nama properti saat ini if (typeof(v) === number) { // Jika nilai atribut adalah tipe numerik, simpan 5 bit decimal. v = _N ((v, 5); Aku tidak tahu. tbl.rows.push (([k, typeof(desc) === undefined? : desc, v]); // Memperset array satu dimensi dari kombinasi properti, deskripsi properti, nilai properti saat ini ke dalam array properti rows dari objek tabel tbl. Aku tidak tahu. } catch (e) {} // Menangkap kelainan, tetapi tidak diproses return tbl; // Mengembalikan objek tbl Aku tidak tahu.

var PositionManager = (function() { // Mengisyaratkan variabel PositionManager menerima nilai balik dari fungsi anonim yang dikembalikan sebagai objek yang dibuat function PositionManager ((e) { // menyatakan bahwa suatu fungsi PositionManager adalah fungsi anonim. if (typeof(e) === undefined) { // Jika parameter e tidak ditransfer, variabel global Exchange by default diberi nilai e e = exchange; Aku tidak tahu. if (e.GetName()!== Futures_CTP) { // Memeriksa apakah objek e dari bursa utama adalah bursa berjangka komoditas, jika tidak maka membuang keanehan. throw Only support CTP ; // Hanya mendukung CTP Aku tidak tahu. this.e = e; // tambahkan sebuah atribut e ke fungsi saat ini (yang sebenarnya juga merupakan objek) dan berikan parameter e this.account = null; // Tambahkan account Variabel awalnya null Aku tidak tahu. // Dapatkan Cache PositionManager.prototype.Account = function() { // Tambahkan metode fungsi Account ke PositionManager yang dinyatakan di atas if (!this.account) { // Jika properti account dari PositionManager adalah null this.account = _C ((this.e.GetAccount); // Mengundang fungsi GetAccount dari objek pertukaran this.e (yaitu API objek pertukaran) untuk mendapatkan informasi akun. Aku tidak tahu. return this.account; // Metode ini mengembalikan informasi akun PositionManager.account ini. Aku tidak tahu. PositionManager.prototype.GetAccount = function ((getTable) { // Tambahkan metode Metode ini mendapatkan informasi akun terbaru This.account = _C ((this.e.GetAccount); if (typeof(getTable)!== undefined string && getTable) { // Jika ingin mengembalikan detail informasi akun yang baru-baru ini diambil sebagai objek, getTable harus benar return AccountToTable ((this.e.GetRawJSON))) // Fungsi GetRawJSON Lihat dokumentasi API Aku tidak tahu. return this.account; // Kembali informasi akun yang telah diperbarui. Aku tidak tahu.

PositionManager.prototype.GetPosition = function(contractType, direction, positions) { // 给 PositionManager 添加方法 用于在主策略中调用该模板的 函数
    return GetPosition(this.e, contractType, direction, positions);
};

PositionManager.prototype.OpenLong = function(contractType, shares) {                  // 添加 开多仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Open(this.e, contractType, PD_LONG, shares);
};

PositionManager.prototype.OpenShort = function(contractType, shares) {                 // 添加 开空仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Open(this.e, contractType, PD_SHORT, shares);
};

PositionManager.prototype.Cover = function(contractType) {                             // 添加 平仓 方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    return Cover(this.e, contractType);
};
PositionManager.prototype.CoverAll = function() {                                      // 添加 所有仓位全平方法
    if (!this.account) {
        this.account = _C(this.e.GetAccount);
    }
    while (true) {
        var positions = _C(this.e.GetPosition)
        if (positions.length == 0) {
            break
        }
        for (var i = 0; i < positions.length; i++) {                                   // 首先平掉 对冲合约 对冲合约 举例 MA709&MA705
            // Cover Hedge Position First
            if (positions[i].ContractType.indexOf('&') != -1) {
                Cover(this.e, positions[i].ContractType)
                Sleep(1000)
            }
        }
        for (var i = 0; i < positions.length; i++) {
            if (positions[i].ContractType.indexOf('&') == -1) {
                Cover(this.e, positions[i].ContractType)
                Sleep(1000)
            }
        }
    }
};
PositionManager.prototype.Profit = function(contractType) {                            // 添加计算收益的方法
    var accountNow = _C(this.e.GetAccount);
    return _N(accountNow.Balance - this.account.Balance);
};

return PositionManager;                                                                // 匿名函数返回 在自身内声明的 PositionManager 函数(对象)。

})();

$.NewPositionManager = function(e) { // Mengekspor fungsi, membangun objek PositionManager return new Posisi Manajer ((e); };

// Melalui:http://mt.sohu.com/20160429/n446860150.shtml$.IsTrading = function ((symbol) { // Mengetahui apakah kontrak dalam transaksi Dalam jangka waktu, parameter symbol Kontrak kode var now = new Date ((); // Dapatkan objek waktu saat ini var day = now.getDay ((); // Dapatkan waktu saat ini pada hari tertentu dalam seminggu. var hour = now.getHours(); // Dapatkan jam yang tepat dalam 24 jam var minute = now.getMinutes ((); // Dapatkan menit dalam satu menit

if (day === 0 || (day === 6 && (hour > 2 || hour == 2 && minute > 30))) {              // 第一个过滤, day == 0 星期天  或者  day == 6 星期六并且
    return false;                                                                      // 2点30以后 。 星期五 夜盘结束。  返回 false  即所有品种不在交易时间
}
symbol = symbol.replace('SPD ', '').replace('SP ', '');                                // 正则表达式 匹配其交易系统用“SPD”表示跨期套利交易,若指令买进“SPD CF1609&CF17...
                                                                                       // 过滤掉 跨期套利的 合约编码
var p, i, shortName = "";
for (i = 0; i < symbol.length; i++) {                                                  // 遍历合约代码字符串,取出 代码(排除数字的部分)赋值给shortName 并且转换为大写
    var ch = symbol.charCodeAt(i);
    if (ch >= 48 && ch <= 57) {
        break;
    }
    shortName += symbol[i].toUpperCase();
}

var period = [                                                                         // 通常交易时间  9:00 - 10:15,
    [9, 0, 10, 15],                                                                    //             10:30 - 11:30
    [10, 30, 11, 30],                                                                  //              13:30 - 15:00
    [13, 30, 15, 0]
];
if (shortName === "IH" || shortName === "IF" || shortName === "IC") {                  // 如果是这些 品种,交易时间 period 调整
    period = [
        [9, 30, 11, 30],
        [13, 0, 15, 0]
    ];
} else if (shortName === "TF" || shortName === "T") {                                  // 国债品种  时间调整
    period = [
        [9, 15, 11, 30],
        [13, 0, 15, 15]
    ];
}


if (day >= 1 && day <= 5) {                                                            // 如果是 周一 到周五, 不考虑夜盘。 判断当前时间是否符合 period 设定的时间表
    for (i = 0; i < period.length; i++) {
        p = period[i];
        if ((hour > p[0] || (hour == p[0] && minute >= p[1])) && (hour < p[2] || (hour == p[2] && minute < p[3]))) {
            return true;                                                               // 符合遍历出的  时间表 中的 时间段,  即该品种在交易时间内。
        }
    }
}

var nperiod = [                                                                        // 额外判断 夜盘品种  nperiod[n][0] 是夜盘时间相同的一类
                                                                                       // 品种汇总,nperiod[n][1] 就是该类品种的夜盘交易时间
    [
        ['AU', 'AG'],
        [21, 0, 02, 30]
    ],
    [
        ['CU', 'AL', 'ZN', 'PB', 'SN', 'NI'],
        [21, 0, 01, 0]
    ],
    [
        ['RU', 'RB', 'HC', 'BU'],
        [21, 0, 23, 0]
    ],
    [
        ['P', 'J', 'M', 'Y', 'A', 'B', 'JM', 'I'],
        [21, 0, 23, 30]
    ],
    [
        ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'IO'],
        [21, 0, 23, 30]
    ],
];
for (i = 0; i < nperiod.length; i++) {                                                // 遍历所有夜盘品种 交易时间段,对比当前时间。
    for (var j = 0; j < nperiod[i][0].length; j++) {
        if (nperiod[i][0][j] === shortName) {
            p = nperiod[i][1];
            var condA = hour > p[0] || (hour == p[0] && minute >= p[1]);
            var condB = hour < p[2] || (hour == p[2] && minute < p[3]);
            // in one day
            if (p[2] >= p[0]) {
                if ((day >= 1 && day <= 5) && condA && condB) {
                    return true;
                }
            } else {
                if (((day >= 1 && day <= 5) && condA) || ((day >= 2 && day <= 6) && condB)) {
                    return true;
                }
            }
            return false;
        }
    }
}
return false;

};

$.NewTaskQueue = function ((onTaskFinish) { // digunakan untuk membangun fungsi obyek antrian untuk melakukan transaksi multi-varietas. Parameter: fungsi yang memanggil kembali saat tugas selesai. var self = {} // menyatakan objek kosong self.ERR_SUCCESS = 0 // Definisi Mengembalikan Informasi Sukses sel.ERR_SET_SYMBOL = 1 // Kesalahan pengaturan kontrak sel.ERR_GET_RECORDS = 2 // Kesalahan mendapatkan baris K sel.ERR_GET_ORDERS = 3 // Kesalahan mendapatkan pesanan yang belum selesai sel.ERR_GET_POS = 4 // Kesalahan mendapatkan informasi penyimpanan sel.ERR_TRADE = 5 // Kesalahan transaksi sel.ERR_GET_DEPTH = 6 // Kesalahan dalam mendapatkan data self.ERR_NOT_TRADING = 7 // Tidak pada saat perdagangan self.ERR_BUSY = 8 // Blokir

self.onTaskFinish = typeof(onTaskFinish) === 'undefined' ? null : onTaskFinish  // 如果在 初始化队列对象时没有 传入需要回调的匿名函数,该属性赋值为null,否则赋值回调函数
self.retryInterval = 300                                                        // 重试间隔 毫秒数
self.tasks = []                                                                 // 这个是一个重要的属性,队列中储存任务的数组。
self.pushTask = function(e, symbol, action, amount, arg, onFinish) {            // 给空对象添加函数,该函数是压入 新任务 到任务数组中。参数分别为:
                                                                                // 交易所对象、合约代码、执行动作、数量、回调函数参数、回调函数
    var task = {                                                                // 构造一个任务对象
        e: e,                                                                   // 交易所对象
        action: action,                                                         // 执行的动作
        symbol: symbol,                                                         // 合约代码
        amount: amount,                                                         // 操作数量
        init: false,                                                            // 是否初始化
        finished: false,                                                        // 是否任务完成
        dealAmount: 0,                                                          // 已处理的 量
        preAmount: 0,                                                           // 上一次的 量
        preCost: 0,                                                             // 上一次的 花费
        retry: 0,                                                               // 重试次数
        maxRetry: 10,                                                           // 最大重试次数
        arg: typeof(onFinish) !== 'undefined' ? arg : undefined,                // 如果没有传入 回调函数,此项 设置为 undefined
        onFinish: typeof(onFinish) == 'undefined' ? arg : onFinish              // 如果没有传入回调函数,把 arg 复制给 onFinish(实际上是 arg没传入,中间隔过去了)
    }
    
    switch (task.action) {                                                      // 根据执行的动作初始化描述信息
        case "buy":
            task.desc = task.symbol + " 开多仓, 数量 " + task.amount
            break
        case "sell":
            task.desc = task.symbol + " 开空仓, 数量 " + task.amount
            break
        case "closebuy":
            task.desc = task.symbol + " 平多仓, 数量 " + task.amount
            break
        case "closesell":
            task.desc = task.symbol + " 平空仓, 数量 " + task.amount
            break
        default:
            task.desc = task.symbol + " " + task.action + ", 数量 " + task.amount
    }

    self.tasks.push(task)                                                       // 压入任务数组中
    Log("接收到任务", task.desc)                                                  // 输出日志 显示 接收到任务。
}

self.cancelAll = function(e) {                                                  // 添加函数,取消所有,参数: 交易所对象
    while (true) {                                                              // 遍历未完成的所有订单,逐个取消。
        var orders = e.GetOrders();
        if (!orders) {                                                          // 所有API 调用都不重试,如果API调用失败,立即返回。
            return self.ERR_GET_ORDERS;
        }
        if (orders.length == 0) {
            break;
        }
        for (var i = 0; i < orders.length; i++) {
            e.CancelOrder(orders[i].Id);
            Sleep(self.retryInterval);
        }
    }
    return self.ERR_SUCCESS                                                      // 返回 完成标记
}

self.pollTask = function(task) {                                                 // 执行数组中弹出的任务
    var insDetail = task.e.SetContractType(task.symbol);                         // 切换到当前 任务 task 对象保存的合约类型
    if (!insDetail) {                                                            // 切换失败 立即返回
        return self.ERR_SET_SYMBOL;
    }
    var ret = null;
    var isCover = task.action != "buy" && task.action != "sell";                 // 根据执行的动作,设置 是否是平仓的 标记
    do {                                                                         // do while 循环,先执行 do 以内
        if (!$.IsTrading(task.symbol)) {                                         // 判断是否在交易时间
            return self.ERR_NOT_TRADING;                                         // 不在交易时间立即返回
        }
        if (self.cancelAll(task.e) != self.ERR_SUCCESS) {                        // 调用全部取消函数 ,如果不等于 完成状态
            return self.ERR_TRADE;                                               // 返回交易失败
        }
        if (!CanTrade(task.amount)) {                                            // 风控模块检测。
            ret = null
            break
        }
        var positions = task.e.GetPosition();                                    // 获取持仓信息
        // Error
        if (!positions) {
            return self.ERR_GET_POS;                                             // 如果调用获取持仓 API 错误,立即返回
        }
        // search position
        var pos = null;
        for (var i = 0; i < positions.length; i++) {                             // 遍历持仓信息,查找持仓合并持仓,类似 上面的 GetPosition 函数
            if (positions[i].ContractType == task.symbol && (((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) && (task.action == "buy" || task.action == "closebuy")) || ((positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) && (task.action == "sell" || task.action == "closesell")))) {
                if (!pos) {
                    pos = positions[i];
                    pos.Cost = positions[i].Price * positions[i].Amount;
                } else {
                    pos.Amount += positions[i].Amount;
                    pos.Profit += positions[i].Profit;
                    pos.Cost += positions[i].Price * positions[i].Amount;
                }
            }
        }
        // record pre position
        if (!task.init) {                                                        // 如果任务没有初始化,执行以下
            task.init = true;                                                    // 更新为已初始化
            if (pos) {                                                           // 如果查找到之前的持仓,把之前的持仓数量、 花费 复制给task 的相应变量保存
                task.preAmount = pos.Amount;
                task.preCost = pos.Cost;
            } else {                                                             // 如果执行这个任务 时没有 ,同样的方向  同样合约的持仓,把task相关变量赋值0
                task.preAmount = 0;
                task.preCost = 0;
                if (isCover) {                                                   // 如果是 平仓动作,输出日志 : 找不到仓位,跳出循环。
                    Log("找不到仓位", task.symbol, task.action);
                    ret = null;
                    break;
                }
            }
        }
        var remain = task.amount;                                                // 声明一个局部变量,用 任务的属性 amount(任务设定的交易量) 初始化
        if (isCover && !pos) {                                                   // 如果 第二次循环中 , 该任务动作是平仓,并且 没有持仓了,给pos 赋值
            pos = {Amount:0, Cost: 0, Price: 0}
        }
        if (pos) {                                                               // 如果 pos 不为null 
            task.dealAmount = pos.Amount - task.preAmount;                       // 已经处理的任务量 等于 每次获取的持仓信息持仓量 与最初开始循环的初始持仓信息持仓量的差值
            if (isCover) {                                                       // 如果是 平仓动作, dealAmount 是负值, 这里取反操作
                task.dealAmount = -task.dealAmount;
            }
            remain = parseInt(task.amount - task.dealAmount);                    // 任务的 交易量 减去 已经处理的交易量  得出 剩余需要处理的交易量
            if (remain <= 0 || task.retry >= task.maxRetry) {                    // 如果剩余需要的交易量小于等于0(此处分析应该是不会小于0,有兴趣的可以分析下。) 或者重试次数大于最大重试上限.
                ret = {                                                          // 更新ret 对象,  更新为已经成交的信息,和 当前仓位信息。
                    price: (pos.Cost - task.preCost) / (pos.Amount - task.preAmount),
                    amount: (pos.Amount - task.preAmount),
                    position: pos
                };
                if (isCover) {                                                   // 如果是 平仓动作
                    ret.amount = -ret.amount;                                    // 平仓时计算出的是负值  ,取反操作
                    if (pos.Amount == 0) {                                       // 如果持仓量为0了, 把ret 的持仓信息 赋值为 null
                        ret.position = null;
                    }
                }
                break;                                                           // remain <= 0 || task.retry >= task.maxRetry 符合这个条件,跳出while循环
            }
        } else if (task.retry >= task.maxRetry) {                                // 如果不是 平仓操作。pos 为null 没有持仓(平仓操作 pos 此处不会是null)
            ret = null;                                                          // 并且 该任务重试测试 大于最大重试次数。跳出循环。
            break;                                                               // 即此时  , 超过最大重试次数,并且 没有增加持仓(开仓 每次都失败了。),跳出循环
        }

        var depth = task.e.GetDepth();                                           // 获取 深度数据
        if (!depth) {
            return self.ERR_GET_DEPTH;                                           // 获取失败立即返回
        }
        var orderId = null;                                                      // 订单ID
        var slidePrice = insDetail.PriceTick * SlideTick;                        // 计算具体滑价值
        if (isCover) {                                                           // 如果是平仓操作
            for (var i = 0; i < positions.length; i++) {                         // 遍历本轮的  API 返回的持仓信息。
                if (positions[i].ContractType !== task.symbol) {                 // 不是当前任务 品种的  跳过。
                    continue;
                }
                if (parseInt(remain) < 1) {                                      // 需要处理的 交易的量 如果小于1,跳出 while
                    break
                }
                var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount, remain);  // 在合约规定的最大下单量、持仓量、需要处理的量中取最小值。 
                if (task.action == "closebuy" && (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD)) {   // 如果是平多仓, 持仓信息 为 今日多仓  或者 昨日多仓
                    task.e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");                  // 设置方向
                    amount = Math.min(amount, depth.Bids[0].Amount)                                                     // 根据盘口量 和 下单量 再取一个最小值。
                    orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), amount, task.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
                                                                                                                        // 执行具体的 API 操作,以下平空类似
                } else if (task.action == "closesell" && (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD)) {
                    task.e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
                    amount = Math.min(amount, depth.Asks[0].Amount)
                    orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), amount, task.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
                }
                // assume order is success insert
                remain -= amount;                                                // 假设是成功执行, 需要处理的交易量 减去 此次交易的量。
            }
        } else {                                                                 // 开仓
            if (task.action == "buy") {
                task.e.SetDirection("buy");
                orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), Math.min(remain, depth.Asks[0].Amount), task.symbol, 'Ask', depth.Asks[0]);
            } else {
                task.e.SetDirection("sell");
                orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), Math.min(remain, depth.Bids[0].Amount), task.symbol, 'Bid', depth.Bids[0]);
            }
        }
        // symbol not in trading or other else happend
        if (!orderId) {                                                          // 没有返回具体的ID ,可能是 交易不在交易队列,或者其他错误。
            task.retry++;                                                        // 累计重试次数
            return self.ERR_TRADE;                                               // 返回错误信息。即使不成功, 重新 执行该任务的时候 会重新一次流程。除了task对象的数据 所有数据都会刷新
        }
    } while (true);                                                              // 循环判断 恒为真
    task.finished = true                                                         // 如果在 while 循环中没有直接 return  顺序执行到此,则任务完成                                                      

    if (self.onTaskFinish) {                                                     // 如果队列控制对象的 回调函数 设置 不为null(即 self.onTaskFinish 存在)
        self.onTaskFinish(task, ret)                                             // 执行回调函数。把 task 任务 对象  和 交易的结果  ret 对象 传入回调函数。 
    }

    if (task.onFinish) {                                                         // 处理 任务的回调函数
        task.onFinish(task, ret);
    }
    return self.ERR_SUCCESS;
}

self.poll = function() {                                                         // 迭代执行 弹出 tasks 中的任务 ,并调用 pollTask 执行任务。
    var processed = 0                                                            // 未执行完成的任务计数 ,每次初始0
    _.each(self.tasks, function(task) {                                          // 迭代  可以搜索 _.each 的用法
        if (!task.finished) {                                                    // 如果 任务不是完成状态,
            processed++                                                          // 未完成任务 计数 累计
            self.pollTask(task)                                                  // 执行弹出的任务
        }
    })
    if (processed == 0) {                                                        // 如果没有未完成的任务,即 所有任务队列内的任务完成 ,执行清空 队列对象中 tasks 数组.
        self.tasks = []
    }
}

self.size = function() {                                                         // 给队列对象添加 函数 size 获取 任务队列 中 任务个数
    return self.tasks.length
}

return self                                                                      // 返回构造好的队列对象

}

$.AccountToTable = AccountToTable;


Lebih banyak