이 전략은 볼링거 밴드 및 촛불 패턴 분석을 기반으로 한 거래 시스템으로, 매일 시간 프레임에서 가격 변동성과 촛불 특성을 분석하여 시장 반전을 포착하도록 설계되었습니다. 핵심 방법론은 볼링거 밴드
이 전략은 표준편차 인수 2.0를 가진 주요 기술 지표로 20주기 볼링거 밴드를 사용한다. 촛불 그림자와 몸 사이의 비율을 계산함으로써, 이 비율이 설정된 임계 (1.0 기본값) 를 초과하고 가격이 볼링거 밴드 경계에 닿을 때 거래 신호를 생성한다. 엔트리 타이밍은 매일 폐쇄, 다음 날 오픈, 매일 최고 또는 낮에서 유연하게 선택할 수 있다. 이 전략은 역동적인 포지션 사이징을 통해 위험을 제어하는 계정 잔액에 기반한 리스크 관리 시스템을 포함한다. 스톱-러스는 최근 스윙 최고 또는 최저점에 설정되며, 반대편의 볼링거 밴드에서 수익을 취하는 목표를 설정한다.
이 전략은 포괄적 인 분석 프레임워크와 강력한 리스크 관리 시스템에서 강점을 찾을 수 있습니다. 시장 조건과 매개 변수 선택 영향에주의를 기울여야합니다. 제안 된 최적화 방향을 통해 전략의 안정성과 신뢰성을 더욱 향상시킬 수 있습니다. 라이브 거래 구현을 위해 구체적인 거래 도구 특성에 따라 조정을 통해 철저한 백테스팅과 매개 변수 최적화를 권장합니다.
/*backtest start: 2023-11-29 00:00:00 end: 2024-11-28 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("Trade Entry Detector, based on Wick to Body Ratio when price tests Bollinger Bands", overlay=true, default_qty_type=strategy.fixed) // Input for primary analysis time frame timeFrame = "D" // Daily time frame // Bollinger Band settings length = input.int(20, title="Bollinger Band Length", minval=1) mult = input.float(2.0, title="Standard Deviation Multiplier", minval=0.1) source = input(close, title="Source") // Entry ratio settings wickToBodyRatio = input.float(1.0, title="Minimum Wick-to-Body Ratio", minval=0) // Order Fill Timing Option fillOption = input.string("Daily Close", title="Order Fill Timing", options=["Daily Close", "Daily Open", "HOD", "LOD"]) // Account and risk settings accountBalance = 100000 // Account balance in dollars riskPercentage = 1.0 // Risk percentage per trade riskAmount = (riskPercentage / 100) * accountBalance // Fixed 1% risk amount // Request daily data for calculations dailyHigh = request.security(syminfo.tickerid, timeFrame, high) dailyLow = request.security(syminfo.tickerid, timeFrame, low) dailyClose = request.security(syminfo.tickerid, timeFrame, close) dailyOpen = request.security(syminfo.tickerid, timeFrame, open) // Calculate Bollinger Bands on the daily time frame dailyBasis = request.security(syminfo.tickerid, timeFrame, ta.sma(source, length)) dailyDev = mult * request.security(syminfo.tickerid, timeFrame, ta.stdev(source, length)) dailyUpperBand = dailyBasis + dailyDev dailyLowerBand = dailyBasis - dailyDev // Calculate the body and wick sizes on the daily time frame dailyBodySize = math.abs(dailyOpen - dailyClose) dailyUpperWickSize = dailyHigh - math.max(dailyOpen, dailyClose) dailyLowerWickSize = math.min(dailyOpen, dailyClose) - dailyLow // Conditions for a candle with an upper wick or lower wick that touches the Bollinger Bands upperWickCondition = (dailyUpperWickSize / dailyBodySize >= wickToBodyRatio) and (dailyHigh > dailyUpperBand) lowerWickCondition = (dailyLowerWickSize / dailyBodySize >= wickToBodyRatio) and (dailyLow < dailyLowerBand) // Define the swing high and swing low for stop loss placement var float swingLow = na var float swingHigh = na if (ta.pivothigh(dailyHigh, 5, 5)) swingHigh := dailyHigh[5] if (ta.pivotlow(dailyLow, 5, 5)) swingLow := dailyLow[5] // Determine entry price based on chosen fill option var float longEntryPrice = na var float shortEntryPrice = na if lowerWickCondition longEntryPrice := fillOption == "Daily Close" ? dailyClose : fillOption == "Daily Open" ? dailyOpen : fillOption == "HOD" ? dailyHigh : dailyLow if upperWickCondition shortEntryPrice := fillOption == "Daily Close" ? dailyClose : fillOption == "Daily Open" ? dailyOpen : fillOption == "HOD" ? dailyHigh : dailyLow // Execute the long and short entries with expiration var int longOrderExpiry = na var int shortOrderExpiry = na if not na(longEntryPrice) longOrderExpiry := bar_index + 2 // Order expires after 2 days if not na(shortEntryPrice) shortOrderExpiry := bar_index + 2 // Order expires after 2 days // Check expiration and execute orders if (longEntryPrice and bar_index <= longOrderExpiry and high >= longEntryPrice) longStopDistance = close - nz(swingLow, close) longPositionSize = longStopDistance > 0 ? riskAmount / longStopDistance : na if (not na(longPositionSize)) strategy.entry("Long", strategy.long, qty=longPositionSize) longEntryPrice := na // Reset after entry if (shortEntryPrice and bar_index <= shortOrderExpiry and low <= shortEntryPrice) shortStopDistance = nz(swingHigh, close) - close shortPositionSize = shortStopDistance > 0 ? riskAmount / shortStopDistance : na if (not na(shortPositionSize)) strategy.entry("Short", strategy.short, qty=shortPositionSize) shortEntryPrice := na // Reset after entry // Exit logic: hit the opposing Bollinger Band if (strategy.position_size > 0) // Long position strategy.exit("Exit Long", "Long", limit=dailyUpperBand) else if (strategy.position_size < 0) // Short position strategy.exit("Exit Short", "Short", limit=dailyLowerBand) if (strategy.position_size > 0) // Long position strategy.exit("Stop Loss Long", "Long", stop=swingLow) else if (strategy.position_size < 0) // Short position strategy.exit("Stop Loss Short", "Short", stop=swingHigh) // Plot daily Bollinger Bands and levels on the chosen time frame plot(dailyUpperBand, color=color.blue, linewidth=1, title="Daily Upper Bollinger Band") plot(dailyLowerBand, color=color.blue, linewidth=1, title="Daily Lower Bollinger Band") plot(dailyBasis, color=color.gray, linewidth=1, title="Daily Middle Bollinger Band")