ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ค ํํธ ํฌ์ ์ค์ – ์ฆ๊ถ์ฌ API๋ฅผ ํ์ฉํ ์๋ ๋งค๋งค ์์คํ ๊ตฌ์ถํ๊ธฐ
octo54 2025. 10. 21. 11:25๐ค ํํธ ํฌ์ ์ค์ – ์ฆ๊ถ์ฌ API๋ฅผ ํ์ฉํ ์๋ ๋งค๋งค ์์คํ ๊ตฌ์ถํ๊ธฐ
์ง๊ธ๊น์ง๋ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ , ๋ฐฑํ
์คํธํ๊ณ , ๋ฆฌ๋ฐธ๋ฐ์ฑํ๋ฉฐ
AI๋ก ๊ฐ์ค์น๋ฅผ ์กฐ์ ํ๋ ์๋ฎฌ๋ ์ด์
๋จ๊ณ๊น์ง ์์ฑํ์ต๋๋ค.
์ด์ ๋จ์ ๊ฑด ๋จ ํ๋ —
**“์ค์ ๋งค๋งค๋ฅผ ์๋์ผ๋ก ์คํํ๋ ์์คํ
”**์
๋๋ค.
์ค๋์ ๊ตญ๋ด ๊ฐ์ธ ํฌ์์๋ค์ด ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋
**ํค์์ฆ๊ถ OpenAPI (Python ์ฐ๋)**์ ๊ธฐ๋ฐ์ผ๋ก,
์ค์ ๋งค๋งค ์๋ํ๋ฅผ ๊ตฌํํ๋ ๊ณผ์ ์ ์๊ฐํฉ๋๋ค.
1๏ธโฃ ์์คํ ๊ฐ์
์๋ ๋งค๋งค ์์คํ ์ ํฌ๊ฒ ๋ค์ ๋ค์ฏ ๋จ๊ณ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
[1] ์ข
๋ชฉ ์ ์ (ํฉํฐ ์ ๋ต ๊ธฐ๋ฐ)
→ [2] ๋งค์ ์กฐ๊ฑด ํ๋จ (์๊ทธ๋)
→ [3] ์ฃผ๋ฌธ ์คํ (API)
→ [4] ํฌํธํด๋ฆฌ์ค ๊ธฐ๋ก
→ [5] ์์ต๋ฅ ๋ฐ ๋ก๊ทธ ๊ด๋ฆฌ
์ด ๊ตฌ์กฐ๋ ์ค์ ํํธ ํ๋ ๋งค๋งค ์์คํ
์ ์ถ์ํ์
๋๋ค.
๋จ, ๊ฐ์ธ ํฌ์์๋ API ํธ์ถ ์ ํ๊ณผ ์ค์๊ฐ ์ฒ๋ฆฌ ํ๊ณ๋ฅผ ๋ฐ๋์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
2๏ธโฃ ํค์ OpenAPI ์ค์น
- ํค์์ฆ๊ถ ์์ ๋ฌธ HTS ์ค์น
- ํค์์ฆ๊ถ OpenAPI+ ์ค์น
- ActiveX ๊ธฐ๋ฐ์ด๋ฏ๋ก ๋ฐ๋์ Windows ํ๊ฒฝ ํ์
- ๋ก๊ทธ์ธ ํ KOA Studio ์คํ → API ๋์ ํ ์คํธ
3๏ธโฃ Python ์ฐ๋
ํค์ OpenAPI๋ COM(Component Object Model) ๋ฐฉ์์ผ๋ก ํต์ ํฉ๋๋ค.
์ด๋ฅผ Python์์ ๋ค๋ฃจ๋ ค๋ฉด PyQt5 + pythoncom + win32com.client ์กฐํฉ์ ์๋๋ค.
pip install pyqt5 pywin32
4๏ธโฃ ๊ธฐ๋ณธ ๋งค์/๋งค๋ ์ฝ๋ ์์
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QAxContainer import QAxWidget
import time
app = QApplication(sys.argv)
kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
# ๋ก๊ทธ์ธ
kiwoom.dynamicCall("CommConnect()")
time.sleep(5)
# ๊ณ์ข๋ฒํธ ํ์ธ
account = kiwoom.dynamicCall("GetLoginInfo(QString)", ["ACCNO"]).strip(';')
print("๊ณ์ข๋ฒํธ:", account)
# ๋งค์ ์ฃผ๋ฌธ ์์
kiwoom.dynamicCall(
"SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
[
"๋งค์์ฃผ๋ฌธ",
"0101",
account,
1, # 1: ๋งค์ / 2: ๋งค๋
"005930", # ์ผ์ฑ์ ์
10, # ์๋
0, # ๊ฐ๊ฒฉ (์์ฅ๊ฐ)
"03", # ์ฃผ๋ฌธ์ ํ: ์์ฅ๊ฐ
""
]
)
print("โ
๋งค์ ์ฃผ๋ฌธ ์ ์ก ์๋ฃ")
์ด ์ฝ๋๋ ์ผ์ฑ์ ์ 10์ฃผ๋ฅผ ์์ฅ๊ฐ๋ก ๋งค์ํ๋ ๊ฐ๋จํ ์์์
๋๋ค.
SendOrder์ ํ๋ผ๋ฏธํฐ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ฉด, ๋ชจ๋ ์ฃผ๋ฌธ์ ์๋ํํ ์ ์์ต๋๋ค.
5๏ธโฃ ์๋ ๋งค๋งค ๋ก์ง (ํฉํฐ ์ ๋ต ๊ฒฐํฉ)
์ด์ ์์ ๋ง๋ ํฉํฐ ๊ธฐ๋ฐ ํฌํธํด๋ฆฌ์ค ๊ฒฐ๊ณผ๋ฅผ ํ์ฉํด๋ด
์๋ค.
์๋ฅผ ๋ค์ด, ๋งค์ผ ์ค์ 9์ ์๋์ผ๋ก ๋ค์ ์กฐ๊ฑด์ ์ํํฉ๋๋ค.
from datetime import datetime
import schedule, pandas as pd
def auto_trade():
portfolio = pd.read_csv("factor_rank.csv") # ๋ฆฌ๋ฐธ๋ฐ์ฑ ๊ฒฐ๊ณผ ํ์ผ
top_picks = portfolio.head(3)["Ticker"].tolist()
for code in top_picks:
print(f"{datetime.now()} โถ {code} ๋งค์ ์๋ ์ค…")
kiwoom.dynamicCall(
"SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
["์๋๋งค์", "0101", account, 1, code, 5, 0, "03", ""]
)
schedule.every().day.at("09:01").do(auto_trade)
while True:
schedule.run_pending()
time.sleep(60)
๐ ์ด๋ ๊ฒ ํ๋ฉด ๋งค์ผ 9์ 1๋ถ,
๊ฐ์ฅ ์์ ํฉํฐ ์ ์๋ฅผ ๊ฐ์ง ์ข
๋ชฉ 3๊ฐ๋ฅผ ์๋์ผ๋ก ๋งค์ํ๊ฒ ๋ฉ๋๋ค.
6๏ธโฃ ํฌํธํด๋ฆฌ์ค ๊ธฐ๋ก & ๋ฆฌํฌํธ ์ฐ๋
์๋ ๋งค๋งค๊ฐ ์คํ๋ ๋๋ง๋ค
- ๋งค์ ์ข ๋ชฉ, ์๋, ์ฒด๊ฒฐ ๊ฐ๊ฒฉ, ์๊ณ , ์์ต๋ฅ ์ CSV๋ก ์ ์ฅํ๊ณ ,
- ๊ทธ ๋ฐ์ดํฐ๋ฅผ PDF ๋ฆฌํฌํธ ์์ฑ ์ฝ๋์ ์ฐ๋ํ๋ฉด
๋งค์ผ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ ์ค์ ์ฑ๊ณผ ๋ฆฌํฌํธ๊ฐ ์์ฑ๋ฉ๋๋ค.
with open("trade_log.csv", "a", encoding="utf-8") as f:
f.write(f"{datetime.now()},{code},๋งค์,5\n")
7๏ธโฃ ๋ฆฌ์คํฌ ๊ด๋ฆฌ: Stop Loss & Take Profit
์๋ ๋งค๋งค์ ํต์ฌ์ “์์ต ์๋ ์ ์ด”์ ๋๋ค.
def risk_control(current_price, avg_price):
profit_rate = (current_price - avg_price) / avg_price
if profit_rate <= -0.05:
print("๐ -5% ์์ ์คํ")
elif profit_rate >= 0.10:
print("๐ +10% ์ต์ ์คํ")
์ด ๋ก์ง์ ์ค์๊ฐ ๊ฐ๊ฒฉ ๋ฐ์ดํฐ์ ์ฐ๊ฒฐํ๋ฉด,
์ ํด๋ ์์ /์ต์ ๊ตฌ๊ฐ์์ ์๋ ๋งค๋๊น์ง ๊ฐ๋ฅํฉ๋๋ค.
โ ๏ธ ์ฃผ์ํ ์
์ฃผ์ ํญ๋ชฉ ์ค๋ช
| ๋ก๊ทธ์ธ ์ธ์ | 24์๊ฐ ์ ์ง ๋ถ๊ฐ → ์ฌ๋ก๊ทธ์ธ ์๋ํ ํ์ |
| API ํธ์ถ ์ ํ | ์ด๋น 5ํ ๋ฏธ๋ง ๊ถ์ฅ |
| ์ค์๊ฐ ๋ฐ์ดํฐ | HTS์ ๋์ผํ์ง ์์ ์ ์์ |
| ๋ณด์ | ํค ํ์ผ, ๊ณ์ข๋ฒํธ, ๋น๋ฐ๋ฒํธ ์ ๋ ํ๋์ฝ๋ฉ ๊ธ์ง |
๐ ์ ๋ฆฌ
๋จ๊ณ ์ค๋ช
| 1 | ํค์ OpenAPI ์ค์น ๋ฐ ๋ก๊ทธ์ธ |
| 2 | PyQt5๋ก API ํธ์ถ ๊ตฌ์กฐ ์ดํด |
| 3 | ๋งค์/๋งค๋ ์ฃผ๋ฌธ ์๋ํ |
| 4 | ํฉํฐ ์ ๋ต ๊ฒฐํฉ์ผ๋ก ์๋ ์ข ๋ชฉ ์ ์ |
| 5 | ์์ต๋ฅ ๊ธฐ๋ก + ๋ฆฌํฌํธ ์ฐ๋ |
| 6 | ์์ ·์ต์ ์กฐ๊ฑด์ผ๋ก ๋ฆฌ์คํฌ ์ ์ด |
๐ ์ด๋ ๊ฒ ํ๋ฉด “๋งค์ผ ์๋์ผ๋ก ํํธ ์ ๋ต์ด ์คํ๋๋ ์์ ์๋ ๋งค๋งค ์์คํ ”์ด ์์ฑ๋ฉ๋๋ค.
๐ ๋ค์ ๊ธ ์๊ณ
๋ค์ ํธ์์๋ **“๋ฐฑ์๋ ์๋ฒ์์ ์๋ ๋งค๋งค ์คํํ๊ธฐ – Flask + ์ค์ผ์ค๋ฌ + DB ์ฐ๋ ๊ตฌ์กฐ”**๋ฅผ ๋ค๋ฃน๋๋ค.
์ฆ, Python ์ฝ๋๊ฐ ์๋ API ์๋ฒ ํํ์ ํํธ ๋งค๋งค ์์ง์ผ๋ก ์
๊ทธ๋ ์ด๋ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ๋๋ฆด๊ฒ์.
ํํธ์๋๋งค๋งค,ํค์์ฆ๊ถAPI,ํ์ด์ฌ์ฃผ์,์๋๋งค๋งค์์คํ ,ํฉํฐํฌ์,๋ฆฌ๋ฐธ๋ฐ์ฑ,์ฃผ์๋ด,๋ฐ์ดํฐํฌ์,PyQt5,์๋ํฌ์
'์ฃผ์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- nextJS
- PostgreSQL
- seo ์ต์ ํ 10๊ฐ
- SEO์ต์ ํ
- rag
- REACT
- Next.js
- ์น๊ฐ๋ฐ
- ๋ฐฑ์๋๊ฐ๋ฐ
- JWT
- CI/CD
- fastapi
- ๋ฅ๋ฌ๋
- ์๋ฐ๋ฉด์
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- ai์ฒ ํ
- Express
- Redis
- ํ๋ก ํธ์๋๊ฐ๋ฐ
- NestJS
- flax
- llm
- JAX
- Python
- Docker
- DevOps
- kotlin
- Prisma
- node.js
- ์ฟ ๋ฒ๋คํฐ์ค
| ์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |

