Bitcoin Momentum Strategy
This Pine Script lesson breaks down the source code to a Bitcoin Momentum trading system which achieves a +15,000% return with only a -34% max drawdown.
Check out my other free lessons!Source Code
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=5 strategy("Bitcoin Momentum Strategy", overlay=true, initial_capital=10000, currency=currency.USDT, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1) // Get user input var const string G_STRATEGY = "Strategy Entry Settings" var const string G_EXIT = "Strategy Exit Settings" var const string G_FILTER = "Strategy Filters" i_HigherTimeframe = input.timeframe("W", "Higher Timeframe", group=G_STRATEGY, tooltip="Higher timeframe MA reference") i_EmaLength = input.int(20, "EMA Length", group=G_STRATEGY, tooltip="Moving average period length") i_AtrLength = input.int(5, "ATR Length", group=G_STRATEGY, tooltip="ATR period length") i_TrailStopSource = input.source(low, "Trail Stop Source", group=G_EXIT, tooltip="Lowest price source for trailing stop") i_TrailStopLookback = input.int(7, "Trail Stop Lookback", group=G_EXIT, tooltip="How many bars to look back for trailing price source") i_TrailStopMulti = input.float(0.2, "Trailing Stop Ratchet Multiplier", group=G_EXIT, tooltip="When momentum is yellow (caution), shrink ATR distance for TS by this much") i_StartTime = input.time(timestamp("01 Jan 2000 13:30 +0000"), "Start Filter", group=G_FILTER, tooltip="Start date & time to begin searching for setups") i_EndTime = input.time(timestamp("1 Jan 2099 19:30 +0000"), "End Filter", group=G_FILTER, tooltip="End date & time to stop searching for setups") // Define custom security function which does not repaint RequestSecurity_NonRP(_market, _res, _exp) => request.security(_market, _res, _exp[barstate.isrealtime ? 1 : 0])[barstate.isrealtime ? 0 : 1] // Define date filter check DateFilter(int start, int end) => time >= start and time <= end // Get indicator values float atrValue = ta.atr(i_AtrLength) float emaValue = ta.ema(close, i_EmaLength) float htfEmaValue = RequestSecurity_NonRP(syminfo.tickerid, i_HigherTimeframe, emaValue) // Check if trading timeframe price is above higher timeframe EMA float marketPrice = close bool isBullish = marketPrice > htfEmaValue //+ (atrValue * 0.25) // Check for bearish volatility caution bool isCaution = isBullish and (ta.highest(high, 7) - low > (atrValue * 1.5) or close < emaValue) // Set momentum color color bgCol = color.red if isBullish[1] bgCol := color.green if isCaution[1] bgCol := color.orange // Handle strategy entry, and reset trailing stop var float trailStop = na if isBullish and strategy.position_size == 0 and DateFilter(i_StartTime, i_EndTime) and not isCaution strategy.entry(id="Buy", direction=strategy.long) trailStop := na // Update trailing stop float temp_trailStop = ta.highest(i_TrailStopSource, i_TrailStopLookback) - (isCaution[1] ? atrValue * i_TrailStopMulti : atrValue) if strategy.position_size > 0 if temp_trailStop > trailStop or na(trailStop) trailStop := temp_trailStop // Handle strategy exit if (close < trailStop or close < htfEmaValue) and barstate.isconfirmed strategy.close("Buy", comment="Sell") // Draw trailing stop, HTF EMA and color-coded momentum indicator plotshape(true, color=bgCol, style=shape.square, location=location.bottom, size=size.auto, title="Momentum Strength") plot(htfEmaValue, color=close > htfEmaValue ? color.green : color.red, linewidth=2, title="HTF EMA") plot(strategy.position_size[1] > 0 ? trailStop : na, style=plot.style_linebr, color=color.red, title="Stop Loss")