Strategi ini adalah sistem perdagangan yang menggabungkan Exponential Moving Average (EMA) dan Cumulative Volume Period (CVP). Strategi ini menangkap titik pembalikan tren pasar dengan menganalisis crossover antara harga EMA dan harga tertimbang volume kumulatif. Strategi ini mencakup filter waktu built-in untuk membatasi sesi perdagangan dan mendukung penutupan posisi otomatis pada akhir periode perdagangan.
Logika inti dari strategi ini didasarkan pada perhitungan kunci berikut:
Ini adalah strategi perdagangan kuantitatif dengan struktur lengkap dan logika yang jelas. Dengan menggabungkan keuntungan dari EMA dan CVP, ini menciptakan sistem perdagangan yang dapat menangkap tren dan fokus pada pengendalian risiko. Strategi ini sangat dapat disesuaikan dan cocok untuk digunakan di lingkungan pasar yang berbeda.
/*backtest start: 2019-12-23 08:00:00 end: 2025-01-04 08:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 // © sapphire_edge // # ========================================================================= # // # // # _____ __ _ ______ __ // # / ___/____ _____ ____ / /_ (_)_______ / ____/___/ /___ ____ // # \__ \/ __ `/ __ \/ __ \/ __ \/ / ___/ _ \ / __/ / __ / __ `/ _ \ // # ___/ / /_/ / /_/ / /_/ / / / / / / / __/ / /___/ /_/ / /_/ / __/ // # /____/\__,_/ .___/ .___/_/ /_/_/_/ \___/ /_____/\__,_/\__, /\___/ // # /_/ /_/ /____/ // # // # ========================================================================= # strategy(shorttitle="⟡Sapphire⟡ EMA/CVP", title="[Sapphire] EMA/CVP Strategy", initial_capital= 50000, currency= currency.USD,default_qty_value = 1,commission_type= strategy.commission.cash_per_contract,overlay= true ) // # ========================================================================= # // # // Settings Menu // // # ========================================================================= # // -------------------- Main Settings -------------------- // groupEMACVP = "EMA / Cumulative Volume Period" tradeDirection = input.string(title='Trade Direction', defval='LONG', options=['LONG', 'SHORT'], group=groupEMACVP) emaLength = input.int(25, title='EMA Length', minval=1, maxval=200, group=groupEMACVP) cumulativePeriod = input.int(100, title='Cumulative Volume Period', minval=1, maxval=200, step=5, group=groupEMACVP) exitType = input.string(title="Exit Type", defval="Crossover", options=["Crossover", "Custom CVP" ], group=groupEMACVP) cumulativePeriodForClose = input.int(50, title='Cumulative Period for Close Signal', minval=1, maxval=200, step=5, group=groupEMACVP) showSignals = input.bool(true, title="Show Signals", group=groupEMACVP) signalOffset = input.int(5, title="Signal Vertical Offset", group=groupEMACVP) // -------------------- Time Filter Inputs -------------------- // groupTimeOfDayFilter = "Time of Day Filter" useTimeFilter1 = input.bool(false, title="Enable Time Filter 1", group=groupTimeOfDayFilter) startHour1 = input.int(0, title="Start Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter) startMinute1 = input.int(0, title="Start Minute", minval=0, maxval=59, group=groupTimeOfDayFilter) endHour1 = input.int(23, title="End Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter) endMinute1 = input.int(45, title="End Minute", minval=0, maxval=59, group=groupTimeOfDayFilter) closeAtEndTimeWindow = input.bool(false, title="Close Trades at End of Time Window", group=groupTimeOfDayFilter) // -------------------- Trading Window -------------------- // isWithinTradingWindow(startHour, startMinute, endHour, endMinute) => nyTime = timestamp("America/New_York", year, month, dayofmonth, hour, minute) nyHour = hour(nyTime) nyMinute = minute(nyTime) timeInMinutes = nyHour * 60 + nyMinute startInMinutes = startHour * 60 + startMinute endInMinutes = endHour * 60 + endMinute timeInMinutes >= startInMinutes and timeInMinutes <= endInMinutes timeCondition = (useTimeFilter1 ? isWithinTradingWindow(startHour1, startMinute1, endHour1, endMinute1) : true) // Check if the current bar is the last one within the specified time window isEndOfTimeWindow() => nyTime = timestamp("America/New_York", year, month, dayofmonth, hour, minute) nyHour = hour(nyTime) nyMinute = minute(nyTime) timeInMinutes = nyHour * 60 + nyMinute endInMinutes = endHour1 * 60 + endMinute1 timeInMinutes == endInMinutes // Logic to close trades if the time window ends if timeCondition and closeAtEndTimeWindow and isEndOfTimeWindow() strategy.close_all(comment="Closing trades at end of time window") // # ========================================================================= # // # // Calculations // // # ========================================================================= # avgPrice = (high + low + close) / 3 avgPriceVolume = avgPrice * volume cumulPriceVolume = math.sum(avgPriceVolume, cumulativePeriod) cumulVolume = math.sum(volume, cumulativePeriod) cumValue = cumulPriceVolume / cumulVolume cumulPriceVolumeClose = math.sum(avgPriceVolume, cumulativePeriodForClose) cumulVolumeClose = math.sum(volume, cumulativePeriodForClose) cumValueClose = cumulPriceVolumeClose / cumulVolumeClose emaVal = ta.ema(close, emaLength) emaCumValue = ta.ema(cumValue, emaLength) // # ========================================================================= # // # // Signal Logic // // # ========================================================================= # // Strategy Entry Conditions longEntryCondition = ta.crossover(emaVal, emaCumValue) and tradeDirection == 'LONG' shortEntryCondition = ta.crossunder(emaVal, emaCumValue) and tradeDirection == 'SHORT' // User-Defined Exit Conditions longExitCondition = false shortExitCondition = false if exitType == "Crossover" longExitCondition := ta.crossunder(emaVal, emaCumValue) shortExitCondition := ta.crossover(emaVal, emaCumValue) if exitType == "Custom CVP" emaCumValueClose = ta.ema(cumValueClose, emaLength) longExitCondition := ta.crossunder(emaVal, emaCumValueClose) shortExitCondition := ta.crossover(emaVal, emaCumValueClose) // # ========================================================================= # // # // Strategy Management // // # ========================================================================= # // Strategy Execution if longEntryCondition and timeCondition strategy.entry('Long', strategy.long) label.new(bar_index, high - signalOffset, "◭", style=label.style_label_up, color = color.rgb(119, 0, 255, 20), textcolor=color.white) if shortEntryCondition and timeCondition strategy.entry('Short', strategy.short) label.new(bar_index, low + signalOffset, "⧩", style=label.style_label_down, color = color.rgb(255, 85, 0, 20), textcolor=color.white) if strategy.position_size > 0 and longExitCondition strategy.close('Long') if strategy.position_size < 0 and shortExitCondition strategy.close('Short') // # ========================================================================= # // # // Plots and Charts // // # ========================================================================= # plot(emaVal, title='EMA', color=color.new(color.green, 25)) plot(emaCumValue, title='Cumulative EMA', color=color.new(color.purple, 35)) fill(plot(emaVal), plot(emaCumValue), color=emaVal > emaCumValue ? #008ee6 : #d436a285, title='EMA and Cumulative Area', transp=70)