John's Bitcoin Intraday Trading Strategy Based on Multiple Indicators

Author: ChaoZhang, Date: 2023-12-07 15:23:44



This strategy combines RSI, MFI, Stoch RSI and MACD four indicators to implement bitcoin intraday trading. Orders will only be placed when multiple indicators give buy or sell signals simultaneously to control risks.

Strategy Logic

  1. The RSI indicator is used to determine whether the market is overbought or oversold. It generates a buy signal when RSI is below 40 and a sell signal when RSI is above 70.

  2. The MFI indicator judges the capital flow in the market. It generates a buy signal when MFI is below 23 and a sell signal when MFI is above 80.

  3. The Stoch RSI indicator determines whether the market is overbought or oversold. It generates a buy signal when the K line is below 34 and a sell signal when above 80.

  4. The MACD indicator judges the market trend and momentum. It generates a buy signal when the fast line is below the slow line and the histogram is negative, and a sell signal for the opposite scenario.

Advantage Analysis

  1. Combining four major indicators improves signal accuracy and avoids losses caused by the failure of a single indicator.

  2. Orders are placed only when multiple indicators give signals simultaneously, which greatly reduces the probability of false signals.

  3. Adopting intraday trading strategies avoids overnight risks and reduces capital costs.

Risks and Solutions

  1. The strategy’s trading frequency may be relatively low, with certain time risks. Indicator parameters can be appropriately relaxed to increase the number of trades.

  2. There is still a probability that indicators may give wrong signals. Machine learning algorithms can be introduced to assist in judging the reliability of indicator signals.

  3. There are some overbought and oversold risks. Indicator parameters can be adjusted accordingly or more indicator logic can be added.

Optimization Directions

  1. Add adaptive indicator parameter functionality. Adjust indicator parameters in real time based on market volatility and change speed.

  2. Add stop loss logic. Exit stop loss if losses exceed a certain percentage to effectively control single loss.

  3. Incorporate sentiment indicators. Increase multidimensional judgments such as market heat and market fear to improve strategy profit space.


By verifying signals through four major indicators, this strategy can effectively reduce the false signal rate and is a relatively stable high-frequency profit strategy. With continuous optimization of parameters and models, the strategy’s win rate and profitability can be further improved.

start: 2023-11-29 00:00:00
end: 2023-12-06 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy('John Day Stop Loss', overlay=false, pyramiding=1,, default_qty_value=10000, initial_capital=10000, currency='USD', precision=2)

from_day =, title='From Day', minval=1)
from_month =, title='From Month', minval=1)
from_year =, title='From Year', minval=2020)
to_day =, title='To Day', minval=1)
to_month =, title='To Month', minval=1)
to_year =, title='To Year', minval=2020)

time_cond = time > timestamp(from_year, from_month, from_day, 00, 00) and time < timestamp(to_year, to_month, to_day, 00, 00)
//time_cond = true

//Stop Loss
longProfitPerc = input.float(title="Stop Loss Profit (%)", defval=2.1) / 100
longExitPrice  = strategy.position_avg_price * (1 - longProfitPerc)

//RSI - yellow
up = ta.rma(math.max(ta.change(close), 0), 14)
down = ta.rma(-math.min(ta.change(close), 0), 14)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
plot(rsi, "RSI", color=#00FFFF)
buy_rsi = true // rsi < 40
sell_rsi = true //rsi > 70

//MFI - cyan
mf = ta.mfi(hlc3, 14)
plot(mf, "MF", color=#FFFF00)
buy_mfi = mf <, title='Max MF', minval=1)
sell_mfi = mf >, title='Min MF', minval=1)

//Stoch RSI
OverBought_StochRSI = input(80)
OverSold_StochRSI = input(34)
smoothK =, "K", minval=1)
smoothD =, "D", minval=1)
lengthRSI =, "RSI Length", minval=1)
lengthStoch =, "Stochastic Length", minval=1)
srcRSI = input(close, title="RSI Source")
rsi1 = ta.rsi(srcRSI, lengthRSI)
kStochRSI = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = ta.sma(kStochRSI, smoothD)
co = ta.crossover(kStochRSI,d)
cu = ta.crossunder(kStochRSI,d)

buy_stochRSI = co and kStochRSI < OverSold_StochRSI
sell_stochRSI = cu and kStochRSI > OverBought_StochRSI

plot(kStochRSI, "K", color=#2962FF)
plot(d, "D", color=#FF6D00)
h0 = hline(OverBought_StochRSI, "Upper Band", color=#787B86)
h1 = hline(OverSold_StochRSI, "Lower Band", color=#787B86)
fill(h0, h1, color=color.rgb(33, 150, 243, 90), title="Background")

// Getting inputs
fast_length = input(title="Fast Length", defval=12)
slow_length = input(title="Slow Length", defval=26)
src = input(title="Source", defval=close)
signal_length ="Signal Smoothing",  minval = 1, maxval = 50, defval = 9)
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"])
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"])
// Plot colors
//col_macd = input(#2962FF, "MACD Line  ", group="Color Settings", inline="MACD")
//col_signal = input(#FF6D00, "Signal Line  ", group="Color Settings", inline="Signal")
//col_grow_above = input(#26A69A, "Above   Grow", group="Histogram", inline="Above")
//col_fall_above = input(#B2DFDB, "Fall", group="Histogram", inline="Above")
//col_grow_below = input(#FFCDD2, "Below Grow", group="Histogram", inline="Below")
//col_fall_below = input(#FF5252, "Fall", group="Histogram", inline="Below")
// Calculating
fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal
buy_MACD = macd < signal and hist < 0 
sell_MACD = macd > signal and hist > 0 

//buy_MACD = true 
//sell_MACD = true

//plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below)))
//plot(macd, title="MACD", color=col_macd)
//plot(signal, title="Signal", color=col_signal)

sessionColor = color(na)
if time_cond

    if (not na(kStochRSI) and not na(d))
        cmt = str.tostring(close)
    	if (buy_stochRSI and buy_MACD and buy_mfi and buy_rsi)
    		strategy.entry("BUY", strategy.long, comment='BUY @ ' + cmt)
    		if longProfitPerc != 0
    		    strategy.exit(id="x", stop=longExitPrice, comment='EXIT @ ' + str.tostring(longExitPrice))
        	sessionColor := input.color(#0000FF, "buy") //red
    	if (sell_stochRSI and sell_MACD and sell_mfi and sell_rsi)
    		strategy.entry("SELL", strategy.short, comment='SELL @ ' + cmt)
    		sessionColor := input.color(#FF0000, "sell") //green