Chiến lược giao dịch lệch

Tác giả:Tốt, Tạo: 2018-08-30 17:45:11, Cập nhật: 2019-12-03 17:32:58

Chiến lược giao dịch lệchwww.fmz.com

  1. Hệ thống giao dịch Aberration được phát minh bởi Keith Fitschen vào năm 1986. Năm 1993, Keith Fitschen đã thương mại hóa hệ thống trong tạp chí Futures Truth. Kể từ khi ra mắt, hệ thống đã liên tục xếp hạng trong số những hệ thống tốt nhất vào năm 1997, 2001 và 2005. Hệ thống xếp hạng trong top 10 trong bảng xếp hạng hiệu suất của các hệ thống giao dịch được xuất bản. Hệ thống giao dịch được đặc trưng bởi giao dịch đồng thời trên tám loại khác nhau, bao gồm ngũ cốc, thịt, kim loại, năng lượng, ngoại hối, tài chính và chỉ số tương lai cổ phiếu. Hệ thống giao dịch Aberration thường giao dịch 3-4 lần một năm, và giữ vị trí 60% thời gian, với trung bình 60 ngày mỗi giao dịch. Nó thu được lợi nhuận khổng lồ thông qua giao dịch dài hạn để nắm bắt xu hướng.

  2. Nó làm thế nào để bù đắp cho sự mất mát? Bởi vì nó giao dịch trong nhiều thị trường không liên quan cùng một lúc, khi một loài mất, một loài khác có thể kiếm được lợi nhuận. Trong một năm, luôn luôn có một hoặc nhiều giống có thể kiếm được lợi nhuận lớn. Những lợi nhuận lớn này bù đắp cho những tổn thất nhỏ trong những thị trường không có xu hướng. Hệ thống giao dịch Aberration quản lý các quỹ kết hợp, vì vậy nó có thể chấp nhận một số tiền tương đối lớn.

  3. sự khác biệt đường quang cũng dựa trên hệ thống giao dịch đường Bollinger, nhưng mục tiêu giao dịch dài hơn hệ thống cướp Bollinger, vì nó có thể sử dụng hai lần kênh lệch chuẩn, và không sử dụng stop loss, và chỉ số kênh được sử dụng để dừng lỗ.

Mã sau đây chỉ là một khuôn khổ của ý tưởng trên, bạn cần phải điều chỉnh chi tiết cho lựa chọn giao dịch của bạn.

Khung mã hóa rõ ràng và có thể sử dụng lại. Trình sửa lỗi thời gian thực khi chạy qua chức năng tương tác. Hoạt động ổn định, thiết kế chi tiết hoàn hảo. Hỗ trợ nhiều loại giao dịch cùng một lúc, có thể kiểm soát số tiền vị trí giao dịch riêng biệt. Tự động tiếp tục tiến trình dựa trên vị trí khi khởi động lại. Với mô-đun kiểm soát rủi ro, hiển thị thời gian thực tình hình rủi ro, tình trạng dừng lỗ.

Nếu bạn không muốn thuê một máy chủ, bạn có thể sử dụng máy tính của riêng bạn hoặc Raspberry Pi mà bất kỳ máy chạy hệ thống Windows, Linux hoặc Mac.

