0bps

Strategy vault / Machine learning

Johns Bitcoin Intraday Trading Strategy Based on Multiple Indicators

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.

Author
ChaoZhang
Complexity
Intermediate · 110 lines
Parameters
24
Backtest bar
1m · intraday
Tested on
BTC/USDT · futures

IMG

Overview

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.

Conclusion

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.

Parameters

NameDefaultWhat it controls
v_input_int_1trueFrom Day
v_input_int_2trueFrom Month
v_input_int_32021From Year
v_input_int_4trueTo Day
v_input_int_5trueTo Month
v_input_int_62025To Year
v_input_float_12.1Stop Loss Profit (%)
v_input_int_723Max MF
v_input_int_880Min MF
v_input_180OverBought_StochRSI
v_input_234OverSold_StochRSI
v_input_int_93K
v_input_int_102D
v_input_int_1114RSI Length
v_input_int_1214Stochastic Length
v_input_3_close0RSI Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_412Fast Length
v_input_526Slow Length
v_input_6_close0Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_int_139Signal Smoothing
v_input_string_10Oscillator MA Type: EMA | SMA
v_input_string_20Signal Line MA Type: EMA | SMA
v_input_color_1#0000FFbuy
v_input_color_2#FF0000sell

Source Pine Script

/*backtest
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"}]
*/


//@version=5
strategy('John Day Stop Loss', overlay=false, pyramiding=1, default_qty_type=strategy.cash, default_qty_value=10000, initial_capital=10000, currency='USD', precision=2)
strategy.risk.allow_entry_in(strategy.direction.long) 

from_day = input.int(defval=1, title='From Day', minval=1)
from_month = input.int(defval=1, title='From Month', minval=1)
from_year = input.int(defval=2021, title='From Year', minval=2020)
to_day = input.int(defval=1, title='To Day', minval=1)
to_month = input.int(defval=1, title='To Month', minval=1)
to_year = input.int(defval=2025, 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 < input.int(defval=23, title='Max MF', minval=1)
sell_mfi = mf > input.int(defval=80, title='Min MF', minval=1)

//Stoch RSI
OverBought_StochRSI = input(80)
OverSold_StochRSI = input(34)
smoothK = input.int(3, "K", minval=1)
smoothD = input.int(2, "D", minval=1)
lengthRSI = input.int(14, "RSI Length", minval=1)
lengthStoch = input.int(14, "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")

//MACD
// 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 = input.int(title="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
    	
bgcolor(sessionColor)

Published by ChaoZhang on the FMZ strategy square · last modified 2023-12-07. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Johns-Bitcoin-Intraday-Trading-Strategy-Based-on-Multiple-Indicators.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open