La estrategia de negociación de la aberración

El autor:La bondad, Creado: 2018-08-30 17:45:11, Actualizado: 2019-12-03 17:32:58

La estrategia de negociación de la aberraciónwww.fmz.com

  1. El sistema de negociación Aberration fue inventado por Keith Fitschen en 1986. En 1993, Keith Fitschen comercializó el sistema en la revista Futures Truth. Desde su lanzamiento, el sistema se ha clasificado constantemente entre los mejores en 1997, 2001 y 2005. El sistema se encuentra en los diez primeros lugares en el ranking de rendimiento de los sistemas de negociación publicados. El sistema de negociación se caracteriza por el comercio simultáneo de ocho variedades diferentes, incluidos cereales, carne, metales, energía, divisas, finanzas y futuros de índices de valores. El sistema de negociación Aberration a menudo opera 3-4 veces al año y mantiene posiciones el 60% del tiempo, con un promedio de 60 días por transacción.

  2. ¿Cómo compensa la pérdida? Debido a que opera en múltiples mercados no relacionados al mismo tiempo, cuando una especie pierde, otra puede obtener ganancias. En un año, siempre hay una o más variedades que pueden obtener enormes ganancias. Estas grandes ganancias compensan pequeñas pérdidas en aquellos mercados que no tienen tendencia.

  3. la diferencia de línea óptica también se basa en el sistema de negociación de línea de Bollinger, pero el objetivo de negociación es más largo que el sistema de ladrón de Bollinger, porque puede usar el doble del canal de desviación estándar, y no se utiliza stop loss, y el indicador del canal se utiliza para detener la pérdida.

El siguiente código es solo un marco de las ideas anteriores, debe ajustar el detalle para sus opciones comerciales.

El marco de codificación es claro y reutilizable. Debug en tiempo real cuando se ejecuta la función interactiva. Funcionamiento estable, diseño de detalles perfecto. Apoyar varias variedades de negociación al mismo tiempo, puede controlar el importe de la posición de negociación por separado. Reanuda automáticamente el progreso basado en la posición al reiniciar. Con el módulo de control de riesgos, muestra en tiempo real la situación de riesgo, la condición de stop loss.

Si no quieres alquilar un servidor, puedes usar tu propia computadora o Raspberry Pi que cualquier máquina ejecute Windows, Linux o sistema 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)
    }
}

Más.

Un sueño pequeño.- Buen trabajo.