| Bot Đặt Lệnh Demo Bằng Python | Paper Trading Binance, MA20, Báo Cáo PnL (Python 365 Ngày 63)

Được viết bởi Đặng Trí Thanh vào ngày 17/08/2026 lúc 16:23 | 22 lượt xem

Bot đặt lệnh demo là gì? Đó là một chương trình Python tự động đặt lệnh mua, bán trên một sổ cái ảo — dùng dữ liệu giá thật từ sàn nhưng không dùng một đồng tiền thật nào. Trong bài học Python 365 Ngày 63 này, bạn sẽ xây dựng hoàn chỉnh một bot đặt lệnh demo: cấu hình vốn ảo, tải giá thật Binance, sinh tín hiệu trung bình động MA20, mô phỏng lệnh giấy, tính lời lỗ (PnL) và ghi nhật ký giao dịch ra file CSV.

Đây là bước đệm quan trọng nhất trước khi bạn dám cho bot chạy với tiền thật: bot demo giúp bạn kiểm chứng chiến lược mà không phải trả giá bằng rủi ro tài chính.

Mục lục

  1. Bot đặt lệnh demo là gì? Vì sao cần bot demo?
  2. Paper trading — lệnh giấy và sổ cái ảo hoạt động ra sao
  3. Cấu hình bot demo — file .env
  4. Tải giá thật từ Binance public API
  5. Trung bình động MA — cách sinh tín hiệu mua bán
  6. Mô phỏng lệnh giấy — vòng lặp mua bán ảo
  7. Tính PnL và tổng tài sản cuối kỳ
  8. Ghi nhật ký giao dịch ra CSV
  9. Script hoàn chỉnh Ngày 63
  10. Kết quả chạy thật — bot demo đã làm gì
  11. Hạn chế của bot demo và cách chuyển sang chiến lược thật
  12. Quản trị rủi ro và những điều cần lưu ý
  13. FAQ
  14. Kết luận

1. Bot đặt lệnh demo là gì? Vì sao cần bot demo?

Bot đặt lệnh demo (paper trading bot) là một chương trình tự động thực hiện các lệnh mua/bán dựa trên quy tắc lập trình sẵn, nhưng thay vì khớp lệnh trên sàn thật, nó ghi nhận lệnh vào một sổ cái ảo. Giá dùng để tính toán vẫn là giá thật được lấy từ sàn (chẳng hạn Binance), vì vậy kết quả mô phỏng phản ánh khá sát điều kiện thị trường thực.

Vì sao bạn cần bot demo?

  • Không rủi ro tài chính: Bạn có thể để bot tự do mua bán, thậm chí “cháy tài khoản ảo”, mà không mất một đồng nào.
  • Kiểm chứng chiến lược nhanh: Thay vì mất hàng tháng quan sát tay, bot demo cho bạn biết một chiến lược đang thắng hay thua sau vài nghìn nến giá.
  • Học cách vận hành bot: Kết nối API, xử lý dữ liệu, quản lý vị thế, ghi log — tất cả kỹ năng này giống hệt khi chạy bot thật.
  • Xây dựng niềm tin bằng số liệu: Một chiến lược đã chứng minh trên demo có biểu đồ PnL rõ ràng sẽ giúp bạn tự tin hơn khi quyết định có nâng cấp lên tài khoản thật hay không.

Ai nên dùng bot đặt lệnh demo? Bất kỳ ai đang tìm hiểu giao dịch tự động đều nên bắt đầu từ đây: người mới học Python muốn thấy lập trình ứng dụng thực tế vào tài chính; trader muốn kiểm chứng ý tưởng chiến lược trước khi mạo hiểm vốn; lập trình viên muốn rèn kỹ năng API, xử lý dữ liệu và xây dựng hệ thống có vòng đời. Với cả ba nhóm, bot demo là sân chơi an toàn nhất để vừa học, vừa đo lường kết quả, vừa tránh những sai lầm tốn kém về sau.

Trong loạt bài Python 365 ngày tại Hướng Nghiệp Dữ Liệu, sau khi đã làm quen với dữ liệu Binance, xử lý nến giá và xây dựng những chương trình nhỏ, Ngày 63 đánh dấu cột mốc quan trọng: viết một bot hoàn chỉnh có vòng đời vận hành — từ cấu hình, lấy dữ liệu, sinh tín hiệu, khớp lệnh ảo đến báo cáo.

