오늘은 가상 자산 시뮬레이션을 위한 매수/매도 함수를 만들어보려고 합니다.
가상 자산을 이용한 시뮬레이션인 만큼 저번에 만들었던 virtual_portfolio_manager.py에 거래 함수를 추가 할 예정입니다.
1. 매수/매도 함수
1). import 선언
import time
import trade_history # 거래 내역 저장을 위해
2). 매수/매도 함수 선언
- 다음과 같이 매수/매도 로직을 구현 할 함수를 선언하고 내부를 채워보도록 하겠습니다.
# --- 가상 거래 기록 및 portfolio 상태 업데이트 함수 (실제 주문 X) ---
"""
:portfolio_data: 현재 포트폴리오 상태 딕셔너리
:trade_type: "buy" 또는 "sell"
:symbol: 거래할 코인 심볼 (예: "BTC")
:quantity: 거래할 수량
:price_per_unit: 거래 당시 코인 개당 가격
:return: 성공 시 업데이트된 포트폴리오 딕셔너리, 실패 시 None
"""
def record_vportfolio_trade(portfolio_data, trade_type, symbol, quantity, price_per_unit):
symbol_upper = symbol.upper() # 코인 심볼은 대문자로 통일
if trade_type.lower() == "buy":
print("BUY")
# --- 매수 로직 ---
elif trade_type.lower() == "sell":
print("SELL")
# --- 매도 로직 ---
else:
print(f"⚠️ 잘못된 거래 유형입니다: {trade_type}")
return None
return portfolio_data
3). 매수 로직
- if trade_type.lower() == "buy":인 경우 아래 로직으로 변경합니다.
if trade_type.lower() == "buy":
# --- 매수 로직 ---
total_cost = quantity * price_per_unit
# 1. 현금 잔고 확인
if portfolio_data["cash"] < total_cost:
print(f"⚠️ 매수 실패: 현금 부족 (필요: {total_cost:,.2f} KRW, 보유: {portfolio_data['cash']:,.2f} KRW)")
return None
# 2. 포트폴리오에서 해당 코인 찾기
owned_coin = None
for coin in portfolio_data["coins_owned"]:
if coin["symbol"] == symbol_upper:
owned_coin = coin
break
# 3. 보유 코인 정보 및 현금 업데이트
portfolio_data["cash"] -= total_cost
if owned_coin: # 이미 보유한 코인 (추가 매수)
print(f"-> 이미 보유한 코인({symbol_upper}) 추가 매수 진행...")
# 평균 매수 단가(평단가) 재계산
old_total_value = owned_coin["avg_buy_price"] * owned_coin["quantity"]
new_total_value = old_total_value + total_cost
new_total_quantity = owned_coin["quantity"] + quantity
owned_coin["quantity"] = new_total_quantity
owned_coin["avg_buy_price"] = new_total_value / new_total_quantity
else: # 처음 매수하는 코인
print(f"-> 신규 코인({symbol_upper}) 매수 진행...")
new_coin_data = {
"symbol": symbol_upper,
"quantity": quantity,
"avg_buy_price": price_per_unit
}
portfolio_data["coins_owned"].append(new_coin_data)
trade_status_message = f"✅ 매수 성공: {symbol_upper} {quantity}개 @ {price_per_unit:,.2f} KRW"
4). 매수 로직 테스트
- 아래 로직을 추가하여 매수가 정상적으로 진행되는지 확인합니다.
# 이 파일을 직접 실행했을 때 간단한 테스트
if __name__ == "__main__":
# 1. 포트폴리오 상태 불러오기 (파일 없으면 초기화)
my_vportfolio = load_vportfolio()
print("\n--- 거래 시작 전 포트폴리오 ---")
print(json.dumps(my_vportfolio, indent=4, ensure_ascii=False))
# 2. 가상 매수 거래 테스트
print("\n--- 가상 매수 테스트 (신규 매수) ---")
# 예: BTC 0.01개 매수
updated_portfolio = record_vportfolio_trade(
my_vportfolio, "buy", "BTC", 0.01, 70000000
)
# 거래가 성공했을 때만 포트폴리오 업데이트 및 저장
if updated_portfolio:
my_vportfolio = updated_portfolio
save_vportfolio(my_vportfolio)
print("\n--- 가상 매수 테스트 (추가 매수) ---")
# 예: BTC 0.02개 추가 매수 (평단가 바뀌는지 확인!)
updated_portfolio = record_vportfolio_trade(
my_vportfolio, "buy", "btc", 0.02, 75000000 # 소문자로 입력해도 대문자로 처리되는지 확인
)
if updated_portfolio:
my_vportfolio = updated_portfolio
save_vportfolio(my_vportfolio)
print("\n--- 최종 포트폴리오 상태 ---")
print(json.dumps(my_vportfolio, indent=4, ensure_ascii=False))
아래와 같이 출력되면 정상입니다.
평단가 등을 테스트하기 위해 가상 자산 또는 매수 가격을 변경해서 테스트 해보셔도 좋습니다.

