Añadir un despertador a la estrategia de negociación

El autor:La bondad, Creado: 2020-08-06 11:15:28, Actualizado: 2023-10-10 21:14:31

img

Los operadores que diseñan estrategias comerciales a menudo me preguntan cómo diseñar funciones de tiempo para las estrategias para que las estrategias puedan manejar ciertas tareas en momentos específicos. Por ejemplo, algunas estrategias intradiarias necesitan cerrar posiciones antes de que termine la primera sección en un día de negociación. ¿Cómo diseñar tales requisitos en la estrategia comercial? Una estrategia puede usar mucho control de tiempo. De esta manera, podemos encapsular la función de control de tiempo para minimizar el acoplamiento entre el código de control de tiempo y la estrategia, para que el módulo de control de tiempo pueda reutilizarse y sea conciso en uso.

Diseñar un reloj de alarma

// triggerTime: 14:58:00
function CreateAlarmClock(triggerHour, triggerMinute) {
    var self = {} // constructed object
    // Set members and functions to the constructed object below
    
    self.isTrigger = false // Has it been triggered that day
    self.triggerHour = triggerHour // The planned trigger hour
    self.triggerMinute = triggerMinute // The planned trigger minute
    self.nowDay = new Date().getDay() // what day is the current time
    
    self.Check = function() { // Check function, check trigger, return true when triggered, return false if not triggered
        var t = new Date() // Get the current time object
        var hour = t.getHours() // Get the current decimal: 0~23
        var minute = t.getMinutes() // Get the current minute: 0~59
        var day = t.getDay() // Get the current number of days

        if (day != self.nowDay) { // Judge, if the current day is not equal to the day of the record, reset the trigger flag as not triggered and update the number of days for the record
            self.isTrigger = false
            self.nowDay = day
        }

        if (self.isTrigger == false && hour == self.triggerHour && minute >= self.triggerMinute) {
            // Determine whether the time is triggered, if it meets the conditions, set the flag isTrigger to true to indicate that it has been triggered
            self.isTrigger = true
            return true
        }

        return false // does not meet the trigger condition, that is, it is not triggered
    }

    return self // return the constructed object
}

Hemos diseñado e implementado una función para crear un objeto de reloj despertador (puede entenderse como un constructor), y otros lenguajes pueden diseñar directamente una clase de reloj despertador (por ejemplo, usando Python, implementaremos uno en Python más adelante).

Diseñar la función para construir el objeto reloj de alarma, y sólo necesita una línea de código para crear un objeto reloj de alarma en uso.

var t = CreateAlarmClock(14, 58)

Por ejemplo, crear un objeto t y activarlo a las 14:58 todos los días. Puedes crear otro objeto t1, que se activa todos los días a las 9:00.

var t1 = CreateAlarmClock(9, 0)

Estrategia de ensayo

Escribe una estrategia de prueba, la estrategia utiliza el sistema de promedio móvil más simple, la estrategia es sólo para probar y no se preocupa por la ganancia. El plan estratégico consiste en abrir una posición (larga, corta, sin negociación) basada en la media móvil diaria de la cruz dorada y la cruz muerta cuando el mercado abre a las 9:00 cada día, y cerrar la posición a las 14:58 de la tarde (cierre a las 15:00).

function CreateAlarmClock(triggerHour, triggerMinute) {
    var self = {} // constructed object
    // Set members and functions to the constructed object below
    
    self.isTrigger = false // Has it been triggered that day
    self.triggerHour = triggerHour // The planned trigger hour
    self.triggerMinute = triggerMinute // The planned trigger minute
    self.nowDay = new Date().getDay() // what day is the current time
    
    self.Check = function() {// Check function, check trigger, return true when triggered, return false if not triggered
        var t = new Date() // Get the current time object
        var hour = t.getHours() // Get the current decimal: 0~23
        var minute = t.getMinutes() // Get the current minute: 0~59
        var day = t.getDay() // Get the current number of days

        if (day != self.nowDay) {// Judge, if the current day is not equal to the day of the record, reset the trigger flag as not triggered and update the number of days for the record
            self.isTrigger = false
            self.nowDay = day
        }

        if (self.isTrigger == false && hour == self.triggerHour && minute >= self.triggerMinute) {
            // Determine whether the time is triggered, if it meets the conditions, set the flag isTrigger to true to indicate that it has been triggered
            self.isTrigger = true
            return true
        }

        return false // does not meet the trigger condition, that is, it is not triggered
    }

    return self // return the constructed object
}

function main() {
    var q = $.NewTaskQueue()
    var p = $.NewPositionManager()
    
    // You can write: var t = CreateAlarmClock(14, 58)
    // You can write: var t1 = CreateAlarmClock(9, 0)
    
    var symbol = "i2009"
    while (true) {
        if (exchange.IO("status")) {
            exchange.SetContractType(symbol)
            var r = exchange.GetRecords()
            if(!r || r.length <20) {
                Sleep(500)
                continue
            }
            if (/*Judging the conditions for opening a position at 9:00*/) {// You can write: t1.Check()
                var fast = TA.MA(r, 2)
                var slow = TA.MA(r, 5)
                
                var direction = ""
                if (_Cross(fast, slow) == 1) {
                    direction = "buy"
                } else if(_Cross(fast, slow) == -1) {
                    direction = "sell"
                }
                if(direction != "") {
                    q.pushTask(exchange, symbol, direction, 1, function(task, ret) {
                        Log(task.desc, ret)
                    })
                }
            }

            if (/*Judging 14:58 conditions for closing the position near the market close*/) {// You can write: t.Check()
                p.CoverAll()
            }

            q.poll()
            LogStatus(_D())
        } else {
            LogStatus(_D())
        }

        Sleep(500)
    }
}

Ponga elCreateAlarmClockEn la estrategia para determinar la posición de apertura y cierre, añadir el código que el objeto reloj de alarma llama elCheckFunción, como la parte comentada del código.

Prueba de retroceso

img

Puedes ver el backtest, posiciones de apertura después de las 9 am y posiciones de cierre a las 14:58.

También se puede utilizar para estrategias de múltiples variedades.

El lenguaje Python implementa la clase del reloj de alarma

Código de ejecución y de ensayo:

import time
class AlarmClock:
    def __init__(self, triggerHour, triggerMinute):
        self.isTrigger = False 
        self.triggerHour = triggerHour
        self.triggerMinute = triggerMinute
        self.nowDay = time.localtime(time.time()).tm_wday

    def Check(self):
        t = time.localtime(time.time())
        hour = t.tm_hour
        minute = t.tm_min
        day = t.tm_wday
        
        if day != self.nowDay:
            self.isTrigger = False
            self.nowDay = day
            
        if self.isTrigger == False and hour == self.triggerHour and minute >= self.triggerMinute:
            self.isTrigger = True
            return True
        
        return False 

def main():
    t1 = AlarmClock(14,58)
    t2 = AlarmClock(9, 0)
    while True:
        if exchange.IO("status"):
            LogStatus(_D(), "Already connected!")
            exchange.SetContractType("rb2010")
            ticker = exchange.GetTicker()
            if t1.Check():
                Log("Market Close", "#FF0000")
                
            if t2.Check():
                Log("Market Open", "#CD32CD")
        else :
            LogStatus(_D(), "not connected!")
        Sleep(500)

Se ejecutará el ensayo de retroevaluación:

img

Debe tenerse en cuenta que, para el backtest, el ciclo de la línea K de la capa inferior no puede ser demasiado grande, de lo contrario el punto de detección de tiempo puede saltarse directamente y no habrá disparador.


Relacionados

Más.