function Aberration(q, e, symbol, period, upRatio, downRatio, opAmount) {
    var self = {}
    self.q = q
    self.e = e
    self.symbol = symbol
    self.upTrack = 0
    self.middleTrack = 0
    self.downTrack = 0
    self.nPeriod = period
    self.upRatio = upRatio
    self.downRatio = downRatio
    self.opAmount = opAmount
    self.marketPosition = 0

    self.lastErrMsg = ''
    self.lastErrTime = ''
    self.lastBar = {
        Time: 0,
        Open: 0,
        High: 0,
        Low: 0,
        Close: 0,
        Volume: 0
    }
    self.symbolDetail = null
    self.lastBarTime = 0
    self.tradeCount = 0
    self.isBusy = false

    self.setLastError = function(errMsg) {
        self.lastErrMsg = errMsg
        self.lastErrTime = errMsg.length > 0 ? _D() : ''
    }

    self.getStatus = function() {
        return [self.symbol, self.opAmount, self.upTrack, self.downTrack, self.middleTrack, _N(self.lastBar.Close), (self.marketPosition == 0 ? "--" : (self.marketPosition > 0 ?
                   "Long#ff0000" : "short#0000ff")), self.tradeCount, self.lastErrMsg, self.lastErrTime]
    }
    self.getMarket = function() {
        return [self.symbol, _D(self.lastBarTime), _N(self.lastBar.Open), _N(self.lastBar.High), _N(self.lastBar.Low), _N(self.lastBar.Close), self.lastBar.Volume]
    }

    self.restore = function(positions) {
        for (var i = 0; i < positions.length; i++) {
            if (positions[i].ContractType == self.symbol) {
                self.marketPosition += positions[i].Amount * ((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) ? 1 : -1)
            }
        }
        if (self.marketPosition !== 0) {
            self.tradeCount++
                Log("restore", self.symbol, "Current position is", self.marketPosition)
        }
    }

    self.poll = function() {
        if (self.isBusy) {
            return false
        }

        if (!$.IsTrading(self.symbol)) {
            self.setLastError("Not in trading hours")
            return false
        }

        if (!self.e.IO("status")) {
            self.setLastError("Unconnected exchange")
            return false
        }

        var detail = self.e.SetContractType(self.symbol)
        if (!detail) {
            self.setLastError("Switching contract failed")
            return false
        }
        if (!self.symbolDetail) {
            self.symbolDetail = detail
            Log("contract", detail.InstrumentName.replace(/\s+/g, ""), ", Strategy first time to open a position:", self.opAmount, "hand, one hand", detail.VolumeMultiple, "unit, Maximum order quantity",
                detail.MaxLimitOrderVolume, "Margin rate:", detail.LongMarginRatio.toFixed(4), detail.ShortMarginRatio.toFixed(4), "Delivery date", detail.StartDelivDate);
        }
        var records = self.e.GetRecords()
        if (!records || records.length == 0) {
            self.setLastError("Failed to get the bar line")
            return false
        }

        var bar = records[records.length - 1]
        self.lastBar = bar

        if (records.length <= self.nPeriod) {
            self.setLastError("The length of the bar line is not enough")
            return false
        }

        if (self.lastBarTime < bar.Time) {
            var sum = 0
            var pos = records.length - self.nPeriod - 1
            for (var i = pos; i < records.length - 1; i++) {
                sum += records[i].Close
            }
            var avg = sum / self.nPeriod
            var std = 0
            for (i = pos; i < records.length - 1; i++) {
                std += Math.pow(records[i].Close - avg, 2)
            }
            std = Math.sqrt(std / self.nPeriod)

            self.upTrack = _N(avg + (self.upRatio * std))
            self.downTrack = _N(avg - (self.downRatio * std))
            self.middleTrack = _N(avg)
            self.lastBarTime = bar.Time
        }
        var msg
        var act = ""
        if (self.marketPosition == 0) {
            if (bar.Close > self.upTrack) {
                msg = 'Buying Long trigger price: ' + bar.Close + ' Upper rail:' + self.upTrack;
                act = "buy"
            } else if (bar.Close < self.downTrack) {
                msg = 'Selling short trigger price: ' + bar.Close + ' lower rail:' + self.downTrack;
                act = "sell"
            }
        } else {
            if (self.marketPosition < 0 && bar.Close > self.middleTrack) {
                msg = 'close the short position trigger price: ' + bar.Close + ' close position line:' + self.middleTrack;
                act = "closesell"
            } else if (self.marketPosition > 0 && bar.Close < self.middleTrack) {
                msg = 'close the long position trigger price: ' + bar.Close + ' close position line:' + self.middleTrack;
                act = "closebuy"
            }
        }

        if (act == "") {
            return true
        }

        Log(self.symbol + ', ' + msg + (NotifyWX ? '@' : ''))

        self.isBusy = true
        self.tradeCount += 1
        if (self.lastErrMsg != '') {
            self.setLastError('')
        }
        self.q.pushTask(self.e, self.symbol, act, self.opAmount, function(task, ret) {
            self.isBusy = false
            if (!ret) {
                return
            }
            if (task.action == "buy") {
                self.marketPosition = 1
            } else if (task.action == "sell") {
                self.marketPosition = -1
            } else {
                self.marketPosition = 0
            }
        })
    }
    return self
}

