API 수수료 페이백 혜택으로 비용 0원 자동매매 구축하기
+ 신규 가입 7만원 받아서 투자 시드로 활용하세요!
안녕하세요! 최근 코인 시장 변동성이 커지면서 24시간 대응이 가능한 '자동매매'에 관심을 가지는 분들이 많습니다.
마침 빗썸에서 API 거래 수수료를 환급(페이백)해주는 혜택을 진행하고 있어, 수수료 부담 없이 자동매매 봇을 돌리기 가장 좋은 시기입니다. 코딩을 몰라도 누구나 딸깍 한 번으로 실행할 수 있는 초간단 파이썬 자동매매 프로그램과 함께, 시드머니 7만원을 공짜로 얻는 팁까지 정리해 드립니다.
내 돈 넣고 봇을 돌릴 필요 없습니다. 신규 가입 시 즉시 7만원을 받을 수 있으니, 이 돈을 봇의 시드머니로 활용하세요.
빗썸 신규가입 7만원 받으러 가기 →시드머니가 준비되었다면, 수수료 페이백 혜택을 받고 바로 자동매매 봇 세팅을 시작하시면 됩니다.
아래 본문을 계속 읽어주세요 ↓자동매매(API) 봇을 돌릴 때 가장 무서운 것이 바로 '거래 수수료'입니다. 봇이 하루에도 수십 번씩 사고팔기를 반복하면 수익보다 수수료가 더 크게 나가는 배보다 배꼽이 더 큰 상황이 발생하죠.
하지만 현재 빗썸에서는 API 거래 시 수수료를 환급해 주는 혜택을 제공하고 있어, 사실상 수수료 0원으로 시스템 트레이딩 환경을 구축할 수 있습니다. 초보자가 자동매매를 연습하기에 이보다 완벽한 조건은 없습니다. 더구나 내가 설정한 자동매매가 만약 돈을 잃지 아주 약간의 이득이라도 볼 수 있다면, 해당 거래에서 발생한 거래 수수료를 쌓아서 환급받을 수 있습니다. 최대 1000억까지 환급해준다고 하니깐 몇 가지 연구를 통해 최대한 많은 환급금을 받을 수 있도록 노력해보세요.
앞서 말씀드렸듯, 아직 가입 전이라면 제발 내 생돈 넣지 마시고 신규 가입 7만원 혜택을 먼저 챙겨서 시드로 쓰세요. 가입 없이 API부터 건드리면 7만원이 누락될 수 있으니 아래 링크를 먼저 확인해 주세요.
👉 [필독] 빗썸 가입하고 투자 지원금 7만원 받는 법
수수료 페이백을 받기 위해 빗썸 이벤트 페이지에 접속하여 [API 거래 이벤트]에서 '참여하기' 버튼을 필수로 눌러주세요.

마이페이지의 [API 관리] 메뉴로 들어가서 봇과 연결할 API Key를 발급받습니다.
🚨 [절대 주의사항]
1. 발급받은 API 키는 절대 타인에게 공유하거나 인터넷(깃허브 등)에 노출하면 안 됩니다.
2. 권한 설정 시 '출금/이체하기' 기능은 반드시 체크 해제(비활성화)하시고, 오직 '조회'와 '거래' 권한만 부여하세요!