6). 매도 로직
elif trade_type.lower() == "sell":
# --- 매도 로직 ---
# 1. 포트폴리오에서 해당 코인 찾기
owned_coin = None
for coin in portfolio_data["coins_owned"]:
if coin["symbol"] == symbol_upper:
owned_coin = coin
break
# 2. 보유 여부 및 수량 확인
if owned_coin is None:
print(f"⚠️ 매도 실패: {symbol_upper} 코인을 보유하고 있지 않습니다.")
return None
if owned_coin["quantity"] < quantity:
print(f"⚠️ 매도 실패: {symbol_upper} 보유 수량 부족 (매도 요청: {quantity}, 보유량: {owned_coin['quantity']})")
return None
# 3. 보유 코인 정보 및 현금 업데이트
total_gain = quantity * price_per_unit
portfolio_data["cash"] += total_gain
owned_coin["quantity"] -= quantity
trade_status_message = f"✅ 매도 성공: {symbol_upper} {quantity}개 @ {price_per_unit:,.2f} KRW"
# 4. 만약 매도 후 수량이 0.0 이 되면 보유 목록에서 완전히 제거
if owned_coin["quantity"] <= 0: # 0 또는 아주 작은 음수가 될 수 있으니 <= 0 으로 체크
portfolio_data["coins_owned"].remove(owned_coin)
print(f"-> {symbol_upper} 전량 매도 완료.")
else:
print(f"-> {symbol_upper} 부분 매도 완료. (남은 수량: {owned_coin['quantity']})")
7). 매도 로직 테스트
my_vportfolio = load_vportfolio()
print("\n--- 거래 시작 전 포트폴리오 ---")
print(json.dumps(my_vportfolio, indent=4, ensure_ascii=False))
# 1. 가상 매도 테스트 (부분 매도)
print("\n--- 가상 매도 테스트 (부분 매도) ---")
updated_portfolio = record_vportfolio_trade(
my_vportfolio, "sell", "BTC", 0.01, 80000000 # 8천만원에 매도 시도
)
if updated_portfolio:
my_vportfolio = updated_portfolio
save_vportfolio(my_vportfolio)
# 2. 가상 매도 실패 테스트 (수량 부족)
print("\n--- 가상 매도 실패 테스트 (수량 부족) ---")
# 예: 남은 BTC보다 많은 수량 매도 시도
updated_portfolio = record_vportfolio_trade(
my_vportfolio, "sell", "BTC", 0.05, 81000000
)
if updated_portfolio:
my_vportfolio = updated_portfolio
save_vportfolio(my_vportfolio)
# 3. 가상 매도 테스트 (전량 매도)
print("\n--- 가상 매도 테스트 (전량 매도) ---")
current_btc_quantity = 0
for coin in my_vportfolio["coins_owned"]:
if coin["symbol"] == "BTC":
current_btc_quantity = coin["quantity"]
break
if current_btc_quantity > 0:
updated_portfolio = record_vportfolio_trade(
my_vportfolio, "sell", "BTC", current_btc_quantity, 82000000
)
if updated_portfolio:
my_vportfolio = updated_portfolio
save_vportfolio(my_vportfolio)
print("\n--- 최종 포트폴리오 상태 ---")
print(json.dumps(my_vportfolio, indent=4, ensure_ascii=False))
아래와 같이 출력되면 정상입니다.

다음 단계
- 매크로의 두뇌 함수 제작!!
끝!!
'프로젝트 > 코인 투자 매크로' 카테고리의 다른 글
| 2025-06-09 [9] 종목 선택 (0) | 2025.06.10 |
|---|---|
| 2025-06-08 [8] [v1.0.0 완료] 캔들스틱, 단순 이동 평균(SMA), 골든/데드 크로스 (3) | 2025.06.08 |
| 2025-06-06 [6] 가상 자산 관리 및 거래 내역 (0) | 2025.06.06 |
| 2025-06-04 [5] 투자 방법 설계 (2) | 2025.06.04 |
| 2025-06-01 [4] bithumb_api_client.py (2) | 2025.06.01 |