-
파이썬으로 만들어 본 주식 계산기Python/파이썬과 주식 2025. 3. 28. 17:10반응형
1. 매수 매도 가격 입력 -> 예상 수익률
2. 매수 가격, 목표 수익률 입력 -> 매도 가격매수 매도 수수료 및 증권 거래세를 포함.
다만 실제 거래에서는 10원 단위 절사 등을 하는데, 완벽하게 같지는 않습니다.
참고만 하시구요.혹시 오류가 있다면 리플 남겨주세요.
pip install ttkbootstrap
import os import tkinter as tk from tkinter import font, ttk from ttkbootstrap import Style BUY_FEE = 0.015 SELL_FEE = 0.015 TAX = 0.15 def on_radiobutton_click(*args): if selected_option_var.get() == 'profit_rate': buy_price_label.configure(font=BOLD_FONT) sell_price_label.configure(font=BOLD_FONT) quantity_label.configure(font=BOLD_FONT) profit_rate_label.configure(font=DEFAULT_FONT) elif selected_option_var.get() == 'sell_price': buy_price_label.configure(font=BOLD_FONT) sell_price_label.configure(font=DEFAULT_FONT) quantity_label.configure(font=BOLD_FONT) profit_rate_label.configure(font=BOLD_FONT) def on_key_release(entry): format_number(entry) if selected_option_var.get() == 'profit_rate': calculate_profit() elif selected_option_var.get() == 'sell_price': calculate_sell_price() def format_number(entry): value = entry.get().replace(',', '') if value.isdigit(): formatted_value = f'{int(value):,}' entry.delete(0, tk.END) entry.insert(0, formatted_value) def calculate_sell_price(*args): try: buy_price = float(buy_price_entry.get().replace(',', '')) quantity = int(quantity_entry.get().replace(',', '')) profit_rate = float(profit_rate_entry.get()) / 100 buy_fee_rate = float(buy_fee_entry.get()) / 100 sell_fee_rate = float(sell_fee_entry.get()) / 100 tax_rate = float(tax_entry.get()) / 100 total_buy = buy_price * quantity * (1 + buy_fee_rate) total_buy_fee = buy_price * quantity * buy_fee_rate sell_price = buy_price * (1 + buy_fee_rate) * (1 + profit_rate) / (1 - sell_fee_rate - tax_rate) total_sell = sell_price * quantity * (1 - sell_fee_rate - tax_rate) total_sell_fee_tax = sell_price * quantity * (sell_fee_rate + tax_rate) profit = total_sell - total_buy sell_price_entry.delete(0, tk.END) sell_price_entry.insert(0, f'{sell_price:,.2f}') fee_entry.delete(0, tk.END) fee_entry.insert(0, f'{total_buy_fee + total_sell_fee_tax:,.2f}') profit_entry.delete(0, tk.END) profit_entry.insert(0, f'{profit:,.2f}') except Exception as e: print(e) def calculate_profit(*args): try: buy_price = float(buy_price_entry.get().replace(',', '')) sell_price = float(sell_price_entry.get().replace(',', '')) quantity = int(quantity_entry.get().replace(',', '')) buy_fee_rate = float(buy_fee_entry.get()) / 100 sell_fee_rate = float(sell_fee_entry.get()) / 100 tax_rate = float(tax_entry.get()) / 100 total_buy = buy_price * quantity * (1 + buy_fee_rate) total_buy_fee = buy_price * quantity * buy_fee_rate total_sell = sell_price * quantity * (1 - sell_fee_rate - tax_rate) total_sell_fee_tax = sell_price * quantity * (sell_fee_rate + tax_rate) profit = total_sell - total_buy profit_rate = (profit / total_buy) * 100 fee_entry.delete(0, tk.END) fee_entry.insert(0, f'{total_buy_fee + total_sell_fee_tax:,.2f}') profit_entry.delete(0, tk.END) profit_entry.insert(0, f'{profit:,.2f}') profit_rate_entry.delete(0, tk.END) profit_rate_entry.insert(0, f'{profit_rate:,.2f}') except Exception as e: print(e) def toggle_always_on_top(): if always_on_top_var.get(): root.wm_attributes('-topmost', 1) # 항상 위 else: root.wm_attributes('-topmost', 0) # 기본 상태 root = tk.Tk() root.title('주식 계산기') root.wm_attributes('-topmost', 1) if os.path.isfile('icon.ico'): root.iconbitmap('icon.ico') style = Style(theme='superhero') DEFAULT_FONT = font.nametofont("TkDefaultFont") BOLD_FONT = font.Font(**{**DEFAULT_FONT.actual(), 'weight': 'bold', 'underline': 1}) frame1 = ttk.Frame(root, padding=(10, 10, 10, 0)) frame1.pack() selected_option_var = tk.StringVar(value='profit_rate') selected_option_var.trace_add("write", on_radiobutton_click) profit_rate_radio = ttk.Radiobutton(frame1, text='수익률', variable=selected_option_var, value='profit_rate', style='Toolbutton') profit_rate_radio.grid(row=0, column=1) sell_price_radio = ttk.Radiobutton(frame1, text='매도가격', variable=selected_option_var, value='sell_price', style='Toolbutton') sell_price_radio.grid(row=0, column=2) frame2 = ttk.Frame(root, padding=10) frame2.pack() buy_price_label = ttk.Label(frame2, text='매수가격') buy_price_label.configure(font=BOLD_FONT) buy_price_label.grid(row=0, column=0, sticky='e') buy_price_entry = ttk.Entry(frame2) buy_price_entry.grid(row=0, column=1) buy_price_entry.bind('<KeyRelease>', lambda e: on_key_release(buy_price_entry)) sell_price_label = ttk.Label(frame2, text='매도가격') sell_price_label.configure(font=BOLD_FONT) sell_price_label.grid(row=1, column=0, sticky='e') sell_price_entry = ttk.Entry(frame2) sell_price_entry.grid(row=1, column=1) sell_price_entry.bind('<KeyRelease>', lambda e: on_key_release(sell_price_entry)) quantity_label = ttk.Label(frame2, text='수량') quantity_label.configure(font=BOLD_FONT) quantity_label.grid(row=2, column=0, sticky='e') quantity_entry = ttk.Entry(frame2) quantity_entry.grid(row=2, column=1) quantity_entry.bind('<KeyRelease>', lambda e: on_key_release(quantity_entry)) profit_rate_label = ttk.Label(frame2, text='수익률(%)') profit_rate_label.configure(font=DEFAULT_FONT) profit_rate_label.grid(row=3, column=0, sticky='e') profit_rate_entry = ttk.Entry(frame2) profit_rate_entry.grid(row=3, column=1) profit_rate_entry.bind('<KeyRelease>', lambda e: on_key_release(profit_rate_entry)) profit_label = ttk.Label(frame2, text='수익(원)') profit_label.grid(row=4, column=0, sticky='e') profit_entry = ttk.Entry(frame2) profit_entry.grid(row=4, column=1) fee_label = ttk.Label(frame2, text='수수료 및 세금(원)') fee_label.grid(row=5, column=0, sticky='e') fee_entry = ttk.Entry(frame2) fee_entry.grid(row=5, column=1) buy_fee_label = ttk.Label(frame2, text='매수 수수료(%)') buy_fee_label.grid(row=6, column=0, sticky='e') buy_fee_entry = ttk.Entry(frame2) buy_fee_entry.grid(row=6, column=1) buy_fee_entry.insert(0, str(BUY_FEE)) buy_fee_entry.bind('<KeyRelease>', calculate_profit) sell_fee_label = ttk.Label(frame2, text='매도 수수료(%)') sell_fee_label.grid(row=7, column=0, sticky='e') sell_fee_entry = ttk.Entry(frame2) sell_fee_entry.grid(row=7, column=1) sell_fee_entry.insert(0, str(SELL_FEE)) sell_fee_entry.bind('<KeyRelease>', calculate_profit) tax_label = ttk.Label(frame2, text='증권거래세(%)') tax_label.grid(row=8, column=0, sticky='e') tax_entry = ttk.Entry(frame2) tax_entry.grid(row=8, column=1) tax_entry.insert(0, str(TAX)) tax_entry.bind('<KeyRelease>', calculate_profit) frame3 = ttk.Frame(root, padding=(10, 0, 10, 10)) frame3.pack() always_on_top_var = tk.BooleanVar(value=True) always_on_top_checkbox = ttk.Checkbutton(frame3, text='항상 위', variable=always_on_top_var, command=toggle_always_on_top) always_on_top_checkbox.grid(row=9, column=0, sticky='w') root.mainloop()
개선할 점..
Configparser나 yaml 등을 이용해
BUY_FEE = 0.015
SELL_FEE = 0.015
TAX = 0.15
이런 변수들을 외부에서 다룰 수 있도록 한다면 좋을 것이다.어렵지 않으니 직접 해보시는 것을 추천한다.
반응형