이제 발급받은 API 키를 프로그램에 넣고 빗썸 서버와 연결할 차례입니다. 파이썬이 익숙한 분들은 아래 코드를 복사해서 쓰시면 되고, 코딩을 전혀 모르는 초보자분들은 제가 만들어둔 원클릭 실행 프로그램을 다운로드해서 사용하시면 됩니다.
복잡한 파이썬 설치 과정 없이 바로 실행할 수 있도록 세팅해 둔 파일을 첨부합니다. 압축을 풀고 클릭만 하시면 됩니다.
라이브러리(pip install pybithumb) 설치 후, 아래 기본 코드를 바탕으로 본인만의 전략(이동평균선 등)을 추가해 보세요.
"""
Bithumb 스캐너 봇 v6.0 (특정 코인 지정 기능 추가)
- 기능 1: '지정 코인' 입력란에 티커(예: XRP)를 입력하면 해당 코인만 집중 공략
- 기능 2: 입력란을 비워두면 기존처럼 전 종목 스캔
- 로직: v5.9의 검증된 매수/매도 로직 유지
"""
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import threading
import time
from datetime import datetime
import math
import pybithumb
import pandas as pd
import requests
class BithumbScannerBot:
def __init__(self):
self.root = tk.Tk()
self.root.title("빗썸 스캐너 v6.0 (타겟 지정 가능)")
self.root.geometry("950x950")
self.is_running = False
self.connect_key = tk.StringVar()
self.secret_key = tk.StringVar()
self.password_input = tk.StringVar()
# 설정 변수
self.ma_interval = tk.StringVar(value="1h")
self.ma_short_val = tk.StringVar(value="5")
self.ma_long_val = tk.StringVar(value="90")
self.rsi_interval = tk.StringVar(value="5m")
self.rsi_buy_cond = tk.StringVar(value="40")
self.buy_amount_krw = tk.StringVar(value="5500")
self.max_slots = tk.StringVar(value="3")
self.trailing_gap = tk.StringVar(value="3.0")
# [NEW] 타겟 코인 변수
self.target_ticker = tk.StringVar(value="")
self.current_scan_coin = tk.StringVar(value="대기 중...")
self.total_profit_status = tk.StringVar(value="총 매수: 0원 | 평가: 0원 | 수익률: 0.00%")
self.held_coins = {}
self.bithumb = None
self.log_text = None
self.last_monitor_msg_time = 0
self.setup_gui()
def setup_gui(self):
main_frame = ttk.Frame(self.root, padding="10")
main_frame.pack(fill="both", expand=True)
# 1. 인증
auth_frame = ttk.LabelFrame(main_frame, text="1. API 및 인증", padding="5")
auth_frame.pack(fill="x", pady=5)
input_frame = ttk.Frame(auth_frame)
input_frame.pack(fill="x")
ttk.Label(input_frame, text="라이센스 키:").pack(side="left")
ttk.Entry(input_frame, textvariable=self.password_input, width=15).pack(side="left", padx=5)
ttk.Button(input_frame, text="인증확인", command=self.verify_password).pack(side="left")
api_frame = ttk.Frame(auth_frame)
api_frame.pack(fill="x", pady=5)
ttk.Label(api_frame, text="Connect Key:").pack(anchor="w")
ttk.Entry(api_frame, textvariable=self.connect_key, width=50, show="*").pack(anchor="w")
ttk.Label(api_frame, text="Secret Key:").pack(anchor="w")
ttk.Entry(api_frame, textvariable=self.secret_key, width=50, show="*").pack(anchor="w")
# 2. 설정
rule_frame = ttk.LabelFrame(main_frame, text="2. 전략 설정 (MA 추세 + RSI 타점)", padding="5")
rule_frame.pack(fill="x", pady=5)
grid_frame = ttk.Frame(rule_frame)
grid_frame.pack(fill="x")
valid_intervals = ['1m', '3m', '5m', '10m', '30m', '1h', '6h', '12h', '24h']
# MA 설정
ttk.Label(grid_frame, text="[MA 설정]", foreground="blue").grid(row=0, column=0, sticky="w", padx=5)
ttk.Label(grid_frame, text="기준봉:").grid(row=0, column=1, sticky="w")
self.ma_combo = ttk.Combobox(grid_frame, textvariable=self.ma_interval, values=valid_intervals, width=5)
self.ma_combo.grid(row=0, column=2, sticky="w")
ttk.Label(grid_frame, text="단기이평:").grid(row=0, column=3, sticky="w", padx=5)
ttk.Entry(grid_frame, textvariable=self.ma_short_val, width=4).grid(row=0, column=4, sticky="w")
ttk.Label(grid_frame, text="장기이평:").grid(row=0, column=5, sticky="w", padx=5)
ttk.Entry(grid_frame, textvariable=self.ma_long_val, width=4).grid(row=0, column=6, sticky="w")
# RSI 설정
ttk.Label(grid_frame, text="[RSI 설정]", foreground="red").grid(row=1, column=0, sticky="w", padx=5, pady=5)
ttk.Label(grid_frame, text="기준봉:").grid(row=1, column=1, sticky="w")
self.rsi_combo = ttk.Combobox(grid_frame, textvariable=self.rsi_interval, values=valid_intervals, width=5)
self.rsi_combo.grid(row=1, column=2, sticky="w")
ttk.Label(grid_frame, text="매수값:").grid(row=1, column=3, sticky="w", padx=5)
ttk.Entry(grid_frame, textvariable=self.rsi_buy_cond, width=4).grid(row=1, column=4, sticky="w")
ttk.Label(grid_frame, text="이하").grid(row=1, column=5, sticky="w")
# [NEW] 타겟 설정 및 자금
ttk.Label(grid_frame, text="[타겟/자금]", foreground="green").grid(row=2, column=0, sticky="w", padx=5, pady=5)
# 지정 코인 입력란
ttk.Label(grid_frame, text="지정 코인:").grid(row=2, column=1, sticky="w")
ttk.Entry(grid_frame, textvariable=self.target_ticker, width=6).grid(row=2, column=2, sticky="w")
ttk.Label(grid_frame, text="(비우면 전체)").grid(row=2, column=3, sticky="w")
ttk.Label(grid_frame, text="매수금액:").grid(row=3, column=1, sticky="w")
ttk.Entry(grid_frame, textvariable=self.buy_amount_krw, width=8).grid(row=3, column=2, sticky="w")
ttk.Label(grid_frame, text="최대 보유:").grid(row=3, column=3, sticky="w", padx=5)
ttk.Entry(grid_frame, textvariable=self.max_slots, width=4).grid(row=3, column=4, sticky="w")
ttk.Label(grid_frame, text="트레일링%:").grid(row=3, column=5, sticky="w", padx=5)
ttk.Entry(grid_frame, textvariable=self.trailing_gap, width=4).grid(row=3, column=6, sticky="w")
# 3. 현황
status_frame = ttk.LabelFrame(main_frame, text="3. 포트폴리오 현황", padding="10")
status_frame.pack(fill="x", pady=10)
self.scan_label = ttk.Label(status_frame, textvariable=self.current_scan_coin,
font=("Arial", 11), foreground="blue", anchor="center")
self.scan_label.pack(fill="x", pady=(0, 5))
self.total_profit_label = ttk.Label(status_frame, textvariable=self.total_profit_status,
font=("Arial", 14, "bold"), foreground="darkgreen", anchor="center",
background="#f0f0f0")
self.total_profit_label.pack(fill="x", ipady=8)
# 4. 버튼
btn_frame = ttk.Frame(main_frame)
btn_frame.pack(fill="x", pady=5)
self.start_btn = ttk.Button(btn_frame, text="🚀 스캔 시작", command=self.start_scan, state="disabled")
self.start_btn.pack(side="left", expand=True, fill="x", padx=2)
self.stop_btn = ttk.Button(btn_frame, text="🛑 정지", command=self.stop_scan, state="disabled")
self.stop_btn.pack(side="left", expand=True, fill="x", padx=2)
# 5. 로그
log_frame = ttk.LabelFrame(main_frame, text="4. 상세 로그", padding="5")
log_frame.pack(fill="both", expand=True)
self.log_text = scrolledtext.ScrolledText(log_frame, height=15, font=("Consolas", 9))
self.log_text.pack(fill="both", expand=True)
# --- 유틸리티 ---
def add_log(self, msg):
self.root.after(0, self._insert_log, msg)
def _insert_log(self, msg):
ts = datetime.now().strftime("%H:%M:%S")
self.log_text.insert(tk.END, f"[{ts}] {msg}\n")
self.log_text.see(tk.END)
if self.log_text.get("1.0", tk.END).count('\n') > 2000:
self.log_text.delete("1.0", "100.0")
def verify_password(self):
if self.password_input.get():
messagebox.showinfo("성공", "인증되었습니다.")
self.start_btn.config(state="normal")
else:
messagebox.showerror("오류", "키 입력 필요")
# --- 데이터 조회 ---
def get_ohlcv_data(self, ticker: str, interval: str) -> pd.DataFrame or None:
symbol = f"{ticker}_KRW"
url = f"https://api.bithumb.com/public/candlestick/{symbol}/{interval}"
try:
headers = {"accept": "application/json"}
response = requests.get(url, headers=headers, timeout=3)
data = response.json()
if data.get('status') != '0000': return None
df = pd.DataFrame(data.get('data', []), columns=['time', 'open', 'close', 'high', 'low', 'volume'])
df['time'] = pd.to_datetime(df['time'], unit='ms')
df = df.set_index('time')
return df[['open', 'high', 'low', 'close']].astype(float)
except: return None
# --- 봇 제어 ---
def start_scan(self):
if not self.connect_key.get(): messagebox.showerror("오류", "API 키 필요"); return
try:
self.bithumb = pybithumb.Bithumb(self.connect_key.get(), self.secret_key.get())
except: messagebox.showerror("오류", "API 객체 생성 실패"); return
self.is_running = True
self.start_btn.config(state="disabled")
self.stop_btn.config(state="normal")
self.ma_combo.config(state="disabled")
self.rsi_combo.config(state="disabled")
threading.Thread(target=self.run_scanning_loop, daemon=True).start()
def stop_scan(self):
self.is_running = False
self.start_btn.config(state="normal")
self.stop_btn.config(state="disabled")
self.ma_combo.config(state="normal")
self.rsi_combo.config(state="normal")
self.current_scan_coin.set("🛑 정지됨")
self.add_log("스캔 정지 요청됨.")
def run_scanning_loop(self):
ma_int = self.ma_interval.get()
rsi_int = self.rsi_interval.get()
# [NEW] 타겟 설정 확인
target_coin = self.target_ticker.get().strip().upper()
if target_coin:
self.add_log(f"=== 🎯 지정 코인 감시 시작: {target_coin} (MA:{ma_int} / RSI:{rsi_int}) ===")
else:
self.add_log(f"=== 🔍 전체 스캔 시작 (MA:{ma_int} / RSI:{rsi_int}) ===")
while self.is_running:
try:
self.manage_held_coins()
max_slots = int(self.max_slots.get())
held_list = list(self.held_coins.keys())
# 슬롯 체크
if len(self.held_coins) >= max_slots:
status_text = f"🔒 슬롯 가득 참 (보유중: {', '.join(held_list)})"
self.current_scan_coin.set(status_text)
if time.time() - self.last_monitor_msg_time > 30:
self.add_log(f"👀 슬롯 가득 참. 보유 종목 집중 감시 중... {held_list}")
self.last_monitor_msg_time = time.time()
time.sleep(1)
continue
# [NEW] 타겟이 있으면 그것만, 없으면 전체
if target_coin:
all_tickers = [target_coin]
else:
all_tickers = pybithumb.get_tickers()
total = len(all_tickers)
for idx, ticker in enumerate(all_tickers):
if not self.is_running: break
if ticker in self.held_coins: continue
if target_coin:
self.current_scan_coin.set(f"🎯 타겟 감시 중: {ticker}")
else:
self.current_scan_coin.set(f"🔍 확인 중 ({idx+1}/{total}): {ticker}")
if len(self.held_coins) >= max_slots: break
# API 딜레이 (타겟 지정시는 조금 더 자주 봐도 됨)
delay = 0.5 if target_coin else 0.15
time.sleep(delay)
self.process_ticker(ticker, ma_int, rsi_int)
if self.is_running and not target_coin:
self.add_log("💤 전체 스캔 완료. 5초 대기...")
time.sleep(5)
except Exception as e:
self.add_log(f"메인 루프 에러: {e}")
time.sleep(5)
def process_ticker(self, ticker, ma_int, rsi_int):
try:
ma_short_p = int(self.ma_short_val.get())
ma_long_p = int(self.ma_long_val.get())
rsi_threshold = float(self.rsi_buy_cond.get())
df_ma = self.get_ohlcv_data(ticker, ma_int)
if df_ma is None or len(df_ma) < ma_long_p + 2: return
if ma_int == rsi_int:
df_rsi = df_ma
else:
df_rsi = self.get_ohlcv_data(ticker, rsi_int)
if df_rsi is None: return
if len(df_rsi) < 16: return
ma_short = df_ma['close'].rolling(window=ma_short_p).mean().iloc[-1]
ma_long = df_ma['close'].rolling(window=ma_long_p).mean().iloc[-1]
delta = df_rsi['close'].diff(1)
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
rsi_val = 100 - (100 / (1 + rs))
cur_price = df_rsi['close'].iloc[-1]
rsi_now = rsi_val.iloc[-1]
if pd.isna(ma_short) or pd.isna(ma_long) or pd.isna(rsi_now): return
cond_ma = ma_short > ma_long
cond_rsi = rsi_now <= rsi_threshold
mark_ma = "✅" if cond_ma else "❌"
mark_rsi = "✅" if cond_rsi else "❌"
status_msg = f"{ticker} | {ma_int}MA({ma_short_p}/{ma_long_p}):{mark_ma} | {rsi_int}RSI:{rsi_now:.1f}{mark_rsi}"
if cond_ma and cond_rsi:
self.add_log(f"⚡ [BUY] {status_msg}")
self.execute_buy(ticker)
elif cond_ma or cond_rsi:
self.add_log(f"👀 [관심] {status_msg}")
except Exception:
pass
# --- [매수 로직] Test 코드와 동일 ---
def execute_buy(self, ticker):
try:
balance = self.bithumb.get_balance(ticker)
if balance is None: return
coin_before = float(balance[0])
orderbook = pybithumb.get_orderbook(ticker)
if not orderbook: return
ask_price = float(orderbook['asks'][0]['price'])
krw_limit = int(self.buy_amount_krw.get())
safe_krw = krw_limit * 0.9975
buy_qty = safe_krw / ask_price
buy_qty = math.floor(buy_qty * 10000) / 10000
if buy_qty <= 0:
self.add_log(f"⚠️ {ticker} 계산된 수량 0")
return
self.add_log(f"🛒 {ticker} 매수 시도: {buy_qty}개 (@{ask_price})")
self.bithumb.buy_market_order(ticker, buy_qty)
time.sleep(3)
balance_new = self.bithumb.get_balance(ticker)
coin_after = float(balance_new[0])
diff = coin_after - coin_before
if diff > 0:
self.held_coins[ticker] = {
'buy_price': ask_price,
'qty': diff,
'highest_price': ask_price
}
self.add_log(f"✅ {ticker} 매수 체결 완료! (+{diff}개)")
else:
self.add_log(f"❌ {ticker} 미체결 (잔고변화 없음)")
except Exception as e:
self.add_log(f"❌ 매수 에러: {e}")
# --- 트레일링 스탑 ---
def manage_held_coins(self):
if not self.held_coins:
self.total_profit_status.set("총 매수: 0원 | 평가: 0원 | 수익률: 0.00%")
return
trailing_gap_pct = float(self.trailing_gap.get())
total_buy_val = 0
total_curr_val = 0
for ticker in list(self.held_coins.keys()):
try:
curr = pybithumb.get_current_price(ticker)
if curr is None: continue
buy_price = self.held_coins[ticker]['buy_price']
highest = self.held_coins[ticker]['highest_price']
qty = self.held_coins[ticker]['qty']
total_buy_val += (buy_price * qty)
total_curr_val += (curr * qty)
if curr > highest:
self.held_coins[ticker]['highest_price'] = curr
highest = curr
profit_rate = (curr - buy_price) / buy_price * 100
drop_from_high = (curr - highest) / highest * 100
if drop_from_high <= -trailing_gap_pct:
self.execute_sell(ticker, qty, f"트레일링({drop_from_high:.2f}%)", profit_rate)
elif profit_rate <= -3.0:
self.execute_sell(ticker, qty, f"손절({profit_rate:.2f}%)", profit_rate)
except: pass
if total_buy_val > 0:
total_rate = (total_curr_val - total_buy_val) / total_buy_val * 100
status_str = f"총 매수: {total_buy_val:,.0f}원 | 평가: {total_curr_val:,.0f}원 | 수익률: {total_rate:+.2f}%"
self.total_profit_status.set(status_str)
def execute_sell(self, ticker, qty, reason, final_profit):
try:
self.add_log(f"👋 {ticker} 매도 실행 [{reason}] (수익: {final_profit:.2f}%)")
self.bithumb.sell_market_order(ticker, qty)
time.sleep(1)
if ticker in self.held_coins:
del self.held_coins[ticker]
self.add_log(f"✅ {ticker} 매도 완료.")
except Exception as e:
self.add_log(f"❌ 매도 에러: {e}")
if __name__ == "__main__":
BithumbScannerBot().root.mainloop()
코인 시장에서는 감정을 배제한 기계적인 매매가 승률을 높이는 지름길입니다. 이번 빗썸 수수료 페이백 기간을 활용해 무료로 자동매매 시스템을 경험해 보시고, 가입 지원금 7만원도 꼭 시드로 알차게 활용하시길 바랍니다.
내용이 도움이 되셨다면 공감과 댓글 부탁드리며, 프로그램 사용 중 막히는 부분이 있다면 언제든 댓글 남겨주세요!
| [26년 5월 최신] 빗썸 7만원 받는법&출금제한 푸는법 (디시 갤러리 후기 팩트체크) (0) | 2026.05.05 |
|---|---|
| [26년 5월] 업비트 vs 빗썸 vs 코인원 국내 거래소 가입 혜택 비교: 현금 9만원 받고 시작하는 법 (4) | 2026.05.01 |
| 🎯 [26년 5월 최신] 빗썸 7만원 혜택 이벤트! 출금까지 초간단 정리 | 1초 초대코드 복사 (5) | 2025.12.26 |
| 대체 투자 전략: 새로운 수익원 탐색! 전통 자산을 넘어서는 스마트한 투자법 (2) | 2025.04.24 |
| 고수익 프리랜서 서비스: 틈새 시장 공략! 작게 시작해서 크게 버는 전략 (1) | 2025.04.24 |