2. Paper trading — lệnh giấy và sổ cái ảo hoạt động ra sao

Paper trading (giao dịch giấy) là phương pháp ghi chép các lệnh giao dịch giả tưởng trên giấy (thời xưa) hoặc trên phần mềm (thời nay) để theo dõi xem chiến lược có sinh lời hay không. Ngày nay, paper trading thường được tự động hóa bằng bot.

Cách bot demo của chúng ta vận hành:

  1. Sổ cái ảo: Bot giữ hai biến chính — cash (tiền mặt ảo) và coins (lượng coin đang nắm giữ).
  2. Lệnh BUY: Khi có tín hiệu mua, bot dùng toàn bộ cash để mua coin: coins = cash / price, sau đó cash = 0.
  3. Lệnh SELL: Khi có tín hiệu bán, bot bán toàn bộ coins lấy tiền mặt: cash = coins * price, sau đó coins = 0.
  4. Tổng tài sản: Tại mọi thời điểm, tài sản ảo = cash + coins × giá hiện tại.
  5. Log lệnh: Mỗi lệnh mua/bán được ghi vào danh sách và xuất ra file CSV.

Vì toàn bộ logic nằm trong một vòng lặp xử lý dữ liệu lịch sử, bot “chạy lại” hàng trăm nến giá trong vài giây — điều mà người giao dịch bằng tay phải mất hàng tuần mới quan sát được. Đây chính là sức mạnh của việc tự động hóa phân tích.

3. Cấu hình bot demo — file .env

Một nguyên tắc hay khi viết bot: không nhét cấu hình cứng vào code. Vốn ảo, symbol, chu kỳ chỉ báo nên nằm trong file cấu hình để bạn chỉnh mà không phải sửa code.

File .env của chúng ta có dạng:

SYMBOL=btcusdt
INITIAL=10000        # vốn ảo ban đầu (USD)
MA=20                # chu kỳ trung bình động

Trong script, ta viết một hàm nhỏ đọc file .env và cho phép ghi đè bằng biến môi trường:

def load_env() -> dict:
    env = {}
    if ENV_FILE.exists():
        for line in ENV_FILE.read_text(encoding="utf-8").splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                k, _, v = line.partition("=")
                env[k.strip()] = v.strip().strip('"').strip("'")
    return env

env = load_env()
SYMBOL = os.environ.get("SYMBOL") or env.get("SYMBOL", "btcusdt")
INITIAL = float(os.environ.get("INITIAL") or env.get("INITIAL", "10000"))
MA_PERIOD = int(os.environ.get("MA") or env.get("MA", "20"))

Giải thích các biến:

  • SYMBOL — cặp giao dịch, mặc định btcusdt (Bitcoin/USDT).
  • INITIAL — vốn ảo ban đầu, mặc định 10.000 USD.
  • MA — chu kỳ trung bình động dùng để sinh tín hiệu, mặc định 20 nến.

Việc tách cấu hình khỏi code giúp bạn thử nghiệm nhanh: đổi MA=50, đổi SYMBOL=ethusdt, đổi vốn ảo lên 100.000 chỉ bằng một dòng trong .env, không cần chạm vào logic.

Cách tiếp cận này còn mang lại lợi ích lâu dài: khi chuyển sang bot thật, bạn sẽ đưa API key, mức rủi ro, kích thước lệnh vào cùng một file cấu hình — nơi duy nhất cần kiểm tra trước khi triển khai. Nếu cấu hình nằm rải rác trong code, một ngày bạn sẽ quên chỉnh ở chỗ nào và gây ra lỗi khó tìm. Tách biệt cấu hình và logic là một trong những dấu hiệu của code chuyên nghiệp.

4. Tải giá thật từ Binance public API

Một trong những điểm hay nhất của Binance là public API không cần API key cho dữ liệu thị trường. Bạn chỉ cần gửi một request HTTP và nhận về dữ liệu nến giá dạng JSON.

Endpoint cơ bản:

https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&limit=100

Hàm Python dùng thư viện chuẩn urllib:

