// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © Halving32 // _ _ _ _ ____ ___ // | | | | | | (_) |___ \__ \ // | |__| | __ _| |_ ___ _ __ __ _ __) | ) | // | __ |/ _` | \ \ / / | '_ \ / _` ||__ < / / // | | | | (_| | |\ V /| | | | | (_| |___) / /_ // |_| |_|\__,_|_| \_/ |_|_| |_|\__, |____/____| // __/ | // |___/ //@version=6 strategy(title = '[Halving32] Estrategia ValSA', shorttitle = '[H32] Estrategia ValSA', overlay = false, initial_capital = .00372, currency = currency.BTC, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = .1, default_qty_type = strategy.percent_of_equity, calc_on_order_fills = true, risk_free_rate = 0.01) /////////////////////////////////////////////////////// //% Para que se venda por encima del precio de compra // GAIN = 'PARÁMETRO DE GANANCIA/PERDIDA POR OPERACIÓN' revenue = input.float(title = '(%) Mínimo sobre el precio de compra al cierre de la operación', group = GAIN, minval = 0.2, step = 0.1, defval = 1.5) / 100 + 1 loss = input.float(title = '(%) Máximo de perdida sobre el precio de compra al cierre de la operación', group = GAIN, maxval = 0, step = 0.1, defval = -1) / 100 + 1 /////////////////////////////////////////////////////// //MARCO DE TIEMPO // var g_strategy = 'CALENDARIO DE OPERACIONES' i_startTime = input.time(title = 'Inicio de Operaciones', defval = timestamp('04 Jan 2025 00:00 -0600'), group = g_strategy, tooltip = 'Fecha y hora para comenzar a operar') i_endTime = input.time(title = 'Final de Operaciones', defval = timestamp('01 Jan 2029 00:00 -0600'), group = g_strategy, tooltip = 'Fecha y hora para dejar de operar') // Checar si la operacion de esta barra ocurrió dentro del filtro de fecha c_dateFilter = time >= i_startTime and time <= i_endTime /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// // CONDICIONES KONCORDE // COMPRA1 = 'CONDICIONES DE COMPRA KONCORDE, IFM, SUPER TENDENCIA Y VOLUMEN' condicion1 = input.bool(false, 'CONDICIÓN 1: Inicia la Primavera Koncord', group = COMPRA1) primavera = input.int(title = 'Nivel de primavera', group = COMPRA1, defval = 29) condicion2 = input.bool(false, 'CONDICIÓN 2: Termina el Pánico, el Pico Azul y verde en negativo empezando a subir (Posible cambio de tendencia)', group = COMPRA1) nivel_azul_p = input.int(title = 'Nivel Azul', group = COMPRA1, defval = -24, maxval = 0) nivel_verde_p = input.int(title = 'Nivel Verde', group = COMPRA1, defval = -3, maxval = 0) condicion3 = input.bool(true, 'CONDICIÓN 3: Espejo', group = COMPRA1) nivel_azul = input.int(title = 'Nivel Azul', group = COMPRA1, defval = 20) nivel_verde = input.int(title = 'Nivel Verde', group = COMPRA1, defval = -8) condicion4 = input.bool(false, 'CONDICIÓN 4: Línea Azul cruza a la media móvil hacia arriba', group = COMPRA1) nivel_azul_a = input.int(title = 'Nivel Azul', group = COMPRA1, defval = 20) condicion6 = input.bool(false, 'CONDICIÓN 5: Línea verde y marron cruzan a la media móvil hacia arriba y azul en positivo (SÓLO PARA PERIODOS < 15 min)', group = COMPRA1) var_azul = input.int(title = 'Nivel Azul por encima del 0', group = COMPRA1, defval = 5) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INDICADOR KONCORDE// initial = 100 // Definition of the function to calculate the PVI // Definición de la función para calcular el PVI var float pvi = na change_1 = ta.change(volume) pvi := na(pvi[1]) ? initial : change_1 > 0 ? pvi[1] * close / close[1] : pvi[1] // Definition of the function to calculate the NVI // Definición de la función para calcular el NVI var float nvi = na change_2 = ta.change(volume) nvi := na(nvi[1]) ? initial : change_2 < 0 ? nvi[1] * close / close[1] : nvi[1] // Definición de la función para calcular el MFI calc_mfi(length) => src = hlc3 upper = math.sum(volume * (ta.change(src) <= 0 ? 0 : src), length) lower = math.sum(volume * (ta.change(src) >= 0 ? 0 : src), length) 100.0 - 100.0 / (1.0 + upper / lower) // Cálculo de los indicadores tprice = ohlc4 lengthEMA = 255 m = 15 pvim = ta.ema(pvi, m) pvimax = ta.highest(pvim, 90) pvimin = ta.lowest(pvim, 90) oscp = (pvi - pvim) * 100 / (pvimax - pvimin) nvim = ta.ema(nvi, m) nvimax = ta.highest(nvim, 90) nvimin = ta.lowest(nvim, 90) azul = (nvi - nvim) * 100 / (nvimax - nvimin) xmf = calc_mfi(14) mult = 2 basis = ta.sma(tprice, 25) dev = mult * ta.stdev(tprice, 25) upper = basis + dev lower = basis - dev OB1 = (upper + lower) / 2.0 OB2 = upper - lower BollOsc = (tprice - OB1) / OB2 * 100 xrsi = ta.rsi(tprice, 14) calc_stoch(src, length, smoothFastD) => ll = ta.lowest(low, length) hh = ta.highest(high, length) k = 100 * (src - ll) / (hh - ll) ta.sma(k, smoothFastD) stoc = calc_stoch(tprice, 21, 3) marron = (xrsi + xmf + BollOsc + stoc / 3) / 2 verde = marron + oscp media = ta.ema(marron, m) plot(verde, color = color.new(#66FF66, 0), style = plot.style_area, title = 'verde') plot(marron, color = color.new(#FFCC99, 0), style = plot.style_area, title = 'marron') plot(azul, color = color.new(#00FFFF, 0), style = plot.style_area, title = 'azul') plot(marron, color = color.new(color.maroon, 0), style = plot.style_line, linewidth = 2, title = 'lmarron') plot(verde, color = color.new(#006600, 0), style = plot.style_line, linewidth = 2, title = 'lineav') plot(azul, color = color.new(#000066, 0), style = plot.style_line, linewidth = 2, title = 'lazul') plot(media, color = color.new(color.red, 0), title = 'media', style = plot.style_line, linewidth = 2) hline(0, color = color.black, linestyle = hline.style_solid) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INDICE DE FACILITACIÓN DE MERCADO (MFI) // r_hl = ta.roc((high - low) / volume, 1) r_v = ta.roc(volume, 1) green_f = r_hl > 1 and r_v > 1 fade_f = r_hl < 1 and r_v < 1 fake_f = r_hl > 1 and r_v < 1 squat_f = r_hl < 1 and r_v > 1 b_color = green_f ? color.green : fade_f ? color.blue : fake_f ? color.gray : squat_f ? color.purple : na // INDICE DE FLUJO MONETARIO (IFM) // IFM = 'INDICE DE FLUJO MONETARIO' condicion5 = input.bool(false, 'CONDICIÓN 6: Indice de Flujo Monetario en Sobreventa con barra de volumen superior al promedio', group = IFM) // Input for IFM lengthIFM = input.int(title = 'Periodos', group = IFM, defval = 14, minval = 1, maxval = 2000) overbought = input.int(title = 'Nivel de Sobrecompra', group = IFM, defval = 80, minval = 1, maxval = 100) oversold = input.int(title = 'Nivel de Sobreventa', group = IFM, defval = 5, minval = 1, maxval = 100) // Calculate IFM src = hlc3 mf = ta.mfi(src, lengthIFM) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // VOLUME CON MEDIAS PROMEDIO DE 3 Y 50 PERIODOS // VOLPROM = 'VOLUMEN PROMEDIO' // Input for MAVOL periods mavol1_period = input.int(1, group = VOLPROM, title = 'Número de Periodos VOL1') mavol2_period = input.int(50, group = VOLPROM, title = 'Número de Periodos VOL2') multiplo = input.float(2, group = VOLPROM, title = 'Multiplo Volumen/Vol2', step = 0.1) // Calculate MAVOLs mavol1 = ta.sma(volume, mavol1_period) mavol2 = ta.sma(volume, mavol2_period) mavol = mavol1 / mavol2 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INDICADOR SUPERTREND// STREND = 'SUPERTREND' atrPeriod = input.int(89, 'ATR Length', group = STREND, minval = 1) factor = input.float(0.5, 'Factor', group = STREND, minval = 0.5, step = 0.5) [supertrend, direction] = ta.supertrend(factor, atrPeriod) supertrend := barstate.isfirst ? na : supertrend upTrend = plot(direction < 0 ? supertrend : na, 'Up Trend', color = color.green, linewidth = 2, force_overlay = true, style = plot.style_linebr) downTrend = plot(direction < 0 ? na : supertrend, 'Down Trend', color = color.red, linewidth = 2, force_overlay = true, style = plot.style_linebr) bodyMiddle = plot(barstate.isfirst ? na : (open + close) / 2, 'Body Middle', linewidth = 2, force_overlay = true, display = display.none) plotshape(direction[1] > direction ? supertrend : na, title = 'UpTrend Begins', location = location.absolute, style = shape.circle, force_overlay = true, size = size.tiny, color = color.green) plotshape(direction[1] < direction ? supertrend : na, title = 'DownTrend Begins', location = location.absolute, style = shape.circle, force_overlay = true, size = size.tiny, color = color.red) fill(bodyMiddle, upTrend, color.new(color.green, 90), fillgaps = false) fill(bodyMiddle, downTrend, color.new(color.red, 90), fillgaps = false) // Inputs para los períodos de las medias móviles smaLength = 28 emaLength = 14 // Cálculo de las medias móviles smaValue = ta.sma(close, smaLength) emaValue = ta.ema(close, emaLength) // Graficar las medias móviles plot(smaValue, color = color.purple, force_overlay = true, title = 'SMA') plot(emaValue, color = color.blue, force_overlay = true, title = 'EMA') // Condiciones para colorear las barras bullishTrend = emaValue > smaValue bearishTrend = emaValue < smaValue // Colorear las barras //barcolor(bullishTrend ? color.blue : bearishTrend ? color.red : na) /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// MERCADO = 'INDICE DE FACILITACIÓN DEL MERCADO' circles = input.bool(true, 'Mostrar señales de facilitación del mercado', group = MERCADO) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Variable para marcar el precio de compra y venta var float precioCompra = na // Variables globales para almacenar los resultados de ta.crossover() var bool azulCruzaMedia = false var bool mediaCruzaVerde = false var bool mediaCruzaMarron = false // Actualización de las variables en cada barra azulCruzaMedia := ta.crossover(azul, media) mediaCruzaVerde := ta.crossover(media, verde) mediaCruzaMarron := ta.crossover(media, marron) /////////////////////////////////////////////////////// // Entry Conditions // /////////////////////////////////////////////////////// f = if condicion1 buySignal1 = verde > (marron + primavera) and azul > 1 buySignal1 g = if condicion2 buySignal2 = azul[2] > azul[1] and azul[1] < azul[0] and verde[1] < verde[0] and azul < nivel_azul_p and verde < nivel_verde_p buySignal2 j = if condicion3 buySignal3 = azul > nivel_azul and verde < nivel_verde and direction[1] > direction buySignal3 k = if condicion4 buySignal4 = ta.crossover(azul, media) and azul < nivel_azul_a buySignal4 l = if condicion5 buySignal5 = mf <= oversold and mavol >= multiplo buySignal5 o = if condicion6 buySignal6 = media < verde and media < marron and azul > var_azul buySignal6 /////////////////////////////////////////////////////// // CONKORD Condiciones de Salida // ////////////////////////////////////////////////////// VENTA = 'CONDICIONES PARA CERRAR UNA ORDEN DE COMPRA' condicion9 = input.bool(true, 'CIERRE 1: Verde cruza hacia abajo Media', group = VENTA) q = if condicion9 salidaCondicion9 = ta.crossover(media, verde) //and close > precioCompra * revenue salidaCondicion9 condicion10 = input.bool(true, 'CIERRE 2: Marrón cruza hacia abajo Media', group = VENTA) r = if condicion10 salidaCondicion10 = ta.crossover(media, marron) //and close > precioCompra * revenue salidaCondicion10 condicion11 = input.bool(true, 'CIERRE 3: Termina microtendencia alcista', group = VENTA) s = if condicion11 salidaCondicion11 = direction[1] < direction //and close > precioCompra * revenue salidaCondicion11 condicion12 = input.bool(false, 'STOP LOSS 1: Cualquiera de las condiciones de cierre anteriores sin tomar en cuenta el precio de compra', group = VENTA) t = if condicion12 salidaCondicion12 = direction[1] < direction or mediaCruzaMarron or mediaCruzaVerde salidaCondicion12 condicion13 = input.bool(false, 'STOP LOSS 2: de emergencia (Termina microtendencia Alcista y tiburones estan vendiendo) ¡QUITARLO EN CUANTO SE EJECUTE LA INSTRUCCIÓN!', group = VENTA) u = if condicion13 salidaCondicion13 = direction[1] < direction and azul < -1 salidaCondicion13 condicion14 = input.bool(false, 'STOP LOSS 3: de emergencia (Se alcanzó el máximo % de pérdidas)', group = VENTA) x = if condicion14 salidaCondicion14 = close < precioCompra * loss salidaCondicion14 /////////////////////////////////////////////////////// // Filtro para que no se repitan señales de compra o venta consecutivamente // /////////////////////////////////////////////////////// var bool buyConditionMet = false /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// // Verificación para que no se repitan señales de compra o venta consecutivamente // /////////////////////////////////////////////////////// longCondition = (f or g or j or k or l or o) and c_dateFilter and not buyConditionMet shortCondition = (q or r or s or t or u or x) and c_dateFilter and buyConditionMet and close > precioCompra * revenue /////////////////////////////////////////////////////// /// Órdenes de compra y venta con ALERTAS AÑADIDAS /////////////////////////////////////////////////////// if longCondition precioCompra := close buyConditionMet := true strategy.entry('Long', strategy.long) // Nueva alerta que se dispara junto con la orden de entrada alert("Compra ValSA: Señal de entrada detectada", alert.freq_once_per_bar_close) if shortCondition buyConditionMet := false strategy.close('Long') // Nueva alerta que se dispara junto con el cierre de la orden alert("Venta ValSA: Señal de salida detectada", alert.freq_once_per_bar_close) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Marcando de las Barras según el índice de facilitación del mercado en el gráfico w = if circles buyConditionMet plotshape(w, 'Buy Signal', shape.circle, location.belowbar, b_color, force_overlay = true, size = size.tiny) // Color de las barras según el índice de facilitación del mercado barcolor(b_color) // Alerts alertcondition(longCondition, title="Comprar", message="Compra ahora") alertcondition(shortCondition, title="Vender", message="Vende ahora") // Plot buy and sell labels plotshape(longCondition, title = 'Compra', style = shape.labelup, location = location.belowbar, color = #edf11e, text = 'Buy', textcolor = color.black, force_overlay = true, size = size.small) plotshape(shortCondition, title = 'Venta', style = shape.labeldown, location = location.abovebar, color = color.white, text = 'Sell', textcolor = color.black, force_overlay = true, size = size.small) /////////////////////////////////////////////////////// // COMPARACIÓN DE PRECIO PROMEDIO ENTRE EXCHANGES // /////////////////////////////////////////////////////// EXCHANGE_COMP = 'COMPARACIÓN DE EXCHANGES' // Inputs para activar/desactivar cada media show_binance = input.bool(false, 'Mostrar Precio Promedio de Binance (1P)', group = EXCHANGE_COMP) show_current = input.bool(false, 'Mostrar Precio Promedio de Exchange Actual (1P)', group = EXCHANGE_COMP) // Obtener precio promedio de Binance de 1 periodo binance_symbol = 'BINANCE:' + syminfo.ticker binance_avg_price = request.security(binance_symbol, timeframe.period, ta.sma(close, 1), barmerge.gaps_off, barmerge.lookahead_off) // Obtener precio promedio de la exchange actual del gráfico de 1 periodo current_symbol = syminfo.tickerid current_avg_price = request.security(current_symbol, timeframe.period, ta.sma(close, 1), barmerge.gaps_off, barmerge.lookahead_off) // Graficar ambas medias solo si están activadas plot(show_binance ? binance_avg_price : na, color = color.new(color.yellow, 0), force_overlay = true, title = 'Binance Avg Price 1P', linewidth = 2) plot(show_current ? current_avg_price : na, color = color.new(color.orange, 0), force_overlay = true, title = 'Current Exchange Avg Price 1P', linewidth = 2)