Bài viết gần đây
-
Học Auto Trade Ở Đâu Uy Tín Và Thực Chiến Nhất 2026?
Tháng 6 28, 2026 -
Tự Động Hóa Giao Dịch T+0 Trên Chứng Khoán Việt Nam Bằng Python
Tháng 6 28, 2026 -
Lập Trình Bot MT5 Bằng Python Với aiomql (Tài Liệu Tiếng Việt)
Tháng 6 28, 2026
| Bot Trading Python Kết Nối SSI/DNSE: Đặt Lệnh Tự Động Chứng Khoán Việt Nam
Tự động hóa giao dịch chứng khoán Việt Nam đã trở thành hiện thực với các API từ SSI và DNSE. Bài viết này hướng dẫn bạn xây dựng bot trading Python kết nối sàn Việt Nam — từ đăng nhập đến đặt lệnh tự động.
Tại Sao Cần Bot Trading?
- Không bỏ lỡ tín hiệu: Bot chạy 9:00–14:45, không cần ngồi theo dõi
- Loại bỏ cảm xúc: Mua/bán theo quy tắc định sẵn, không FOMO hay panic sell
- Tốc độ: Đặt lệnh trong milliseconds khi có tín hiệu
- Backtested: Chiến lược đã được kiểm tra trước khi chạy thật
Lựa Chọn Broker: SSI vs DNSE
| SSI FastConnect | DNSE iBoard API | |
|---|---|---|
| API chính thức | ✅ Có | ✅ Có |
| Phí API | Miễn phí | Miễn phí |
| Python SDK | ✅ Có | Cần tự viết wrapper |
| Dữ liệu realtime | ✅ Websocket | ✅ REST API |
| Phí giao dịch | ~0.15% | ~0.15–0.2% |
Cài Đặt SSI FastConnect SDK
pip install ssi-fc-data
Kết Nối SSI và Lấy Dữ Liệu Realtime
from ssi_fc_data import fc_md_client, model
# Thông tin đăng nhập SSI (lấy tại SSI iBoard → Cài đặt → API)
config = model.Config(
Url="https://fc-data.ssi.com.vn/",
ConsumerID="your_consumer_id",
ConsumerSecret="your_consumer_secret"
)
client = fc_md_client.MarketDataClient(config)
# Lấy dữ liệu intraday OHLCV
def get_intraday(symbol, resolution="1"):
data = client.iboard(
symbol=symbol,
look_back=100,
resolution=resolution
)
return data
df = get_intraday("VNM")
print(df.tail(5))
Đặt Lệnh Qua SSI Trading API
import requests
import json
SSI_TRADE_URL = "https://trade.ssi.com.vn/rest/v2"
class SSITrader:
def __init__(self, access_token, account_no):
self.token = access_token
self.account_no = account_no
self.headers = {
"Authorization": f"Bearer {self.token}",
"Content-Type": "application/json"
}
def get_balance(self):
r = requests.get(
f"{SSI_TRADE_URL}/Account/Balance",
headers=self.headers,
params={"account": self.account_no}
)
return r.json()
def get_positions(self):
r = requests.get(
f"{SSI_TRADE_URL}/Position",
headers=self.headers,
params={"account": self.account_no}
)
return r.json()
def place_order(self, symbol, side, quantity, price, order_type="LO"):
"""
side: "B" (Buy) hoặc "S" (Sell)
order_type: "LO" (Limit), "MP" (Market Price)
"""
payload = {
"account": self.account_no,
"instrumentID": symbol,
"market": "VN",
"buySell": side,
"orderType": order_type,
"price": price,
"quantity": quantity
}
r = requests.post(
f"{SSI_TRADE_URL}/Order/NewOrder",
headers=self.headers,
json=payload
)
return r.json()
def cancel_order(self, order_id):
payload = {
"account": self.account_no,
"orderID": order_id
}
r = requests.post(
f"{SSI_TRADE_URL}/Order/CancelOrder",
headers=self.headers,
json=payload
)
return r.json()
# Sử dụng
trader = SSITrader(access_token="...", account_no="...")
Bot Hoàn Chỉnh: Chiến Lược RSI Tự Động
import time
import pandas as pd
from datetime import datetime
class RSIBot:
def __init__(self, trader, symbol, capital_per_trade=10_000_000):
self.trader = trader
self.symbol = symbol
self.capital = capital_per_trade
self.position = 0 # số lượng cổ phiếu đang nắm
self.log = []
def calc_rsi(self, prices, period=14):
s = pd.Series(prices)
delta = s.diff()
gain = delta.clip(lower=0).rolling(period).mean()
loss = (-delta.clip(upper=0)).rolling(period).mean()
return (100 - (100 / (1 + gain/loss))).iloc[-1]
def run(self):
print(f"[{datetime.now()}] Bot khởi động: {self.symbol}")
while True:
now = datetime.now()
# Chỉ chạy trong giờ giao dịch
if not (9 <= now.hour < 14 or (now.hour == 14 and now.minute <= 45)):
time.sleep(60)
continue
try:
# Lấy dữ liệu giá gần nhất
df = get_intraday(self.symbol, resolution="5") # nến 5 phút
prices = df['close'].tolist()
if len(prices) < 20:
time.sleep(30)
continue
current_price = prices[-1]
rsi = self.calc_rsi(prices)
print(f"[{now.strftime('%H:%M')}] {self.symbol}: {current_price:,.0f} | RSI: {rsi:.1f}")
# Logic giao dịch
if rsi 0:
result = self.trader.place_order(self.symbol, "B", quantity, current_price)
if result.get('status') == 'success':
self.position = quantity
print(f" ✅ MUA {quantity} {self.symbol} @ {current_price:,.0f}")
elif rsi > 70 and self.position > 0:
# Tín hiệu BÁN
result = self.trader.place_order(self.symbol, "S", self.position, current_price)
if result.get('status') == 'success':
print(f" ✅ BÁN {self.position} {self.symbol} @ {current_price:,.0f}")
self.position = 0
# Stop loss 5%
elif self.position > 0:
entry = self.capital / self.position
if current_price < entry * 0.95:
self.trader.place_order(self.symbol, "S", self.position, current_price)
print(f" 🛑 STOP LOSS @ {current_price:,.0f}")
self.position = 0
time.sleep(60) # kiểm tra mỗi 1 phút
except Exception as e:
print(f" ⚠️ Lỗi: {e}")
time.sleep(30)
# Khởi chạy bot
bot = RSIBot(trader, symbol="VNM", capital_per_trade=20_000_000)
bot.run()
Lưu Ý Quan Trọng
- Test kỹ trước: Chạy paper trading (giả lập) ít nhất 2–4 tuần
- Giới hạn vốn: Bot lỗi có thể đặt lệnh sai — đặt giới hạn tối đa/ngày
- Logging: Ghi log tất cả lệnh để kiểm tra sau
- Monitoring: Kết hợp Telegram bot để nhận thông báo ngay khi có lệnh
Kết Luận
Bot trading Python kết nối SSI/DNSE là hoàn toàn khả thi với trader Việt Nam. Bắt đầu đơn giản với 1 cổ phiếu, 1 chiến lược, vốn nhỏ — sau khi ổn định mới scale up.
📌 Muốn ứng dụng Python vào phân tích và giao dịch tài chính thực chiến?
Khóa Python Fintech — Phân Tích Dữ Liệu Lớn & Tự Động Hóa Giao Dịch tại Hướng Nghiệp Dữ Liệu giúp bạn thực hành với dữ liệu VnIndex, Binance API thật — không dạy lý thuyết hàn lâm.
📞 Hotline/Zalo: 0927 909 257
Weekly Digest — Nhận Bản Tin Hàng Tuần
Nhận các bài viết phân tích kỹ thuật chuyên sâu, thuật toán giao dịch tự động (Trading Bot) và các giải pháp công nghệ mới nhất từ Hướng Nghiệp Dữ Liệu.
admin
Biên tập viên, Hướng Nghiệp Dữ LiệuBiên tập viên nội dung tại Hướng Nghiệp Dữ Liệu, phụ trách tổng hợp và biên soạn các bài viết về lập trình Python, dữ liệu và công nghệ.