import json
import urllib.request
from datetime import datetime

HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) PythonDay63"}

def fetch_klines(symbol: str, limit: int = 100) -> list:
    url = (f"https://api.binance.com/api/v3/klines?"
           f"symbol={symbol.upper()}&interval=1h&limit={limit}")
    req = urllib.request.Request(url, headers=HEADERS)
    with urllib.request.urlopen(req, timeout=15) as resp:
        raw = json.loads(resp.read().decode("utf-8"))
    return [{"time": datetime.fromtimestamp(k[0] / 1000).strftime("%Y-%m-%d %H:%M"),
             "close": float(k[4])} for k in raw]

Mỗi nến (kline) trả về một mảng với nhiều trường; chúng ta chỉ cần hai trường quan trọng:

Vị trí Ý nghĩa
k[0] Thời gian mở nến (millisecond epoch)
k[4] Giá đóng cửa (close)

Hàm trên trả về danh sách các dict {time, close} — vừa đủ cho chiến lược trung bình động của chúng ta. Vì sử dụng urllib chuẩn, bạn không cần cài thêm thư viện nào — rất phù hợp với người mới học Python.

Lưu ý: public API có giới hạn tần suất request; với bài học này chỉ gọi một lần mỗi lần chạy nên hoàn toàn an toàn.

5. Trung bình động MA — cách sinh tín hiệu mua bán

Trung bình động (Moving Average — MA) là giá đóng cửa trung bình của N nến gần nhất. Nó giúp “làm mượt” biến động giá để nhìn rõ xu hướng.

Công thức MA20 tại nến thứ i:

MA(i) = ( P(i-19) + P(i-18) + ... + P(i) ) / 20

Trong Python:

ma = sum(closes[i - MA_PERIOD:i]) / MA_PERIOD

Quy tắc tín hiệu đơn giản (chiến lược crossover):

  • Mua (BUY): giá đóng cửa lớn hơn MA20 và bot chưa giữ coin nào.
  • Bán (SELL): giá đóng cửa nhỏ hơn MA20 và bot đang giữ coin.

Ý tưởng đằng sau: nếu giá nằm trên đường trung bình động, xu hướng ngắn hạn đang tăng → mua. Nếu giá rơi xuống dưới đường MA, xu hướng đảo chiều → bán để chốt lời hoặc cắt lỗ.

Đây là một chiến lược cực kỳ đơn giản nhưng hoàn chỉnh — đủ để bạn hiểu toàn bộ vòng đời của một bot giao dịch: tín hiệu → hành động → quản lý vị thế → báo cáo.

Để hiểu rõ hơn, hãy xem một ví dụ bằng số với MA nhỏ (MA3) trên chuỗi giá giả định: giá đóng cửa của 3 nến gần nhất là 100, 102, 104. Trung bình động là (100 + 102 + 104) / 3 = 102. Nếu nến tiếp theo đóng cửa ở 105, giá (105) > MA (102) → tín hiệu MUA. Ngược lại, nếu nến tiếp theo đóng cửa ở 99, giá (99) < MA → tín hiệu BÁN. Với MA20, quy tắc tương tự nhưng dùng 20 nến thay vì 3, giúp tín hiệu bớt nhạy với nhiễu ngắn hạn.

Một điểm cần lưu ý: MA càng ngắn (MA5, MA10) thì phản ứng càng nhanh nhưng dễ bị nhiễu; MA càng dài (MA50, MA200) thì tín hiệu càng chậm nhưng ổn định hơn. Việc chọn chu kỳ MA phụ thuộc vào khung thời gian và phong cách giao dịch — và bot demo chính là công cụ để bạn thử nghiệm điều này một cách an toàn.

6. Mô phỏng lệnh giấy — vòng lặp mua bán ảo

Trái tim của bot demo là vòng lặp replay trên dữ liệu nến đã tải. Với mỗi nến từ vị trí MA_PERIOD trở đi, bot tính MA, so sánh với giá, rồi quyết định mua/bán:

closes = [k["close"] for k in klines]
cash, coins = INITIAL, 0.0
trades, entry = [], None

