El rango promedio de fluctuación verdadera (ATR) se utiliza para medir la intensidad de la volatilidad del mercado, mostrando la variabilidad del mercado, pero no refleja la estabilidad de la dirección de los precios y la tendencia.
El valor medio de la oscilación real se calcula a partir de la oscilación real de los últimos N días y de la oscilación real del mismo día. La raíz de la oscilación real del día es la mayor diferencia entre los tres conjuntos de resultados: el precio más alto del día - el precio más bajo del día; el precio más alto del día - el precio de cierre del día anterior; el precio más alto del día - el precio de cierre del día anterior.
El índice de fuerza relativa (RSI) es un indicador técnico de la tendencia del mercado futuro que se utiliza para determinar la fuerza de compra y venta de los dos extremos de la bolsa en un período de tiempo.
RSI = 100 - (100/ ((1+RS)); RS = suma de los puntos de cierre y los puntos de caída de los n días; En general, el RSI tiene 50 como línea media, más de 50 se considera un mercado multi-head y menos de 50 se considera un mercado de cabeza baja; Un RSI mayor a 70 se considera un estado de sobrecompra, y puede haber un retroceso o un cambio en el mercado posterior. Menos de 30 es un estado de sobreventa, y puede haber un aumento posterior.
ATR se usa para filtrar, cuando ATR>ATRMa ((ATR promedio de los últimos N días) indica que la amplitud de la volatilidad del mercado ha comenzado a aumentar y que la tendencia está aumentando; RSI se utiliza para generar señales de negociación.
/*backtest start: 2021-02-11 00:00:00 end: 2022-02-10 23:59:00 period: 15m basePeriod: 5m exchanges: [{"eid":"Huobi","currency":"BCH_USDT"}] args: [["rsi_period",12],["atrma_period",18]] */ /* * rsi_period: 强弱指标计算周期 * atr_period: 平均真实波幅计算周期 * atrma_period: 平均真实波幅均值计算呢周期 * tick_interval: 时间间隔 * slide_price: 下单滑动值 */ // RSI指示操作状态 var RSI_NONE = 0; var RSI_BUY = 1; var RSI_SELL = 2; var last_rsi_staus; // ATR活跃信号判断 function isAtrActive(records) { let atr = TA.ATR(records, atr_period); let atrma = atr[atr.length - 1]; if (atr.length > atrma_period) { let tmp_atr = 0; for (let i = atr.length - atrma_period; i < atr.length; i++) { tmp_atr += atr[i]; } atrma = tmp_atr / atr_period; } else { atrma = aval(atr.join("+")) / atr.length; } return atr[atr.length - 1] > atrma; } // 获取RSI操作状态 function getRsiStatus(records) { let rsi = TA.RSI(records, rsi_period)[records.length - 1]; if (rsi < 30) { return RSI_BUY; } else if (rsi > 70) { return RSI_SELL; } else { return RSI_NONE; } } // 取消未成交下单 function canelPendingOrders() { while (true) { let orders = _C(exchange.GetOrders); if (orders.length == 0) { break; } for (let i = 0; i < orders.length; i++) { exchange.CancelOrder(orders[i].Id); } } } function onTick() { let records = _C(exchange.GetRecords, PERIOD_M15); let ticker = _C(exchange.GetTicker); if (records == null || ticker == null || records.length < rsi_period || records.length < atr_period) { return; } if (isAtrActive(records)) { let rsi = getRsiStatus(records); if (rsi != RSI_NONE) { let account = _C(exchange.GetAccount); if (rsi == RSI_BUY && last_rsi_staus != RSI_BUY) { Log("买入信号"); last_rsi_staus = RSI_BUY; canelPendingOrders(); if(account.Balance>0){ let price = ticker.Last + slide_price; let amount = account.Balance / price * 0.99; exchange.Buy(price, amount); } } else if (rsi == RSI_SELL && last_rsi_staus != RSI_SELL) { Log("卖出信号"); last_rsi_staus = RSI_SELL; canelPendingOrders(); if (account.Stocks > 0) { let price = ticker.Last - slide_price; exchange.Sell(price, account.Stocks); } } } } last_records = records; } function main() { while (true) { onTick(); Sleep(tick_interval * 1000); } }
¿Qué es esto?Error de tiempo de ejecución: abort ((undefined) at Error en jsStackTrace, esto es una tontería
Un cuchillo¿Hay alguna otra información?