function main() {
    if (exchange.GetName() !== 'Futures_CTP') {
        throw "Only support traditional commodity futures(CTP)"
    }
    
    SetErrorFilter("login|ready|initialization")

    LogStatus("Ready...")
    if (Reset) {
        LogProfitReset()
        LogReset()
    }
    
    // Ref: https://www.fmz.com/bbs-topic/362
    if (typeof(exchange.IO("mode", 0)) == 'number') {
        Log("Switching the market mode successfully")
    }

    LogStatus("Waiting to connect with the futures dealer server..")
    while (!exchange.IO("status")) {
        Sleep(500)
    }
    LogStatus("Get asset information")
    var tblRuntime = {
        type: 'table',
        title: 'Trading Information',
        cols: ['Variety', 'Each open position volume', 'upper rail', 'lower rail', 'middle rail', 'last transaction price', 'position', 'transaction count', 'last error', 'error time'],
        rows: []
    };
    var tblMarket = {
        type: 'table',
        title: 'Quote information',
        cols: ['Variety', 'current cycle', 'opening', 'highest', 'lowest', 'last transaction price', 'volume'],
        rows: []
    };
    var tblPosition = {
        type: 'table',
        title: 'Position information',
        cols: ['Variety', 'leverage', 'direction', 'average price', 'quantity', 'holding profit and loss'],
        rows: []
    };
    var positions = _C(exchange.GetPosition)
    if (positions.length > 0 && !AutoRestore) {
        throw "There can be no positions when the program starts, but you can check the automatic recovery for automatic identification!"
    }
    var initAccount = _C(exchange.GetAccount)
    var detail = JSON.parse(exchange.GetRawJSON())
    if (positions.length > 0) {
        initAccount.Balance += detail['CurrMargin']
    }
    var initNetAsset = detail['CurrMargin'] + detail['Available']
    var initAccountTbl = $.AccountToTable(exchange.GetRawJSON(), "Initial funding")

    if (initAccountTbl.rows.length == 0) {
        initAccountTbl.rows = [
            ['Balance', 'Available margin', initAccount.Balance],
            ['FrozenBalance', 'Frozen funds', initAccount.FrozenBalance]
        ]
    }

    var nowAcccount = initAccount
    var nowAcccountTbl = initAccountTbl

    var symbols = Symbols.replace(/\s+/g, "").split(',')
    var pollers = []
    var prePosUpdate = 0
    var suffix = ""
    var needUpdate = false
    var holdProfit = 0

    function updateAccount(acc) {
        nowAcccount = acc
        nowAcccountTbl = $.AccountToTable(exchange.GetRawJSON(), "Current funds")
        if (nowAcccountTbl.rows.length == 0) {
            nowAcccountTbl.rows = [
                ['Balance', 'Available margin', nowAcccount.Balance],
                ['FrozenBalance', 'Frozen funds', nowAcccount.FrozenBalance]
            ]
        }
    }

    var q = $.NewTaskQueue(function(task, ret) {
        needUpdate = true
        Log(task.desc, ret ? "success" : "fail")
        var account = task.e.GetAccount()
        if (account) {
            updateAccount(account)
        }
    })

    _.each(symbols, function(symbol) {
        var pair = symbol.split(':')
        pollers.push(Aberration(q, exchange, pair[0], NPeriod, Ks, Kx, (pair.length == 1 ? AmountOP : parseInt(pair[1]))))
    })

    if (positions.length > 0 && AutoRestore) {
        _.each(pollers, function(poll) {
            poll.restore(positions)
        })
    }
    var isFirst = true
    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            var js = cmd.split(':', 2)[1]
            Log("Execution debug code:", js)
            try {
                eval(js)
            } catch (e) {
                Log("Exception", e)
            }
        }
        tblRuntime.rows = []
        tblMarket.rows = []
        var marketAlive = false
        _.each(pollers, function(poll) {
            if (poll.poll()) {
                marketAlive = true
            }
            tblRuntime.rows.push(poll.getStatus())
            tblMarket.rows.push(poll.getMarket())
        })
        q.poll()
        Sleep(LoopInterval * 1000)
        if ((!exchange.IO("status")) || (!marketAlive)) {
            if (isFirst) {
                LogStatus("Waiting for the market open...", _D())
            }
            continue
        }
        isFirst = false
        var now = new Date().getTime()
        if (marketAlive && (now - prePosUpdate > 30000 || needUpdate)) {
            var pos = exchange.GetPosition()
            if (pos) {
                holdProfit = 0
                prePosUpdate = now
                tblPosition.rows = []
                for (var i = 0; i < pos.length; i++) {
                    tblPosition.rows.push([pos[i].ContractType, pos[i].MarginLevel, ((pos[i].Type == PD_LONG || pos[i].Type == PD_LONG_YD) ? 'long#ff0000' : 'short#0000ff'),
                     pos[i].Price, pos[i].Amount, _N(pos[i].Profit)])
                    holdProfit += pos[i].Profit
                }
                if (pos.length == 0 && needUpdate) {
                    LogProfit(_N(nowAcccount.Balance - initAccount.Balance, 4), nowAcccount)
                }
            }
            needUpdate = false
            if (RCMode) {
                var account = exchange.GetAccount()
                if (account) {
                    updateAccount(account)
                    var detail = JSON.parse(exchange.GetRawJSON())
                    var netAsset = detail['PositionProfit'] + detail['CurrMargin'] + detail['Available']
                    var risk = detail['CurrMargin'] / (detail['CurrMargin'] + detail['Available'] + detail['PositionProfit'])
                    suffix = ", Initial net worth of the account: " + _N(initNetAsset, 2) + " , risk control minimum net value requirement" + MinNetAsset + " , Current account equity: " + _N(netAsset, 2) + 
                             ", Profit and loss: " + _N(netAsset - initNetAsset, 3) + " yuan, risk: " + ((risk * 100).toFixed(3)) + "% #ff0000"
                    if (netAsset < MinNetAsset) {
                        Log("The risk control module triggers, stops running and closes all positions, the current net value is ", netAsset, ", Require less than the minimum net value:", MinNetAsset)
                        if (RCCoverAll) {
                            Log("Start to close all positions")
                            $.NewPositionManager().CoverAll()
                        }
                        throw "Stop running"
                    }
                }
            }
        }
        LogStatus('`' + JSON.stringify([tblRuntime, tblPosition, tblMarket, initAccountTbl, nowAcccountTbl]) + '`\nLast price update: ' + _D() + 
                    ', Last update of position: ' + _D(prePosUpdate) + '\nCurrent holding position total profit and loss: ' + _N(holdProfit, 3) + suffix)
    }
}

Thêm nữa

Giấc mơ nhỏLàm tốt lắm.