for i in range(MA_PERIOD, len(closes)):
    ma = sum(closes[i - MA_PERIOD:i]) / MA_PERIOD
    price = closes[i]
    if price > ma and coins == 0:          # tín hiệu mua, chưa có vị thế
        coins = cash / price
        cash = 0.0
        entry = price
        trades.append((klines[i]["time"], "BUY", price))
        print(f"  [{klines[i]['time']}] MUA  @ {price:,.2f}")
    elif price < ma and coins > 0:         # tín hiệu bán, đang giữ coin
        cash = coins * price
        pnl = (price / entry - 1) * 100
        coins = 0.0
        trades.append((klines[i]["time"], "SELL", price))
        print(f"  [{klines[i]['time']}] BAN  @ {price:,.2f}  (PnL {pnl:+.2f}%)")
        entry = None

Điểm mấu chốt của mô phỏng lệnh giấy:

  • Điều kiện coins == 0 / coins > 0: đảm bảo bot không mua khi đã có vị thế, không bán khi không có coin — giống quy tắc “một lệnh tại một thời điểm”.
  • cashcoins nghịch đảo: khi mua thì cash về 0, khi bán thì coins về 0 — mô hình hóa việc “all-in/all-out” đơn giản.
  • entry: lưu giá mua vào để tính lời lỗ phần trăm khi đóng lệnh.

Khi hết dữ liệu mà bot vẫn đang giữ coin, ta đóng vị thế theo giá cuối:

if coins > 0:  # đóng vị thế theo giá cuối
    final = coins * closes[-1]
    pnl = (closes[-1] / entry - 1) * 100 if entry else 0.0
    trades.append((klines[-1]["time"], "CLOSE", closes[-1]))
    print(f"  [{klines[-1]['time']}] DONG  @ {closes[-1]:,.2f} (PnL {pnl:+.2f}%)")
else:
    final = cash

7. Tính PnL và tổng tài sản cuối kỳ

Sau khi vòng lặp kết thúc, bot tính toán báo cáo:

  • Vốn ban đầu: INITIAL (ví dụ 10.000 USD).
  • Vốn cuối: final = tiền mặt nếu đã bán hết, hoặc giá trị coin theo giá cuối nếu còn giữ.
  • Lợi nhuận phần trăm: (final / INITIAL - 1) × 100.
  • Số lệnh: len(trades).

Code báo cáo:

print("n" + "=" * 56)
print("  BAO CAO PAPER TRADING")
print("=" * 56)
print(f"  Vốn ban đầu : ${INITIAL:,.0f}")
print(f"  Vốn cuối    : ${final:,.2f}")
print(f"  Lợi nhuận   : {(final / INITIAL - 1) * 100:+.2f}%")
print(f"  Số lệnh     : {len(trades)}")
print("=" * 56)

Vì sao cần báo cáo rõ ràng? Vì một bot giao dịch không chỉ cần “đúng chiến lược” mà cần đo lường được kết quả. Chỉ số PnL phần trăm giúp bạn so sánh công bằng giữa các cấu hình khác nhau (ví dụ MA20 vs MA50) dù vốn ảo khác nhau.

8. Ghi nhật ký giao dịch ra CSV

Một bot chuyên nghiệp phải để lại dấu vết kiểm toán (audit trail). Bot demo ghi toàn bộ lệnh vào file paper_trading_log.csv với ba cột: time, action, price.

import csv

