Te llevará al mundo de la cuantificación ---- MACD operación bidireccional de control deslizante análisis de código stop-loss

El autor:Un sueño pequeño., Creado: 2016-04-22 13:53:14, Actualizado: 2023-06-14 10:38:59

Te llevará al mundo de la cuantificación ---- MACD operación bidireccional de control deslizante análisis de código stop-loss

En el artículo anterior, nos dimos cuenta de las estrategias de simplificación de la cuantificación de 30 líneas de código, y en este artículo, el autor nos llevará paso a paso a los principiantes de la cuantificación para acercarse más al placer de diseñar estrategias de cuantificación. El texto continúa diciendo que esta vez se trata de una transacción de BTC en el momento, y que el autor es completamente ignorante en materia de finanzas, inversiones, valores, etc.; incluso no entiende el proceso de negociación de futuros. Y es más, los ojos deslumbrados, los nombres desconocidos, los términos confundidos, y la cabeza aturdida (¡que también es un poco entendido! Después de leer el contenido, tengo en mente los conceptos básicos, combinados con mi lenguaje de JS con un poco de conocimiento, escribo un simple. En pocas palabras, la línea K es un registro del mercado en un período determinado, que facilita la observación de la dinámica del mercado. La línea media es el indicador utilizado en el artículo anterior y, al igual que el indicador MACD, es un indicador que refleja la tendencia del mercado. Los conceptos, algoritmos, formulaciones de derivación, etc. de estos dos indicadores se describen de manera diferente. Si no entiende, consulte Baidu.

El código contiene las siguientes variables globales, las reglas antiguas, explicación por explicación, las viejas aves pueden ignorarse.

Nombre de la variable Valores iniciales Explicación
Intervalo de tiempo 2000 Esta variable es el ciclo de consulta, es decir, la cantidad de tiempo que el programa espera para suspenderse, la unidad es de milisegundos, 1000 milisegundos es de 1 segundo, por lo que la variable tiene un valor inicial de 2 segundos.
Estado libre 0 Esta es una variable de estado que indica el espacio libre.
El estado_comprar 1 Esta es una variable de estado que indica que se tiene una posición múltiple.
El estado de la venta 2 Variable de estado, que indica una posición vacía.
No se puede hacer más 3 Variable de estado de almacenamiento, que indica que no está almacenado.
El número de orden es el siguiente: 4 La información es muy clara.
estado Estado libre Variable de estado, inicializado con el estado de vacío.
La señal de retraso 0 La señal se retrasó, por el momento no sirve.
StopProfit 0.002 Esta variable es más importante, la tasa de stop loss, por ejemplo, el capital * tasa de stop loss ((0.002) significa que el máximo de pérdida es de 0.002 veces el capital, el límite de pérdida.
el paso 0.5 Valor de paso de la pausa de deslizamiento. Se utiliza para elevar, bajar y clasificar los precios de pausa.
OpCantidad 1 La cantidad de operaciones fijas.
ganancia 0 ¿Qué es lo que está pasando?

Objetos globales, para registrar información de almacenamiento, que contienen algunos métodos, principalmente para implementar el stop loss deslizante.

    var holdOrder = {//持仓信息对象
	    orderState: ORDER_INVALID,// 持仓状态
	    price: 0, //持仓均价
	    amount: 0, //持仓量
	    time: null, // 操作时间
	    stopPrice: 0, // 止损价
	    level: 1,   //止损等级
	    updateCurrentProfit: function(lastPrice,amount){//更新当前盈亏
	        if(state === STATE_SELL){//当前 空头持仓
	        	return (lastPrice - this.price) * amount;
	        }
	        if(state === STATE_BUY){//当前 多头持仓
	        	return - (lastPrice - this.price) * amount;
	        }
	    },
	    SetStopPrice: function(ticker,stopState){//更新止损价
	    	if(stopState === STATE_FREE){ //更新止损时状态 为空闲
	    		return this.stopPrice;
	    	}
	    	if(stopState === STATE_BUY){ //更新止损时状态 为多仓
	            if(this.orderState === ORDER_INVALID){
	        	    return this.stopPrice;
	            }
	            if(this.stopPrice === 0){//初始 止损价为0 时 
	            	this.stopPrice = this.price * ( 1 - stopProfit );
	            }
	            if( ticker.Last <= this.price ){ //最后成交价 小于等于  持仓均价时
	                this.stopPrice = this.price * ( 1 - stopProfit );
	                this.level = 1;
	            }else{//其它情况
	        	    if( ticker.Last - this.price > this.level * step ){//超出当前等级   设置滑动止损
	                    this.stopPrice = this.price * (1 - stopProfit) + (ticker.Last - this.price );
	                    //更新止损价为滑动后的止损价
	                    this.level++;//上调止损等级
	        	    }else{//其它
	        	    	this.stopPrice = this.stopPrice;//保持当前止损价不变
	        	    }
	            }
	    	}else if( stopState === STATE_SELL){//空头持仓类似
	    		if(this.orderState === ORDER_INVALID){
	        	    return this.stopPrice;
	            }
	            if(this.stopPrice === 0){
	            	this.stopPrice = this.price * ( 1 + stopProfit );
	            }
	            if( ticker.Last >= this.price ){
	                this.stopPrice = this.price * ( 1 + stopProfit );
	                this.level = 1; 
	            }else{
	        	    if( this.price - ticker.Last > this.level * step ){
	                    this.stopPrice = this.price * (1 + stopProfit) - ( this.price - ticker.Last );
	                    this.level++;
	        	    }else{
	        	    	this.stopPrice = this.stopPrice;
	        	    }
	            }
	    	}
	        return this.stopPrice;//返回止损价
	    },
	    initHoldOrder: function(){//平仓后  用于 初始化持仓信息的  函数
	        this.orderState = ORDER_INVALID;
	        this.price = 0;
	        this.amount = 0;
	        this.time = null;
	        this.stopPrice = 0;
	        this.level = 1;
	    }
	};
  • Los que no se han unido al grupo oficial de QQ pueden unirse al grupo: 309368835 Inventor Quantification.

A continuación vamos a ver una rápida vista previa de las funciones que se utilizarán.

function MACD_Cross(){//检测MACD指标,交叉状态的函数
    var records = exchange.GetRecords();//获取K线数据
    while(!records || records.length < 45){ //K线数据不能为null,要大于45个柱,不符合标准 循环获取直到符合
    	records = exchange.GetRecords();
    	Sleep(Interval);
    }
    var macd = TA.MACD(records,12,26,9);//调用指标函数, 参数为MACD 默认的参数。
    var dif = macd[0];  //dif线
    var dea = macd[1];  //dea线
    var column = macd[2]; // MACD柱
    var len = records.length;  //K线周期长度
    if( (dif[len-1] > 0 && dea[len-1] > 0) && dif[len-1] > dea[len-1] && dif[len-2] < dea[len-2] && column[len-1] > 0.2 ){ 
    //判断金叉条件:dif 与 dea 此刻均大于0 , 且dif由下上穿dea , 且 MACD量柱大于0.2
    	return 1; //返回1  代表 金叉信号。
    }
    if( (dif[len-1] < 0 && dea[len-1] < 0) && dif[len-1] < dea[len-1] && dif[len-2] > dea[len-2] && column[len-1] < -0.2 ){
    //判断死叉条件:
        return 2;//返回2  代表 死叉信号。
    }   
    return 0;  //金叉  、死叉  信号以外,为等待信号 0 。
}
function getTimeByNormal(time){// 获取时间的 函数 把毫秒时间 转换 标准时间
    var timeByNormal = new Date();
    timeByNormal.setTime(time);
    var strTime = timeByNormal.toString();
    var showTimeArr = strTime.split(" ");
    var showTime = showTimeArr[3]+"-"+showTimeArr[1]+"-"+showTimeArr[2]+"-"+showTimeArr[4];
    return showTime;
}

A continuación se inicia la entrada a la función principal de la política, que utiliza la misma estrategia de 30 líneas de línea recta que la anterior. La biblioteca de plantillas de transacciones contiene los detalles de la transacción, los amigos interesados pueden encontrar el código en la cuantificación de los inventores, la versión de comentarios en el grupo oficial de QQ compartido, github.

function main(){
    var initAccount = $.GetAccount(exchange);//首先我们来记录初始时的账户信息,这里调用了模板类库的导出函数
    var nowAccount = initAccount;//再声明一个 变量 表示 现在账户信息
    var diffMoney = 0; //钱 差额
    var diffStocks = 0;//币 差额
    var repair = 0; //计算 盈亏时   用于修正的 量
    var ticker = exchange.GetTicker(); //获取此刻市场行情
    Log("初始账户:",initAccount); //输出显示  初始账户信息。
    while(true){//主函数循环
        scan(); //扫描函数,  稍后讲解,主要是判断  开仓、平仓 以及 操作 开仓 、 平仓。
        ticker = exchange.GetTicker();//在while循环内 获取 市场行情
        if(!ticker){//如果 没有获取到  (null) 跳过以下 重新循环
        	continue;
        }
        if(holdOrder.orderState == ORDER_VALID){//判断当前是否  持仓
        	Log("当前持仓:",holdOrder); //如果 当前持仓   输出  持仓 信息
        }
        if(holdOrder.orderState == ORDER_INVALID){//如果 未持仓(已平仓)
        	nowAccount = $.GetAccount(exchange); //获取当前账户信息
            diffMoney = nowAccount.Balance - initAccount.Balance; //计算  当前账户  与 初始账户之间的  钱 差额
            diffStocks = nowAccount.Stocks - initAccount.Stocks; // 计算  当前账户  与  初始账户之间的  币 差额
            repair = diffStocks * ticker.Last; //把 币的差额 * 最后成交价  ,转为等值的钱, 用于计算 盈亏
            LogProfit(diffMoney + repair ,"RMB","现在账户:",nowAccount,"本次盈亏:",profit);//输出 盈亏 信息
        }
    	Sleep(Interval);//轮询
    }
}

A continuación se incluyen las principales partes de la estrategia, la detección de la posición de apertura y la operación de la posición de apertura.

function scan(){
	var sellInfo = null; //声明  储存平仓信息的变量  , 初始化null
	var buyInfo = null;  //声明  开仓的 , 初始化null
	var opFun = null;//  开仓函数, 两种状态 ,  开多仓 ,  开空仓。
	var singal = 0; //信号
    while(true){//检测 及操作 循环
        var ticker = exchange.GetTicker(); //获取市场行情
        if(!ticker){ //判断 获取失败  跳过以下 ,继续循环获取
        	continue;
        }
        holdOrder.SetStopPrice(ticker,state); //设置 持仓 止损价
        if(state === STATE_FREE &&  (singal = MACD_Cross()) !== 0  ){
        	//判断策略运行状态是否空闲、此刻MACD指标信号是否空闲, 符合 策略运行状态空闲 且 有金叉或死叉执行以下
        	holdOrder.initHoldOrder();//初始化持仓信息
            opFun = singal === 1 ?  $.Buy : $.Sell ;//根据MACD_Cross函数返回结果,判断开多仓、开空仓。
            buyInfo = opFun(opAmount);//开仓操作
            holdOrder.orderState = ORDER_VALID;//设置持仓信息,状态为持仓
            holdOrder.price = buyInfo.price; //设置持仓均价  由 开仓操作函数 opFun返回。 
            holdOrder.amount = buyInfo.amount; //设置持仓量
            holdOrder.time = getTimeByNormal((new Date()).getTime());//设置持仓开始的时间
            state = singal === 1 ? STATE_BUY : STATE_SELL; //更新策略状态为多仓 或 空仓
            var account = $.GetAccount(exchange); //获取账户信息
            if(singal === 1){//输出开仓方向 和 当前账户信息
            	Log("开多仓。","账户:",account);
            }else{
                Log("开空仓。","账户:",account);
            }
            break;
        }else{
        	var lastPrice = holdOrder.price;// 把持仓均价 赋值 给 lastPrice
        	if( state === STATE_BUY && holdOrder.orderState === ORDER_VALID && ticker.Last < holdOrder.stopPrice ){
            //如果 多仓 且 持仓信息为持仓 且 最后成交价 小于止损价,执行以下
        	    Log("多头止损平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//多头止损平仓信息
        	    sellInfo = $.Sell(holdOrder.amount);//平仓
                holdOrder.orderState = ORDER_INVALID;//平仓信息 更新进对象
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);//更新浮动盈亏
        	    state = STATE_FREE;//更新状态
        	    break;//跳出
        	}
        	if( state === STATE_SELL && holdOrder.orderState === ORDER_VALID && ticker.Last > holdOrder.stopPrice ){//同上 , 这个是空头止损平仓
        	    Log("空头止损平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
        	    sellInfo = $.Buy(holdOrder.amount);
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
        	}
            if(state === STATE_BUY && MACD_Cross() === 2 ){//做多时,MACD指标死叉 -- 死叉平仓
        	    sellInfo = $.Sell(holdOrder.amount);
        	    Log("死叉平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
            }
             if(state === STATE_SELL && MACD_Cross() === 1 ){//做空时,MACD指标金叉 ---金叉平仓
        	    sellInfo = $.Buy(holdOrder.amount);
        	    Log("金叉平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
            }
        }
        Sleep(Interval);//轮询间隔,就是让程序暂停一会儿。
    }
}

El código está cansado, el agua de la boca se detiene.

Primero, el principio de la suspensión por deslizamiento.

En este código sobre el deterioro del deslizamiento, se muestra que el sistema de control de velocidad de los motores no es el único que funciona.SetStopPriceFunción de acuerdo con la transmisiónstopState(Estado de suspensión) yticker(Datos del mercado) para actualizar el precio de stop loss.stopState === STATE_BUY), para juzgar y actualizar el precio de suspensión de pérdidas en función de las diferentes situaciones.orderStatePara el estado de inactividad (es decir, no se mantiene una posición efectiva), se devuelve el precio de stop loss actual. Si el precio de stop loss es 0, se inicializa como el precio medio de compra multiplicado por(1 - stopProfit)Después, según el precio final de la transacción.ticker.LastLos precios de las acciones y de las accionesthis.priceLa diferencia entre el valor de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valores de los valoresthis.level) se compara con el multiplicador del paso (step). Si se supera el nivel actual, se actualiza el precio de stop loss como el valor después del deslizamiento, al mismo tiempo que se aumenta el nivel de stop loss; de lo contrario, se mantiene el precio de stop loss actual sin cambios.stopState === STATE_SELLLa lógica es similar, pero se toma un valor negativo de la diferencia entre el precio de la transacción final y el precio de la propiedad, y se reduce la diferencia al actualizar el precio de suspensión. Finalmente, se devuelve el precio de suspensión después de la actualización.

El stop loss deslizante es una estrategia de gestión de riesgos.

En el proceso de la tenencia, el precio del stop loss se ajusta según la fluctuación del precio del mercado para reducir las pérdidas o proteger las ganancias. Según la lógica del código, se pueden ver los siguientes puntos clave para lograr un stop slip:updateCurrentProfitEl método se utiliza para actualizar las ganancias y pérdidas actuales, calculando las ganancias y pérdidas actuales en función del estado de la posesión y el último precio. Si la posesión es un estado de venta libre (STATE_SELL), las ganancias y pérdidas se multiplican por la diferencia entre el precio más reciente y el precio de la posesión igual; si es un estado de compra múltiple (STATE_BUY), las ganancias y pérdidas son negativas. El método de SetStopPrice se utiliza para actualizar los precios de las pérdidas y pérdidas en función de los parámetros introducidos.1 - stopProfitSi el precio final de la operación excede el paso del nivel actual, el precio de la operación se establece como el precio de la operación tras el deslizamiento y se sube el nivel de la operación. En otros casos, el precio de la operación se mantiene sin cambios. Si el estado de la operación es STATE_SELL, la lógica es similar.

En este caso, el usuario puede volver a experimentar, pero recuerde referirse a la librería de transacciones de monedas digitales de Ethereum.

Fuentes de información


Relacionados

Más.

el cielo medioHola, soy el propietario de www.banbiren.com, el autor de la plataforma de movimiento de monedas, estoy aprendiendo a transaccionar cuantitativamente, mi qq es:39866099, ¿puede invitarme a unirse al grupo, antes de buscar no puedo unirme?

No hay nadaEl progreso es rápido.

MuyaEs muy duro.

Un sueño pequeño.Bien ^^, usted por el lado. Solicite directamente, MAC QQ no encontró lugar para invitar >_<, 1 grupo número: 309368835 Ahora hay varias posiciones.

Un sueño pequeño.¡Qué bueno el dedo de Dios!

Un sueño pequeño.Aprenden juntos.