왜 미국 주식 자동매매가 좋은가요?
🎯 1. 시장이 24시간 돌아가진 않지만, 야간 거래 가능
미국 주식 매매 장점은 야간 거래가 가능하다는 점입니다.
저처럼 회사에 다니면서 야간에 시스템 트레이딩을 공부하는 사람은 야간에는 테스트가 힘듭니다.
NXT 가 가능한 시간이 있기는 하지만 퇴근 하고 저녁 식사를 하고 나면 대부분 해당 시간 이후 입니다.
정말 하루 휴가를 내지 않으면 테스트가 불가능합니다. TOT
오~~ 그런데 미국 주식은 야간에도 가능합니다.
구분 | 국내(KRX) | 국내 NXT | 미국 주식 (서머타임 적용) | 미국 주식 (서머타임 미적용) |
프리마켓 | 08:30~08:40 (종가매매) | 08:00~08:50 (프리마켓) | 17:00~22:30 | 18:00~23:30 |
정규장 | 09:00~15:30 | 09:00~15:20 (메인마켓) | 22:30~05:00 (다음날) | 23:30~06:00 (다음날) |
애프터마켓 | 15:40~16:00 (종가매매) | 15:30~20:00 (애프터마켓) | 05:00~07:00 (다음날, 1차) 07:00~09:00 (2차) |
06:00~07:00 (다음날, 1차) 07:00~09:00 (2차) |
단일가매매 | 16:00~18:00 | 없음 | 없음 | 없음 |
총 거래 가능 시간 | 약 6.5시간 | 12시간 | 최대 16시간(프리+정규+애프터) | 최대 16시간(프리+정규+애프터) |
✔️ 자동매매 시스템을 퇴근 후에도 작동하게 만들면 "자고 있는 동안 돈이 일한다"는 진짜 자동 수익 모델 가능!
🌊 2. 변동성이 크고 기회가 많다
테슬라, 엔비디아 같은 미국 종목은 하루에 5~10%도 쉽게 움직입니다.
즉, 간단한 자동전략으로도 먹을 게 많아요.
✔️ "코스피야 눈치게임, 나스닥은 롤러코스터!"
변동성이 있어야 자동 전략도 수익을 낼 확률이 높습니다.
💵 3. 환율 상승도 추가 수익!
주가도 오르고 환율도 오르면?
👉 두 배로 이익! 반대로 손해도 두 배니까 리스크 관리 중요.
🤖 Step-by-Step 코드 설명 (미국 주식 자동매매 시스템)
🧱 Step 1: 프로그램 시작 + 기본 설정
self.kiwoom = Kiwoom()
self.kiwoom.CommConnect(block=True)
self.account = self.kiwoom.GetLoginInfo("ACCNO")[0]
키움 API에 연결하고 로그인 계좌를 불러옵니다. 미국 주식은 해외주식 거래 가능한 계좌여야 해요.
📊 Step 2: 엑셀에서 종목, 매수가, 매도가 불러오기
def read_excel(self):
return pd.read_excel("stocks.xlsx")
종목명 | 매수가 | 매도가
------|--------|--------
AAPL | 180 | 200
TSLA | 250 | 300
📂 엑셀 파일로 전략 관리 가능 = 비전문가도 쉽게 전략 수정 가능!
🔍 Step 3: 현재가 조회 (미국 주식용)
def get_current_price(self, code):
data = self.kiwoom.block_request("opt40001", 종목코드=code, output="해외주식기본정보", next=0)
price = data.get("현재가", "0")
return int(str(price).replace(",", "").split('.')[0])
미국 주식은 opt40001이라는 TR을 써야 시세 조회가 됩니다.
일반 국내주식 TR(opt10001)은 사용할 수 없어요.
🤝 Step 4: 조건 체크 → 자동 매수/매도
if current <= buy_price and name not in self.bought_set:
self.kiwoom.SendOrder("미국주식매수", "1001", self.account, 1, code, qty, 0, "03", "")
elif current >= sell_price and name not in self.sold_set:
self.kiwoom.SendOrder("미국주식매도", "1002", self.account, 2, code, qty, 0, "03", "")
📥 매수가 이하면 매수, 📤 매도가 이상이면 매도
매수/매도는 **시장가("03")**로 실행해서 빠르게 체결시킵니다.
self.bought_set은 중복 주문 방지용입니다.
📦 Step 5: 현재 보유 종목 업데이트
self.kiwoom.block_request("opw00018", 계좌번호=..., 비밀번호=..., ...)
이 부분은 아직 국내 주식 기준입니다.
미국 주식은 opw00005나 opw00004와 같은 별도 해외계좌 평가잔고 조회 TR을 사용해야 할 수도 있어요.
추후 확장 포인트!
✅ 전체 코드 (미국 주식용)
import sys
import time
import pandas as pd
from datetime import datetime
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QTimer
from pykiwoom.kiwoom import Kiwoom
EXCEL_PATH = "stocks.xlsx"
LOG_FILE = "trade_log.txt"
INTERVAL_MS = 30000 # 30초 주기
class TradingBot(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("📈 미국주식 자동 매매 시스템")
self.setGeometry(300, 100, 900, 700)
self.kiwoom = Kiwoom()
self.kiwoom.CommConnect(block=True)
self.account = self.kiwoom.GetLoginInfo("ACCNO")[0]
self.account_pw = ""
self.bought_set = set()
self.sold_set = set()
self.init_ui()
self.get_password()
self.update_holdings()
self.log("미국주식 자동매매 시작 ✅")
self.timer = QTimer()
self.timer.timeout.connect(self.run_trading)
self.timer.start(INTERVAL_MS)
def init_ui(self):
self.text_log = QTextEdit()
self.text_log.setReadOnly(True)
self.btn_manual = QPushButton("🔁 수동 실행")
self.btn_manual.clicked.connect(self.run_trading)
self.status_label = QLabel("⏱️ 대기 중...")
self.table = QTableWidget()
self.table.setColumnCount(4)
self.table.setHorizontalHeaderLabels(["종목명", "수량", "매입가", "현재가"])
self.table.horizontalHeader().setStretchLastSection(True)
layout = QVBoxLayout()
layout.addWidget(self.text_log)
layout.addWidget(self.status_label)
layout.addWidget(self.btn_manual)
layout.addWidget(QLabel("\n📦 현재 보유 종목"))
layout.addWidget(self.table)
central = QWidget()
central.setLayout(layout)
self.setCentralWidget(central)
def get_password(self):
pw, ok = QInputDialog.getText(self, "계좌 비밀번호 입력", "계좌 비밀번호를 입력하세요:", QLineEdit.Password)
if ok and pw:
self.account_pw = pw
self.log("🔐 계좌 비밀번호가 등록되었습니다.")
else:
QMessageBox.critical(self, "오류", "비밀번호가 입력되지 않았습니다. 프로그램을 종료합니다.")
sys.exit(1)
def log(self, message):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_msg = f"[{now}] {message}"
self.text_log.append(log_msg)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(log_msg + "\n")
def read_excel(self):
return pd.read_excel(EXCEL_PATH)
def name_to_code(self, name):
# 미국 주식은 'A' 접두사를 붙이는 경우가 많습니다
return f"A{name.strip().upper()}"
def get_current_price(self, code):
try:
data = self.kiwoom.block_request(
"opt40001",
종목코드=code,
output="해외주식기본정보",
next=0
)
price = data.get("현재가", "0")
return int(str(price).replace(",", "").split('.')[0])
except Exception as e:
self.log(f"[현재가 조회 실패] {code} : {e}")
return 0
def run_trading(self):
self.status_label.setText("🔍 주가 확인 중...")
df = self.read_excel()
for _, row in df.iterrows():
name = row['종목명']
buy_price = int(row['매수가'])
sell_price = int(row['매도가'])
code = self.name_to_code(name)
current = self.get_current_price(code)
self.log(f"{name} 현재가: {current} / 매수: {buy_price} / 매도: {sell_price}")
qty = 1 # 테스트용 수량
if current <= buy_price and name not in self.bought_set:
self.log(f"📥 매수 주문: {name} @ {current}")
self.kiwoom.SendOrder("미국주식매수", "1001", self.account, 1, code, qty, 0, "03", "")
self.bought_set.add(name)
self.sold_set.discard(name)
elif current >= sell_price and name not in self.sold_set:
self.log(f"📤 매도 주문: {name} @ {current}")
self.kiwoom.SendOrder("미국주식매도", "1002", self.account, 2, code, qty, 0, "03", "")
self.sold_set.add(name)
self.bought_set.discard(name)
self.update_holdings()
self.status_label.setText("⏱️ 대기 중...")
def update_holdings(self):
try:
data = self.kiwoom.block_request("opw00018",
계좌번호=self.account,
비밀번호=self.account_pw,
비밀번호입력매체구분="00",
조회구분=2,
output="계좌평가잔고개별합산",
next=0)
if not isinstance(data, dict) or '종목번호' not in data:
self.log("[경고] 보유 종목 정보가 없습니다.")
self.table.setRowCount(0)
return
codes = data['종목번호']
names = data['종목명']
qtys = data['보유수량']
prices = data['매입가']
self.table.setRowCount(len(codes))
for i in range(len(codes)):
name = names[i].strip()
qty = int(qtys[i]) if str(qtys[i]).strip().isdigit() else 0
buy_price = int(prices[i]) if str(prices[i]).strip().isdigit() else 0
cur_price = self.get_current_price(codes[i].strip())
self.table.setItem(i, 0, QTableWidgetItem(name))
self.table.setItem(i, 1, QTableWidgetItem(str(qty)))
self.table.setItem(i, 2, QTableWidgetItem(str(buy_price)))
self.table.setItem(i, 3, QTableWidgetItem(str(cur_price)))
except Exception as e:
self.log(f"[보유 종목 조회 오류] {str(e)}")
if __name__ == "__main__":
app = QApplication(sys.argv)
bot = TradingBot()
bot.show()
sys.exit(app.exec_())
🔚 마무리 - 미국 주식 자동매매, 지금 시작할 이유
낮에만 거래 | 퇴근 후 거래 가능 |
하루 수익 적음 | 하루 5~10% 기회 |
코스피 지수에 민감 | 다양한 종목 개별성장 |
환율효과 없음 | 환차익도 가능 |
'시스템 트레이딩 > 엑셀 주식 트레이더 1호' 카테고리의 다른 글
엑셀 + 파이썬 주식 트레이더 1.2편 (Qt GUI 보유 주식 표시) (1) | 2025.06.27 |
---|---|
엑셀 + 파이썬 주식 트레이더 1.1편 (Console 로그) (2) | 2025.06.27 |