with open(LOG_FILE, "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(["time", "action", "price"])
    for t in trades:
        w.writerow(t)

File CSV sau khi chạy có dạng:

time,action,price
2026-08-07 15:00,BUY,64600.0
2026-08-09 04:00,SELL,65012.96
2026-08-09 17:00,BUY,64959.86
2026-08-10 06:00,SELL,64901.59
2026-08-10 08:00,BUY,65189.99
2026-08-10 10:00,SELL,64982.01
2026-08-10 12:00,BUY,65134.0
2026-08-10 15:00,CLOSE,65277.69

File CSV cực kỳ hữu ích:

  • Mở bằng Excel / Google Sheets để phân tích trực quan.
  • Dùng cho backtest và so sánh chiến lược.
  • Làm dữ liệu đầu vào cho các bài học sau (vẽ biểu đồ, phân tích hiệu suất, tối ưu tham số).

9. Script hoàn chỉnh Ngày 63

Dưới đây là script hoàn chỉnh Day 63_Bot dat lenh demo.py:

"""
Day 63 - Bot đặt lệnh demo (Paper Trading) bằng Python
=======================================================
Bot dùng dữ liệu giá THẬT (Binance public API) nhưng đặt lệnh GIẢ
trên sổ cái ảo — ghi log, tính PnL, không rủi ro tiền thật.

Cấu hình .env:
  SYMBOL=btcusdt
  INITIAL=10000        # vốn ảo
  MA=20                # chu kỳ MA tín hiệu

Chạy:
  python "Day 63_Bot dat lenh demo.py"
"""
import csv
import json
import os
import sys
import urllib.request
from datetime import datetime
from pathlib import Path

try:
    sys.stdout.reconfigure(encoding="utf-8")
except Exception:
    pass

BASE_DIR = Path(__file__).parent
ENV_FILE = BASE_DIR / ".env"
LOG_FILE = BASE_DIR / "paper_trading_log.csv"
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) PythonDay63"}


def load_env() -> dict:
    env = {}
    if ENV_FILE.exists():
        for line in ENV_FILE.read_text(encoding="utf-8").splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                k, _, v = line.partition("=")
                env[k.strip()] = v.strip().strip('"').strip("'")
    return env


env = load_env()
SYMBOL = os.environ.get("SYMBOL") or env.get("SYMBOL", "btcusdt")
INITIAL = float(os.environ.get("INITIAL") or env.get("INITIAL", "10000"))
MA_PERIOD = int(os.environ.get("MA") or env.get("MA", "20"))


def fetch_klines(symbol: str, limit: int = 100) -> list:
    url = (f"https://api.binance.com/api/v3/klines?"
           f"symbol={symbol.upper()}&interval=1h&limit={limit}")
    req = urllib.request.Request(url, headers=HEADERS)
    with urllib.request.urlopen(req, timeout=15) as resp:
        raw = json.loads(resp.read().decode("utf-8"))
    return [{"time": datetime.fromtimestamp(k[0] / 1000).strftime("%Y-%m-%d %H:%M"),
             "close": float(k[4])} for k in raw]


