Bài viết gần đây
-
-
So sánh Flutter và React Native
Tháng mười một 17, 2025 -
So sánh Flutter và React Native
Tháng mười một 17, 2025 -
Chiến lược RSI 30–70 trong Bot Auto Trading Python
Tháng mười một 17, 2025 -
Chiến Lược Giao Dịch News Filter sử dụng API Python
Tháng mười một 17, 2025
| Chiến lược RSI trong Bot Auto Trading: Thế nào là hiệu quả?
Được viết bởi thanhdt vào ngày 16/11/2025 lúc 20:53 | 8 lượt xem
Chiến lược RSI trong Bot Auto Trading: Thế nào là hiệu quả?
RSI (Relative Strength Index) là một trong những chỉ báo kỹ thuật phổ biến nhất trong trading. Tuy nhiên, không phải mọi chiến lược RSI đều hiệu quả. Trong bài viết này, chúng ta sẽ tìm hiểu các chiến lược RSI thực sự hiệu quả cho bot auto trading và cách triển khai chúng bằng Python.
1. Hiểu về RSI
RSI là chỉ báo động lượng đo lường tốc độ và độ lớn của biến động giá. RSI dao động từ 0 đến 100:
- RSI < 30: Vùng oversold (quá bán) – có thể tăng giá
- RSI > 70: Vùng overbought (quá mua) – có thể giảm giá
- RSI 30-70: Vùng trung tính
Công thức tính RSI
import pandas as pd
import numpy as np
def calculate_rsi(prices, period=14):
"""
Tính toán RSI (Relative Strength Index)
Parameters:
-----------
prices : pd.Series
Chuỗi giá đóng cửa
period : int
Chu kỳ tính toán (mặc định 14)
Returns:
--------
pd.Series
Giá trị RSI
"""
delta = prices.diff()
# Tách gain và loss
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
# Tính RS và RSI
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
2. Các chiến lược RSI hiệu quả
2.1. Chiến lược RSI Cơ bản (Oversold/Overbought)
Đặc điểm:
- Đơn giản, dễ triển khai
- Phù hợp với thị trường có xu hướng rõ ràng
- Cần kết hợp với xác nhận từ chỉ báo khác
Quy tắc:
- Mua: RSI < 30 (oversold) và bắt đầu tăng
- Bán: RSI > 70 (overbought) và bắt đầu giảm
class BasicRSIStrategy:
"""Chiến lược RSI cơ bản"""
def __init__(self, rsi_period=14, oversold=30, overbought=70):
self.rsi_period = rsi_period
self.oversold = oversold
self.overbought = overbought
def calculate_rsi(self, prices):
"""Tính RSI"""
delta = prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=self.rsi_period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=self.rsi_period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
def generate_signals(self, df):
"""
Tạo tín hiệu giao dịch
Returns:
--------
pd.Series: 1 = Mua, -1 = Bán, 0 = Giữ
"""
df['RSI'] = self.calculate_rsi(df['Close'])
df['Signal'] = 0
# Tín hiệu mua: RSI vượt lên từ dưới 30
df.loc[(df['RSI'] < self.oversold) &
(df['RSI'].shift(1) >= self.oversold), 'Signal'] = 1
# Tín hiệu bán: RSI giảm xuống từ trên 70
df.loc[(df['RSI'] > self.overbought) &
(df['RSI'].shift(1) <= self.overbought), 'Signal'] = -1
return df['Signal']
2.2. Chiến lược RSI + Moving Average (Hiệu quả cao)
Đặc điểm:
- Kết hợp RSI với Moving Average để lọc tín hiệu
- Giảm false signals đáng kể
- Phù hợp với nhiều loại thị trường
Quy tắc:
- Mua: RSI < 30 VÀ giá > MA (xu hướng tăng)
- Bán: RSI > 70 VÀ giá < MA (xu hướng giảm)
class RSIWithMAStrategy:
"""Chiến lược RSI kết hợp Moving Average"""
def __init__(self, rsi_period=14, ma_period=50, oversold=30, overbought=70):
self.rsi_period = rsi_period
self.ma_period = ma_period
self.oversold = oversold
self.overbought = overbought
def calculate_indicators(self, df):
"""Tính toán các chỉ báo"""
# RSI
delta = df['Close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=self.rsi_period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=self.rsi_period).mean()
rs = gain / loss
df['RSI'] = 100 - (100 / (1 + rs))
# Moving Average
df['MA'] = df['Close'].rolling(window=self.ma_period).mean()
return df
def generate_signals(self, df):
"""Tạo tín hiệu giao dịch"""
df = self.calculate_indicators(df)
df['Signal'] = 0
# Tín hiệu mua: RSI oversold + giá trên MA (uptrend)
buy_condition = (
(df['RSI'] < self.oversold) &
(df['Close'] > df['MA']) &
(df['RSI'].shift(1) >= self.oversold) # RSI vừa vượt lên
)
df.loc[buy_condition, 'Signal'] = 1
# Tín hiệu bán: RSI overbought + giá dưới MA (downtrend)
sell_condition = (
(df['RSI'] > self.overbought) &
(df['Close'] < df['MA']) &
(df['RSI'].shift(1) <= self.overbought) # RSI vừa giảm xuống
)
df.loc[sell_condition, 'Signal'] = -1
return df['Signal']
2.3. Chiến lược RSI Divergence (Nâng cao – Rất hiệu quả)
Đặc điểm:
- Phát hiện sự phân kỳ giữa giá và RSI
- Tín hiệu mạnh, độ chính xác cao
- Phù hợp để phát hiện đảo chiều xu hướng
Quy tắc:
- Bullish Divergence: Giá tạo lower low, RSI tạo higher low → Tín hiệu mua
- Bearish Divergence: Giá tạo higher high, RSI tạo lower high → Tín hiệu bán
class RSIDivergenceStrategy:
"""Chiến lược RSI Divergence"""
def __init__(self, rsi_period=14, lookback=5):
self.rsi_period = rsi_period
self.lookback = lookback
def find_peaks_troughs(self, series):
"""Tìm đỉnh và đáy trong chuỗi"""
from scipy.signal import find_peaks
# Tìm đỉnh
peaks, _ = find_peaks(series, distance=self.lookback)
# Tìm đáy
troughs, _ = find_peaks(-series, distance=self.lookback)
return peaks, troughs
def detect_divergence(self, prices, rsi):
"""Phát hiện divergence"""
signals = pd.Series(0, index=prices.index)
# Tìm đỉnh và đáy của giá
price_peaks, price_troughs = self.find_peaks_troughs(prices.values)
rsi_peaks, rsi_troughs = self.find_peaks_troughs(rsi.values)
# Bullish Divergence: Giá tạo lower low, RSI tạo higher low
if len(price_troughs) >= 2 and len(rsi_troughs) >= 2:
price_low1 = prices.iloc[price_troughs[-2]]
price_low2 = prices.iloc[price_troughs[-1]]
rsi_low1 = rsi.iloc[rsi_troughs[-2]]
rsi_low2 = rsi.iloc[rsi_troughs[-1]]
if price_low2 < price_low1 and rsi_low2 > rsi_low1:
signals.iloc[price_troughs[-1]] = 1 # Tín hiệu mua
# Bearish Divergence: Giá tạo higher high, RSI tạo lower high
if len(price_peaks) >= 2 and len(rsi_peaks) >= 2:
price_high1 = prices.iloc[price_peaks[-2]]
price_high2 = prices.iloc[price_peaks[-1]]
rsi_high1 = rsi.iloc[rsi_peaks[-2]]
rsi_high2 = rsi.iloc[rsi_peaks[-1]]
if price_high2 > price_high1 and rsi_high2 < rsi_high1:
signals.iloc[price_peaks[-1]] = -1 # Tín hiệu bán
return signals
def generate_signals(self, df):
"""Tạo tín hiệu từ divergence"""
# Tính RSI
delta = df['Close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=self.rsi_period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=self.rsi_period).mean()
rs = gain / loss
df['RSI'] = 100 - (100 / (1 + rs))
# Phát hiện divergence
signals = self.detect_divergence(df['Close'], df['RSI'])
return signals
2.4. Chiến lược RSI với Multiple Timeframes (Rất hiệu quả)
Đặc điểm:
- Phân tích RSI trên nhiều khung thời gian
- Tín hiệu mạnh và đáng tin cậy hơn
- Phù hợp cho swing trading và position trading
Quy tắc:
- Mua: RSI(1h) < 30, RSI(4h) < 50, RSI(1d) > 50 (xu hướng tăng dài hạn)
- Bán: RSI(1h) > 70, RSI(4h) > 50, RSI(1d) < 50 (xu hướng giảm dài hạn)
class MultiTimeframeRSIStrategy:
"""Chiến lược RSI đa khung thời gian"""
def __init__(self, rsi_period=14):
self.rsi_period = rsi_period
def calculate_rsi(self, prices):
"""Tính RSI"""
delta = prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=self.rsi_period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=self.rsi_period).mean()
rs = gain / loss
return 100 - (100 / (1 + rs))
def analyze_multiple_timeframes(self, exchange, symbol):
"""
Phân tích RSI trên nhiều khung thời gian
Parameters:
-----------
exchange : ccxt.Exchange
Exchange object
symbol : str
Trading pair (e.g., 'BTC/USDT')
Returns:
--------
dict: RSI values cho các timeframe
"""
timeframes = {
'1h': '1h',
'4h': '4h',
'1d': '1d'
}
rsi_values = {}
for tf_name, tf_code in timeframes.items():
# Lấy dữ liệu OHLCV
ohlcv = exchange.fetch_ohlcv(symbol, tf_code, limit=100)
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
# Tính RSI
rsi = self.calculate_rsi(df['close'])
rsi_values[tf_name] = rsi.iloc[-1]
return rsi_values
def generate_signals(self, rsi_values):
"""
Tạo tín hiệu từ RSI đa khung thời gian
Returns:
--------
int: 1 = Mua, -1 = Bán, 0 = Giữ
"""
rsi_1h = rsi_values['1h']
rsi_4h = rsi_values['4h']
rsi_1d = rsi_values['1d']
# Tín hiệu mua: RSI ngắn hạn oversold, dài hạn trong xu hướng tăng
if rsi_1h < 30 and rsi_4h < 50 and rsi_1d > 50:
return 1
# Tín hiệu bán: RSI ngắn hạn overbought, dài hạn trong xu hướng giảm
if rsi_1h > 70 and rsi_4h > 50 and rsi_1d < 50:
return -1
return 0
3. Bot Auto Trading với RSI Strategy
3.1. Cấu trúc Bot hoàn chỉnh
import ccxt
import pandas as pd
import numpy as np
import time
from datetime import datetime
from typing import Dict, Optional
class RSITradingBot:
"""Bot auto trading sử dụng chiến lược RSI"""
def __init__(self, exchange_name: str, api_key: str, api_secret: str,
strategy_type: str = 'rsi_ma'):
"""
Khởi tạo bot
Parameters:
-----------
exchange_name : str
Tên sàn (binance, coinbase, etc.)
api_key : str
API key
api_secret : str
API secret
strategy_type : str
Loại chiến lược ('basic', 'rsi_ma', 'divergence', 'multi_tf')
"""
# Kết nối exchange
exchange_class = getattr(ccxt, exchange_name)
self.exchange = exchange_class({
'apiKey': api_key,
'secret': api_secret,
'enableRateLimit': True,
})
# Chọn chiến lược
self.strategy = self._init_strategy(strategy_type)
# Quản lý vị thế
self.position = None
self.entry_price = None
self.stop_loss = None
self.take_profit = None
# Cài đặt rủi ro
self.max_position_size = 0.1 # 10% vốn
self.stop_loss_pct = 0.02 # 2%
self.take_profit_pct = 0.04 # 4%
def _init_strategy(self, strategy_type: str):
"""Khởi tạo chiến lược"""
if strategy_type == 'basic':
return BasicRSIStrategy()
elif strategy_type == 'rsi_ma':
return RSIWithMAStrategy()
elif strategy_type == 'divergence':
return RSIDivergenceStrategy()
elif strategy_type == 'multi_tf':
return MultiTimeframeRSIStrategy()
else:
raise ValueError(f"Unknown strategy type: {strategy_type}")
def get_market_data(self, symbol: str, timeframe: str = '1h', limit: int = 100):
"""Lấy dữ liệu thị trường"""
ohlcv = self.exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
df.set_index('timestamp', inplace=True)
return df
def calculate_position_size(self, balance: float, price: float) -> float:
"""Tính toán kích thước vị thế"""
max_position_value = balance * self.max_position_size
position_size = max_position_value / price
return position_size
def place_order(self, symbol: str, side: str, amount: float,
order_type: str = 'market'):
"""Đặt lệnh giao dịch"""
try:
if side == 'buy':
order = self.exchange.create_market_buy_order(symbol, amount)
else:
order = self.exchange.create_market_sell_order(symbol, amount)
print(f"[{datetime.now()}] {side.upper()} {amount} {symbol} @ {order['price']}")
return order
except Exception as e:
print(f"Error placing order: {e}")
return None
def check_stop_loss_take_profit(self, current_price: float):
"""Kiểm tra stop loss và take profit"""
if self.position is None:
return
if self.position == 'long':
# Kiểm tra stop loss
if current_price <= self.stop_loss:
print(f"[{datetime.now()}] Stop Loss triggered @ {current_price}")
self.close_position(current_price)
return
# Kiểm tra take profit
if current_price >= self.take_profit:
print(f"[{datetime.now()}] Take Profit triggered @ {current_price}")
self.close_position(current_price)
return
def open_position(self, symbol: str, side: str, price: float, amount: float):
"""Mở vị thế"""
order = self.place_order(symbol, side, amount)
if order:
self.position = side
self.entry_price = price
# Đặt stop loss và take profit
if side == 'long':
self.stop_loss = price * (1 - self.stop_loss_pct)
self.take_profit = price * (1 + self.take_profit_pct)
print(f"[{datetime.now()}] Position opened: {side} @ {price}")
def close_position(self, price: float):
"""Đóng vị thế"""
if self.position:
# Tính toán lợi nhuận
if self.position == 'long':
pnl_pct = ((price - self.entry_price) / self.entry_price) * 100
print(f"[{datetime.now()}] Position closed. P&L: {pnl_pct:.2f}%")
self.position = None
self.entry_price = None
self.stop_loss = None
self.take_profit = None
def run(self, symbol: str, timeframe: str = '1h', check_interval: int = 300):
"""
Chạy bot
Parameters:
-----------
symbol : str
Trading pair
timeframe : str
Khung thời gian
check_interval : int
Thời gian chờ giữa các lần kiểm tra (giây)
"""
print(f"[{datetime.now()}] Bot started for {symbol}")
while True:
try:
# Lấy dữ liệu thị trường
df = self.get_market_data(symbol, timeframe)
current_price = df['close'].iloc[-1]
# Kiểm tra stop loss và take profit
if self.position:
self.check_stop_loss_take_profit(current_price)
if self.position is None: # Đã đóng vị thế
time.sleep(check_interval)
continue
# Tạo tín hiệu
if isinstance(self.strategy, MultiTimeframeRSIStrategy):
rsi_values = self.strategy.analyze_multiple_timeframes(
self.exchange, symbol
)
signal = self.strategy.generate_signals(rsi_values)
else:
signals = self.strategy.generate_signals(df)
signal = signals.iloc[-1]
# Xử lý tín hiệu
if signal == 1 and self.position != 'long':
# Tín hiệu mua
balance = self.exchange.fetch_balance()
available_balance = balance['USDT']['free'] if 'USDT' in balance else balance['total']['USDT']
amount = self.calculate_position_size(available_balance, current_price)
if amount > 0:
self.open_position(symbol, 'long', current_price, amount)
elif signal == -1 and self.position == 'long':
# Tín hiệu bán
self.close_position(current_price)
# Đợi đến lần kiểm tra tiếp theo
time.sleep(check_interval)
except KeyboardInterrupt:
print(f"[{datetime.now()}] Bot stopped by user")
break
except Exception as e:
print(f"[{datetime.now()}] Error: {e}")
time.sleep(check_interval)
4. Backtesting Chiến lược RSI
4.1. Hàm Backtest
def backtest_rsi_strategy(df, strategy, initial_capital=10000):
"""
Backtest chiến lược RSI
Parameters:
-----------
df : pd.DataFrame
Dữ liệu OHLCV
strategy : Strategy object
Đối tượng chiến lược
initial_capital : float
Vốn ban đầu
Returns:
--------
dict: Kết quả backtest
"""
# Tạo tín hiệu
signals = strategy.generate_signals(df.copy())
df['Signal'] = signals
# Tính toán vị thế và lợi nhuận
capital = initial_capital
position = 0
entry_price = 0
trades = []
for i in range(len(df)):
price = df['close'].iloc[i]
signal = df['Signal'].iloc[i]
if signal == 1 and position == 0: # Mua
position = capital / price
entry_price = price
trades.append({
'type': 'buy',
'date': df.index[i],
'price': price,
'capital': capital
})
elif signal == -1 and position > 0: # Bán
capital = position * price
pnl = ((price - entry_price) / entry_price) * 100
trades.append({
'type': 'sell',
'date': df.index[i],
'price': price,
'capital': capital,
'pnl': pnl
})
position = 0
# Tính toán metrics
if position > 0: # Đóng vị thế cuối cùng
final_price = df['close'].iloc[-1]
capital = position * final_price
total_return = ((capital - initial_capital) / initial_capital) * 100
winning_trades = [t for t in trades if t.get('pnl', 0) > 0]
losing_trades = [t for t in trades if t.get('pnl', 0) < 0]
win_rate = len(winning_trades) / len([t for t in trades if 'pnl' in t]) * 100 if trades else 0
avg_win = np.mean([t['pnl'] for t in winning_trades]) if winning_trades else 0
avg_loss = np.mean([t['pnl'] for t in losing_trades]) if losing_trades else 0
return {
'initial_capital': initial_capital,
'final_capital': capital,
'total_return': total_return,
'total_trades': len([t for t in trades if 'pnl' in t]),
'winning_trades': len(winning_trades),
'losing_trades': len(losing_trades),
'win_rate': win_rate,
'avg_win': avg_win,
'avg_loss': avg_loss,
'profit_factor': abs(avg_win / avg_loss) if avg_loss != 0 else 0,
'trades': trades
}
# Ví dụ sử dụng
import yfinance as yf
# Lấy dữ liệu
data = yf.download('BTC-USD', period='1y', interval='1h')
df = pd.DataFrame(data)
df.columns = [col.lower() for col in df.columns]
# Chạy backtest
strategy = RSIWithMAStrategy(rsi_period=14, ma_period=50)
results = backtest_rsi_strategy(df, strategy, initial_capital=10000)
print(f"Total Return: {results['total_return']:.2f}%")
print(f"Win Rate: {results['win_rate']:.2f}%")
print(f"Total Trades: {results['total_trades']}")
print(f"Profit Factor: {results['profit_factor']:.2f}")
5. Tối ưu hóa tham số RSI
5.1. Tìm tham số tối ưu
from itertools import product
def optimize_rsi_parameters(df, strategy_class, param_ranges):
"""
Tối ưu hóa tham số RSI
Parameters:
-----------
df : pd.DataFrame
Dữ liệu lịch sử
strategy_class : class
Lớp chiến lược
param_ranges : dict
Phạm vi tham số cần tối ưu
Returns:
--------
dict: Tham số tối ưu và kết quả
"""
best_params = None
best_return = -float('inf')
best_results = None
# Tạo tất cả các tổ hợp tham số
param_names = list(param_ranges.keys())
param_values = list(param_ranges.values())
for params in product(*param_values):
param_dict = dict(zip(param_names, params))
# Tạo chiến lược với tham số mới
strategy = strategy_class(**param_dict)
# Backtest
results = backtest_rsi_strategy(df, strategy)
# Đánh giá (có thể dùng Sharpe ratio, total return, etc.)
score = results['total_return'] * (results['win_rate'] / 100)
if score > best_return:
best_return = score
best_params = param_dict
best_results = results
return {
'best_params': best_params,
'best_return': best_return,
'results': best_results
}
# Ví dụ tối ưu hóa
param_ranges = {
'rsi_period': [10, 14, 21],
'ma_period': [20, 50, 100],
'oversold': [25, 30, 35],
'overbought': [65, 70, 75]
}
optimization_results = optimize_rsi_parameters(df, RSIWithMAStrategy, param_ranges)
print("Best Parameters:", optimization_results['best_params'])
print("Best Return:", optimization_results['best_return'])
6. Quản lý rủi ro với RSI
6.1. Position Sizing động
class RiskManager:
"""Quản lý rủi ro cho chiến lược RSI"""
def __init__(self, max_risk_per_trade=0.02, max_portfolio_risk=0.1):
self.max_risk_per_trade = max_risk_per_trade
self.max_portfolio_risk = max_portfolio_risk
def calculate_position_size(self, account_balance, entry_price, stop_loss_price):
"""
Tính toán kích thước vị thế dựa trên rủi ro
Parameters:
-----------
account_balance : float
Số dư tài khoản
entry_price : float
Giá vào lệnh
stop_loss_price : float
Giá stop loss
Returns:
--------
float: Kích thước vị thế
"""
risk_amount = account_balance * self.max_risk_per_trade
price_risk = abs(entry_price - stop_loss_price)
if price_risk == 0:
return 0
position_size = risk_amount / price_risk
return position_size
def adjust_stop_loss_by_volatility(self, entry_price, rsi, atr):
"""
Điều chỉnh stop loss dựa trên volatility
Parameters:
-----------
entry_price : float
Giá vào lệnh
rsi : float
Giá trị RSI hiện tại
atr : float
Average True Range (đo lường volatility)
Returns:
--------
float: Giá stop loss
"""
# RSI càng cực đoan, stop loss càng rộng (volatility cao)
if rsi < 20 or rsi > 80:
stop_loss_multiplier = 2.0
elif rsi < 30 or rsi > 70:
stop_loss_multiplier = 1.5
else:
stop_loss_multiplier = 1.0
stop_loss = entry_price - (atr * stop_loss_multiplier)
return stop_loss
7. Kết luận: Chiến lược RSI nào hiệu quả nhất?
Đánh giá các chiến lược:
- RSI Cơ bản (Oversold/Overbought)
- ✅ Đơn giản, dễ triển khai
- ❌ Nhiều false signals
- ⭐ Hiệu quả: 3/5
- RSI + Moving Average
- ✅ Giảm false signals đáng kể
- ✅ Phù hợp nhiều thị trường
- ⭐ Hiệu quả: 4/5
- RSI Divergence
- ✅ Tín hiệu mạnh, độ chính xác cao
- ❌ Khó phát hiện, ít tín hiệu
- ⭐ Hiệu quả: 4.5/5
- RSI Multi-Timeframe
- ✅ Tín hiệu đáng tin cậy nhất
- ✅ Phù hợp swing/position trading
- ⭐ Hiệu quả: 5/5
Khuyến nghị:
- Cho người mới bắt đầu: RSI + MA Strategy
- Cho trader có kinh nghiệm: Multi-Timeframe RSI
- Cho scalping: RSI Divergence với khung thời gian ngắn
Lưu ý quan trọng:
- Không bao giờ trade chỉ dựa vào RSI: Luôn kết hợp với các chỉ báo khác
- Quản lý rủi ro: Luôn đặt stop loss và take profit
- Backtest trước: Kiểm tra chiến lược trên dữ liệu lịch sử
- Tối ưu hóa tham số: Tìm tham số phù hợp với từng thị trường
- Theo dõi và điều chỉnh: Thị trường thay đổi, chiến lược cũng cần thay đổi
8. Tài liệu tham khảo
- RSI Indicator – Investopedia
- Technical Analysis of the Financial Markets – John J. Murphy
- Python for Finance – Yves Hilpisch
Lưu ý: Trading có rủi ro. Hãy luôn backtest kỹ lưỡng và bắt đầu với số vốn nhỏ. Bài viết này chỉ mang tính chất giáo dục, không phải lời khuyên đầu tư.