반응형
import os
import pyupbit
import time
import pandas as pd
import asyncio
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext, Application
# Load API keys from .env file
load_dotenv(dotenv_path='config.env')
UPBIT_ACCESS_KEY = os.getenv('UPBIT_ACCESS_KEY')
UPBIT_SECRET_KEY = os.getenv('UPBIT_SECRET_KEY')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
# Initialize Upbit and Telegram
upbit = pyupbit.Upbit(UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY)
application = Application.builder().token(TELEGRAM_TOKEN).build()
# Global variables
selected_coin = None
is_trading = False
trade_task = None
def check_volume_increase(df, minutes):
"""거래량 연속 증가 확인"""
return all(df['volume'].diff().iloc[-minutes:] > 0)
def check_price_increase(df, minutes):
"""가격 연속 증가 확인"""
return all(df['close'].diff().iloc[-minutes:] > 0)
def check_volume_increase_percentage(df, minutes, threshold):
"""거래량 증가율 확인"""
volume_increase = (df['volume'].iloc[-1] / df['volume'].iloc[-minutes] - 1) * 100
return volume_increase > threshold
# Command handlers
async def start(update: Update, context: CallbackContext) -> None:
await update.message.reply_text('코인 자동 거래 봇이 시작되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="코인 자동 거래 봇이 실행되었습니다!")
async def select_coin(update: Update, context: CallbackContext) -> None:
global selected_coin
if not context.args:
await update.message.reply_text('코인을 선택하려면 /select_coin [코인심볼] 형식으로 입력하세요.')
await context.bot.send_message(chat_id=update.effective_chat.id, text='코인을 선택하려면 /select_coin [코인심볼] 형식으로 입력하세요.')
else:
selected_coin = context.args[0]
await update.message.reply_text(f'선택된 코인: {selected_coin}')
await context.bot.send_message(chat_id=update.effective_chat.id, text=f'선택된 코인: {selected_coin}')
async def start_trading(update: Update, context: CallbackContext) -> None:
global is_trading, trade_task
is_trading = True
await update.message.reply_text('자동 거래가 시작되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="자동 거래가 시작되었습니다!")
trade_task = asyncio.create_task(trade(update, context))
async def stop_trading(update: Update, context: CallbackContext) -> None:
global is_trading, trade_task
is_trading = False
if trade_task:
trade_task.cancel()
await update.message.reply_text('자동 거래가 종료되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="자동 거래가 종료되었습니다!")
async def check_balance(update: Update, context: CallbackContext) -> None:
balance = upbit.get_balance()
await update.message.reply_text(f'잔고: {balance} 원')
await context.bot.send_message(chat_id=update.effective_chat.id, text=f'잔고: {balance} 원')
import logging
# 로깅 설정
logging.basicConfig(filename='trading_bot.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
import os
import pyupbit
import time
import pandas as pd
import asyncio
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext, Application
# Load API keys from .env file
load_dotenv(dotenv_path='config.env')
UPBIT_ACCESS_KEY = os.getenv('UPBIT_ACCESS_KEY')
UPBIT_SECRET_KEY = os.getenv('UPBIT_SECRET_KEY')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
# Initialize Upbit and Telegram
upbit = pyupbit.Upbit(UPBIT_ACCESS_KEY, UPBIT_SECRET_KEY)
application = Application.builder().token(TELEGRAM_TOKEN).build()
# Global variables
selected_coin = None
is_trading = False
trade_task = None
def check_volume_increase(df, minutes):
"""거래량 연속 증가 확인"""
return all(df['volume'].diff().iloc[-minutes:] > 0)
def check_price_increase(df, minutes):
"""가격 연속 증가 확인"""
return all(df['close'].diff().iloc[-minutes:] > 0)
def check_volume_increase_percentage(df, minutes, threshold):
"""거래량 증가율 확인"""
volume_increase = (df['volume'].iloc[-1] / df['volume'].iloc[-minutes] - 1) * 100
return volume_increase > threshold
# Command handlers
async def start(update: Update, context: CallbackContext) -> None:
await update.message.reply_text('코인 자동 거래 봇이 시작되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="코인 자동 거래 봇이 실행되었습니다!")
async def select_coin(update: Update, context: CallbackContext) -> None:
global selected_coin
if not context.args:
await update.message.reply_text('코인을 선택하려면 /select_coin [코인심볼] 형식으로 입력하세요.')
await context.bot.send_message(chat_id=update.effective_chat.id, text='코인을 선택하려면 /select_coin [코인심볼] 형식으로 입력하세요.')
else:
selected_coin = context.args[0]
await update.message.reply_text(f'선택된 코인: {selected_coin}')
await context.bot.send_message(chat_id=update.effective_chat.id, text=f'선택된 코인: {selected_coin}')
async def start_trading(update: Update, context: CallbackContext) -> None:
global is_trading, trade_task
is_trading = True
await update.message.reply_text('자동 거래가 시작되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="자동 거래가 시작되었습니다!")
trade_task = asyncio.create_task(trade(update, context))
async def stop_trading(update: Update, context: CallbackContext) -> None:
global is_trading, trade_task
is_trading = False
if trade_task:
trade_task.cancel()
await update.message.reply_text('자동 거래가 종료되었습니다!')
await context.bot.send_message(chat_id=update.effective_chat.id, text="자동 거래가 종료되었습니다!")
async def check_balance(update: Update, context: CallbackContext) -> None:
balance = upbit.get_balance()
await update.message.reply_text(f'잔고: {balance} 원')
await context.bot.send_message(chat_id=update.effective_chat.id, text=f'잔고: {balance} 원')
import logging
# 로깅 설정
logging.basicConfig(filename='trading_bot.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
async def trade(update: Update, context: CallbackContext):
global is_trading
buy_price = None
stop_loss = 0.95
take_profit = 1.10
while is_trading:
try:
df = pyupbit.get_ohlcv(selected_coin, interval="minute5", count=200)
if df is None:
raise ValueError("데이터를 가져오지 못했습니다. 코인 심볼을 확인하세요.")
short_ma = df['close'].rolling(window=5).mean()
long_ma = df['close'].rolling(window=20).mean()
krw_balance = upbit.get_balance("KRW")
if isinstance(krw_balance, dict):
krw_balance = float(krw_balance['balance'])
coin_balance = upbit.get_balance(selected_coin)
if isinstance(coin_balance, dict):
coin_balance = float(coin_balance['balance'])
# 단순 매수 신호 조건
if short_ma[-1] > long_ma[-1] and short_ma[-2] <= long_ma[-2] and coin_balance == 0:
buy_price = upbit.buy_market_order(selected_coin, krw_balance * 0.9995)
logging.info(f"매수 신호 발생 - 매수 주문 실행: {buy_price}")
await context.bot.send_message(chat_id=update.effective_chat.id, text="매수 신호 발생 - 매수 주문 실행")
elif check_price_increase(df, 10) and coin_balance == 0:
buy_price = upbit.buy_market_order(selected_coin, krw_balance * 0.9995)
logging.info(f"거래량 및 가격 증가 - 매수 주문 실행: {buy_price}")
if coin_balance > 0:
current_price = df['close'][-1]
# 손절매 및 이익 실현 비율 동적 조정
if current_price <= buy_price * stop_loss:
upbit.sell_market_order(selected_coin, coin_balance)
logging.info(f"손절매 - 매도 주문 실행: {current_price}")
await context.bot.send_message(chat_id=update.effective_chat.id, text="손절매 - 매도 주문 실행")
buy_price = None
elif current_price >= buy_price * take_profit:
upbit.sell_market_order(selected_coin, coin_balance)
logging.info(f"이익 실현 - 매도 주문 실행: {current_price}")
await context.bot.send_message(chat_id=update.effective_chat.id, text="이익 실현 - 매도 주문 실행")
buy_price = None
# asyncio.sleep을 사용하여 주기적으로 is_trading 상태 확인
await asyncio.sleep(300) # 5분 동안 대기
except asyncio.CancelledError:
logging.info("자동 거래가 취소되었습니다.")
await context.bot.send_message(chat_id=update.effective_chat.id, text="자동 거래가 취소되었습니다.")
break
except Exception as e:
logging.error(f"오류 발생: {e}")
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"오류 발생: {e}")
await asyncio.sleep(60)
# Add handlers to dispatcher
application.add_handler(CommandHandler('start', start))
application.add_handler(CommandHandler('select_coin', select_coin))
application.add_handler(CommandHandler('start_trading', start_trading))
application.add_handler(CommandHandler('stop_trading', stop_trading))
application.add_handler(CommandHandler('check_balance', check_balance))
# Start the bot
application.run_polling()
# Add handlers to dispatcher
application.add_handler(CommandHandler('start', start))
application.add_handler(CommandHandler('select_coin', select_coin))
application.add_handler(CommandHandler('start_trading', start_trading))
application.add_handler(CommandHandler('stop_trading', stop_trading))
application.add_handler(CommandHandler('check_balance', check_balance))
# Start the bot
application.run_polling()
텔레그램과 연동했습니다.
이 코드는 Upbit 거래소에서 자동으로 코인을 거래하는 Telegram 봇을 구현한 것입니다. 아래는 코드 분석과 사용법입니다.
코드 분석
1. 라이브러리 임포트
os
: 환경 변수 접근을 위한 모듈.pyupbit
: Upbit API를 사용하기 위한 라이브러리.time
,pandas
,asyncio
: 시간, 데이터 처리, 비동기 작업을 위한 모듈.dotenv
:.env
파일에서 환경 변수를 로드하기 위한 모듈.telegram
: Telegram 봇 API를 사용하기 위한 모듈.logging
: 로그 기록을 위한 모듈.
2. 환경 변수 로드
load_dotenv
: API 키와 토큰을 포함한 환경 변수를 로드합니다.UPBIT_ACCESS_KEY
,UPBIT_SECRET_KEY
,TELEGRAM_TOKEN
: Upbit API와 Telegram Bot API에 필요한 키.
3. Upbit 및 Telegram 초기화
upbit
: Upbit API 객체 생성.application
: Telegram 봇 객체 생성.
4. 글로벌 변수
selected_coin
: 선택된 코인 심볼.is_trading
: 거래 상태를 나타내는 플래그.trade_task
: 비동기 거래 작업을 위한 변수.
5. 거래 조건 확인 함수
check_volume_increase
: 거래량이 연속적으로 증가하는지 확인.check_price_increase
: 가격이 연속적으로 증가하는지 확인.check_volume_increase_percentage
: 거래량 증가율을 확인.
6. 명령어 핸들러
start
: 봇 시작 메시지 전송.select_coin
: 코인 선택 및 확인.start_trading
: 자동 거래 시작.stop_trading
: 자동 거래 중지.check_balance
: 현재 잔고 확인.
7. 거래 로직
trade
: 선택된 코인에 대해 매수 및 매도 로직을 수행.- 이동 평균을 사용하여 매수 신호를 감지.
- 손절매 및 이익 실현 조건을 설정.
8. 로깅
- 모든 거래 및 오류 정보를
trading_bot.log
파일에 기록.
9. 핸들러 추가 및 봇 시작
- Telegram 봇에 명령어 핸들러를 추가하고, 폴링 방식으로 봇을 실행.
사용법
- 환경 설정
.env
파일을 생성하고 다음과 같이 API 키를 추가합니다.UPBIT_ACCESS_KEY=your_upbit_access_key UPBIT_SECRET_KEY=your_upbit_secret_key TELEGRAM_TOKEN=your_telegram_bot_token
- 봇 실행
- Python 환경에서 이 코드를 실행합니다.
- Telegram 명령어 사용
/start
: 봇을 시작합니다./select_coin [코인심볼]
: 거래할 코인을 선택합니다. 예:/select_coin BTC
./start_trading
: 자동 거래를 시작합니다./stop_trading
: 자동 거래를 중지합니다./check_balance
: 현재 잔고를 확인합니다.
- 로그 확인
- 거래 및 오류 정보는
trading_bot.log
파일에서 확인할 수 있습니다.
- 거래 및 오류 정보는
***** 이 프로그램은 충분한 테스트를 거치지 않았습니다. 이 프로그램으로 인한 손실에 대해서는 각자 알아서 하세요. 테스트용 개발용으로 올립니다 **********
반응형
'IT와 보안 그 어디 쯤 > 웹프로그래밍_끄적이기' 카테고리의 다른 글
REST API (0) | 2023.06.02 |
---|---|
국토교통부 실거래가 정보오픈API 활용 가이드 - 아파트 전월세 신고정보 조회 - (0) | 2023.05.23 |
국토교통부 실거래가 정보 오픈API 활용 가이드연립다세대 전월세 신고정보 조회 - (0) | 2023.05.23 |
국토교통부 실거래가 정보 오픈API 활용 가이드- 아파트 매매 신고 상세자료 조회 - (0) | 2023.05.23 |
국토교통부 실거래가 정보 오픈API 활용 가이드- 연립다세대 매매 신고정보 조회 - (0) | 2023.05.23 |