def run():
    print("=" * 56)
    print("   BOT DAT LENH DEMO (PAPER TRADING)  |  Ngay 63")
    print("=" * 56)
    print(f"  Von ao: ${INITIAL:,.0f} | Symbol: {SYMBOL.upper()} | MA{MA_PERIOD}n")

    try:
        klines = fetch_klines(SYMBOL)
        print(f"Lay {len(klines)} nen 1h tu Binance (public, khong can key)")
    except Exception as exc:
        print(f"Loi lay du lieu: {exc}")
        return

    closes = [k["close"] for k in klines]
    cash, coins = INITIAL, 0.0
    trades, entry = [], None

    for i in range(MA_PERIOD, len(closes)):
        ma = sum(closes[i - MA_PERIOD:i]) / MA_PERIOD
        price = closes[i]
        if price > ma and coins == 0:
            coins = cash / price
            cash = 0.0
            entry = price
            trades.append((klines[i]["time"], "BUY", price))
            print(f"  [{klines[i]['time']}] BUY  @ {price:,.2f}")
        elif price < ma and coins > 0:
            cash = coins * price
            pnl = (price / entry - 1) * 100
            coins = 0.0
            trades.append((klines[i]["time"], "SELL", price))
            print(f"  [{klines[i]['time']}] SELL @ {price:,.2f}  (PnL {pnl:+.2f}%)")
            entry = None

    if coins > 0:
        final = coins * closes[-1]
        pnl = (closes[-1] / entry - 1) * 100 if entry else 0.0
        trades.append((klines[-1]["time"], "CLOSE", closes[-1]))
        print(f"  [{klines[-1]['time']}] CLOSE @ {closes[-1]:,.2f} (PnL {pnl:+.2f}%)")
    else:
        final = cash

    print("n" + "=" * 56)
    print("  BAO CAO PAPER TRADING")
    print("=" * 56)
    print(f"  Von ban dau : ${INITIAL:,.0f}")
    print(f"  Von cuoi    : ${final:,.2f}")
    print(f"  Loi nhuan   : {(final / INITIAL - 1) * 100:+.2f}%")
    print(f"  So lenh     : {len(trades)}")
    print("=" * 56)

    with open(LOG_FILE, "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["time", "action", "price"])
        for t in trades:
            w.writerow(t)
    print(f"  Log: {LOG_FILE}")
    print("n  Demo - khong dung tien that. Noi dung giao duc.")


if __name__ == "__main__":
    run()

Script chỉ dùng thư viện chuẩn của Python (csv, json, os, sys, urllib.request, datetime, pathlib) — không cần pip install gì thêm. Đây là lựa chọn có chủ đích để người mới học có thể chạy được ngay.

10. Kết quả chạy thật — bot demo đã làm gì

Chạy thật bot trên dữ liệu giá BTC/USDT 1h của Binance với vốn ảo 10.000 USD, MA20, chúng ta có kết quả:

Chỉ số Giá trị
Vốn ban đầu $10,000.00
Vốn cuối $10,042.61
Lợi nhuận +0.43%
Số lệnh 10 lệnh (BUY/SELL/CLOSE)

Nhật ký giao dịch cho thấy bot hoạt động đúng logic: mua khi giá vượt lên trên MA20, bán khi giá rơi xuống dưới MA20, và đóng vị thế cuối theo giá hiện tại.

Điều đáng chú ý: 0.43% trong ~3 ngày dữ liệu 1h — con số nhỏ, nhưng quan trọng là bot hoạt động đúng quy trình và có báo cáo rõ ràng. Với một bot demo, mục tiêu không phải là “kiếm thật nhiều” mà là kiểm chứng chiến lược có lý thuyết đứng đắn hay không trước khi nghĩ đến tiền thật.

Nếu muốn cải thiện, bạn có thể thử:

  • Đổi MA=10 hoặc MA=50 trong .env và so sánh kết quả.
  • Đổi SYMBOL=ethusdt để xem chiến lược chạy trên đồng khác.
  • Tăng limit lên 500 nến để có chuỗi dữ liệu dài hơn.
  • Thêm bộ lọc khối lượng, thêm stop loss, hoặc chỉ giao dịch khi xu hướng rõ ràng.

Nhìn vào danh sách lệnh, bạn có thể nhận ra bot vào lệnh khá dày đặc trong vài ngày — đó là đặc điểm của chiến lược MA ngắn hạn trên khung 1h: tín hiệu xuất hiện thường xuyên nhưng mỗi lệnh lãi/lỗi nhỏ. Một chiến lược như vậy phù hợp với mục tiêu “tần suất cao, biên lợi nhuận nhỏ” nhưng sẽ rất nhạy với phí giao dịch nếu chuyển sang thật. Đây chính là lý do vì sao việc ghi log và đo lường PnL lại quan trọng: số liệu sẽ tự nói cho bạn biết chiến lược có đáng theo đuổi hay không.

11. Hạn chế của bot demo và cách chuyển sang chiến lược thật

Bot demo rất hữu ích nhưng có những giới hạn bạn cần biết:

1. Không mô phỏng trượt giá (slippage) và phí. Lệnh thật phải trả phí giao dịch và có thể khớp ở giá xấu hơn giá hiển thị. Một chiến lược thắng 0.5% trên demo có thể chỉ còn 0.2% sau phí trên tài khoản thật.

2. Giá khớp lý tưởng. Bot demo giả định bạn mua/bán đúng giá đóng cửa — trên thực tế lệnh thị trường có thể khớp lệch vài chục đô la với BTC.

3. Không có độ trễ và lỗi kết nối. Bot thật phải xử lý timeout, mất kết nối, lỗi API, thậm chí sàn bảo trì. Bài học về vận hành bot thật sẽ nói kỹ hơn về phần này.

4. Tâm lý con người không có trong demo. Bạn có thể “cháy” tài khoản ảo mà không đau; với tiền thật, việc giữ kỷ luật theo tín hiệu là thử thách lớn nhất.

Để chuyển sang chiến lược thật, lộ trình gợi ý:

  1. Chạy bot demo ít nhất 1–2 tháng với nhiều cấu hình.
  2. Thêm phí giao dịchslippage vào mô phỏng để có số liệu thực tế hơn.
  3. Backtest trên dữ liệu dài hạn (nhiều năm, nhiều điều kiện thị trường).
  4. Thử nghiệm trên tài khoản demo của sàn (Binance Testnet, MT5 demo) — nơi có cả phí, độ trễ và thanh khoản thật.
  5. Chỉ khi chiến lược ổn định, mới bắt đầu với vốn nhỏ và tăng dần.

12. Quản trị rủi ro và những điều cần lưu ý

Dù là bot demo, bạn vẫn nên hình thành tư duy quản trị rủi ro ngay từ đầu — vì nó sẽ được mang nguyên vẹn sang bot thật:

  • Không “all-in” một lệnh: Bot demo của chúng ta all-in để đơn giản, nhưng bot thật nên chia nhỏ vốn theo phần trăm rủi ro.
  • Stop loss luôn cần thiết: Chiến lược chỉ có tín hiệu MA mà không có stop loss có thể thua rất sâu khi thị trường biến động mạnh.
  • Không cam kết lợi nhuận: Bất kỳ ai hứa hẹn “% cố định mỗi tháng” đều là dấu hiệu đỏ. Thị trường luôn có rủi ro.
  • Demo không phải thật: Kết quả demo tốt chưa đảm bảo kết quả thật. Luôn đối chiếu cả phí, trượt giá và tâm lý.
  • Nội dung giáo dục: Mọi nội dung trong loạt bài Python 365 chỉ phục vụ học tập lập trình và phân tích dữ liệu, không phải lời khuyên đầu tư.
  • Định cỡ vị thế (position sizing): đừng bao giờ dùng toàn bộ vốn cho một lệnh. Quy tắc phổ biến là chỉ rủi ro 1–2% tài sản mỗi lệnh.
  • Theo dõi drawdown: ghi lại mức sụt giảm tối đa từ đỉnh đến đáy của tài khoản; nếu drawdown quá sâu, chiến lược đang quá rủi ro dù tổng PnL vẫn dương.
  • Đa dạng hóa: thử bot trên nhiều cặp và nhiều khung thời gian để tránh phụ thuộc vào một thị trường duy nhất.
  • Kiểm tra nhiều giai đoạn thị trường: một chiến lược thắng trong xu hướng tăng có thể thua trong thị trường đi ngang — hãy backtest qua cả ba trạng thái.

Nếu bạn muốn đi sâu vào bot giao dịch thật với quản trị rủi ro bài bản, hãy tham khảo khóa học Bot Auto Trading tại Hướng Nghiệp Dữ Liệu — nơi hướng dẫn đầy đủ từ chiến lược, backtest, kết nối sàn đến vận hành VPS 24/7.

13. FAQ

Bot đặt lệnh demo có cần nạp tiền không? Không. Bot demo dùng sổ cái ảo, bạn chỉ cần cấu hình vốn ảo trong file .env.

Tải giá Binance có cần API key không? Không. Dữ liệu nến giá (klines) là public API, chỉ cần gửi request HTTP là nhận dữ liệu.

Tại sao kết quả demo lại là số âm hoặc dương rất nhỏ? Vì MA20 là chiến lược đơn giản, chỉ phản ánh xu hướng trung bình. Kết quả nhỏ là bình thường; mục tiêu là học quy trình vận hành bot.

Làm sao xem bot đã giao dịch những lệnh nào? Mở file paper_trading_log.csv — mỗi dòng là một lệnh với thời gian, hành động (BUY/SELL/CLOSE) và giá.

Bot demo có thể dùng cho tiền thật không? Không nên. Bot demo bỏ qua phí, trượt giá và độ trễ. Muốn giao dịch thật, hãy nâng cấp theo lộ trình ở mục 11 và luôn thử trên tài khoản demo của sàn trước.

Cần cài thư viện Python nào không? Không. Script chỉ dùng thư viện chuẩn của Python.

Có thể chạy với symbol khác không? Có. Đổi SYMBOL=ethusdt hoặc bất kỳ cặp nào có trên Binance (vd bnbusdt, solusdt).

Bot demo có cần chạy liên tục 24/7 không? Không. Bot này phân tích dữ liệu lịch sử và kết thúc ngay sau khi in báo cáo. Nếu muốn bot tự theo dõi thị trường liên tục, bạn cần vòng lặp thời gian thực và chạy trên VPS — nội dung của các bài học nâng cao hơn.

Vì sao bot mua nhiều lần mà không phải lúc nào cũng lãi? Vì chiến lược MA đơn giản không thể thắng mọi lệnh. Điều quan trọng là tổng PnL cuối kỳ dương và hiểu rõ xác suất thắng thua của chiến lược.

File CSV sinh ra để làm gì? Để kiểm toán và phân tích: bạn có thể mở bằng Excel, vẽ biểu đồ giá theo lệnh, hoặc dùng làm dữ liệu đầu vào cho backtest và tối ưu tham số trong các bài học sau.

Làm sao biết bot chạy đúng hay sai? Kiểm tra ba dấu hiệu: (1) bot in đúng số nến đã tải, (2) các lệnh BUY/SELL thay phiên nhau và không có lệnh BUY khi đã giữ coin, (3) vốn cuối kỳ tính lại khớp với nhật ký lệnh.

Tôi có thể thêm chỉ báo khác như RSI, MACD không? Hoàn toàn được. Bạn chỉ cần tính thêm chỉ báo trong vòng lặp và bổ sung điều kiện vào quy tắc mua/bán. Đây là bài tập mở rộng tuyệt vời sau bài học này.

14. Kết luận

Trong Ngày 63 của loạt bài Python 365, bạn đã xây dựng một bot đặt lệnh demo hoàn chỉnh bằng Python: cấu hình qua .env, tải giá thật từ Binance public API, sinh tín hiệu trung bình động MA20, mô phỏng lệnh giấy trên sổ cái ảo, tính PnL và ghi nhật ký giao dịch CSV.

Những kỹ năng bạn vừa rèn:

  • Đọc file cấu hình và biến môi trường.
  • Gọi HTTP API và xử lý JSON bằng thư viện chuẩn.
  • Triển khai một chiến lược giao dịch định lượng đơn giản.
  • Mô phỏng vòng đời lệnh mua/bán trên sổ cái ảo.
  • Tính toán báo cáo hiệu suất (PnL).
  • Ghi log và xuất dữ liệu CSV.

Quan trọng nhất: bạn đã có một bộ khung bot có thể mở rộng. Từ đây, bạn có thể thêm nhiều chỉ báo, thêm stop loss, kết nối MT5 hoặc sàn thật, và cuối cùng vận hành bot 24/7 trên VPS — đó chính là hành trình Bot Auto Trading mà Hướng Nghiệp Dữ Liệu đồng hành cùng bạn.

Bài học hôm nay tuy nhỏ nhưng đã gói trọn một vòng đời phần mềm thực tế: từ cấu hình, dữ liệu, logic, báo cáo đến log — đúng những gì một bot giao dịch thật cần có. Hãy giữ file Day 63_Bot dat lenh demo.pypaper_trading_log.csv cẩn thận, vì các bài học tiếp theo sẽ xây dựng dựa trên nền tảng này: vẽ biểu đồ kết quả, tối ưu tham số, thêm chỉ báo, và cuối cùng là kết nối với sàn để giao dịch có kiểm soát.

Chúc bạn thành công trên hành trình Python 365 ngày — và nhớ rằng, con đường an toàn nhất để trở thành người vận hành bot giỏi luôn bắt đầu từ những lệnh demo biết đo lường, chứ không phải từ những lời hứa lợi nhuận.

Đọc thêm:

  • Python 365 Ngày 62 — Top API miễn phí cho lập trình viên Python
  • Khóa học Lập trình Python cơ bản: https://www.huongnghiepdulieu.com/lap-trinh-python-co-ban/
  • Khóa học Bot Auto Trading: https://www.huongnghiepdulieu.com/bot-auto-trading/
Đặng Trí Thanh

Đặng Trí Thanh

Giám đốc Công nghệ · DNT Digital · Giảng viên HNDL
853 Bài viết
15.4k Người theo dõi
120k+ Lượt đọc

Đặng Trí Thanh — Founder & CTO · Hướng Nghiệp Dữ Liệu - DNT Digital. Chuyên đào tạo và triển khai thực chiến Python, MT5 và hệ thống bot auto trading / IB cho học viên và doanh nghiệp.