模拟炒股py

部署运行你感兴趣的模型镜像
import random
import time
import json
import os
from datetime import datetime, timedelta

class Stock:
    """股票类"""
    def __init__(self, code, name, initial_price):
        self.code = code
        self.name = name
        self.price = initial_price
        self.history = [initial_price]
        self.volume = 0
        self.last_price = initial_price  # 添加上一日价格用于计算涨跌幅
        
    def update_price(self):
        """更新股票价格(模拟市场波动)"""
        # 保存上一日价格
        self.last_price = self.price
        
        # 随机价格波动,范围在-5%到+5%之间
        change_rate = random.uniform(-0.05, 0.05)
        self.price = round(self.price * (1 + change_rate), 2)
        self.price = max(0.01, self.price)  # 确保价格不会低于0.01
        self.history.append(self.price)
        
        # 保持历史记录在合理范围内
        if len(self.history) > 100:
            self.history = self.history[-100:]
        
        # 模拟成交量
        self.volume = random.randint(1000, 100000)
    
    def get_change_rate(self):
        """获取涨跌幅"""
        if self.last_price == 0:
            return 0
        return round((self.price - self.last_price) / self.last_price * 100, 2)

class Portfolio:
    """投资组合类"""
    def __init__(self, username, initial_capital=100000):
        self.username = username
        self.cash = initial_capital
        self.positions = {}  # {股票代码: 股数}
        self.total_invested = 0
        self.initial_capital = initial_capital
        self.transaction_history = []  # 添加交易历史
        
    def buy_stock(self, stock_code, shares, stock_price):
        """买入股票"""
        if shares <= 0:
            return False, "股数必须大于0"
            
        cost = shares * stock_price
        if cost > self.cash:
            return False, f"资金不足,需要 {cost:.2f} 元,当前现金 {self.cash:.2f} 元"
        
        self.cash -= cost
        if stock_code in self.positions:
            self.positions[stock_code] += shares
        else:
            self.positions[stock_code] = shares
        
        # 记录交易历史
        self.transaction_history.append({
            'type': 'buy',
            'stock_code': stock_code,
            'shares': shares,
            'price': stock_price,
            'total': cost,
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        })
        
        return True, f"成功买入 {shares}{stock_code},花费 {cost:.2f} 元"
    
    def sell_stock(self, stock_code, shares, stock_price):
        """卖出股票"""
        if stock_code not in self.positions:
            return False, "您没有持有该股票"
            
        if self.positions[stock_code] < shares:
            return False, f"持仓不足,当前持有 {self.positions[stock_code]} 股,要卖出 {shares} 股"
        
        if shares <= 0:
            return False, "股数必须大于0"
        
        revenue = shares * stock_price
        self.cash += revenue
        self.positions[stock_code] -= shares
        
        if self.positions[stock_code] == 0:
            del self.positions[stock_code]
        
        # 记录交易历史
        self.transaction_history.append({
            'type': 'sell',
            'stock_code': stock_code,
            'shares': shares,
            'price': stock_price,
            'total': revenue,
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        })
        
        return True, f"成功卖出 {shares}{stock_code},获得 {revenue:.2f} 元"
    
    def get_total_value(self, stock_market):
        """获取总资产价值"""
        total = self.cash
        for stock_code, shares in self.positions.items():
            if stock_code in stock_market:
                total += shares * stock_market[stock_code].price
        return total
    
    def get_profit_rate(self, stock_market):
        """获取收益率"""
        total_value = self.get_total_value(stock_market)
        if self.initial_capital == 0:
            return 0
        return round((total_value - self.initial_capital) / self.initial_capital * 100, 2)
    
    def get_position_value(self, stock_code, stock_market):
        """获取某只股票的持仓价值"""
        if stock_code not in self.positions:
            return 0
        if stock_code not in stock_market:
            return 0
        return self.positions[stock_code] * stock_market[stock_code].price

class StockMarket:
    """股票市场类"""
    def __init__(self):
        self.stocks = {}
        self.initialize_market()
    
    def initialize_market(self):
        """初始化股票市场"""
        stock_list = [
            ("000001", "平安银行", 15.50),
            ("000002", "万科A", 25.80),
            ("000858", "五粮液", 180.00),
            ("002415", "海康威视", 45.60),
            ("600036", "招商银行", 38.90),
            ("600519", "贵州茅台", 1680.00),
            ("600887", "伊利股份", 32.50),
            ("000651", "格力电器", 58.70),  # 修复重复代码
            ("002594", "比亚迪", 245.00),
            ("300059", "东方财富", 28.90)
        ]
        
        for code, name, price in stock_list:
            self.stocks[code] = Stock(code, name, price)
    
    def update_all_prices(self):
        """更新所有股票价格"""
        for stock in self.stocks.values():
            stock.update_price()
    
    def get_stock_info(self, code):
        """获取股票信息"""
        if code in self.stocks:
            stock = self.stocks[code]
            return {
                'code': stock.code,
                'name': stock.name,
                'price': stock.price,
                'change_rate': stock.get_change_rate(),
                'volume': stock.volume
            }
        return None

class GameManager:
    """游戏管理器"""
    def __init__(self):
        self.market = StockMarket()
        self.players = {}
        self.load_data()
    
    def load_data(self):
        """加载游戏数据"""
        try:
            if os.path.exists('stock_game_data.json'):
                with open('stock_game_data.json', 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    for username, player_data in data.items():
                        self.players[username] = Portfolio(username, player_data.get('initial_capital', 100000))
                        self.players[username].cash = player_data.get('cash', 100000)
                        self.players[username].positions = player_data.get('positions', {})
                        self.players[username].transaction_history = player_data.get('transaction_history', [])
        except Exception as e:
            print(f"加载数据时出错: {e}")
    
    def save_data(self):
        """保存游戏数据"""
        data = {}
        for username, player in self.players.items():
            data[username] = {
                'initial_capital': player.initial_capital,
                'cash': player.cash,
                'positions': player.positions,
                'transaction_history': player.transaction_history
            }
        
        try:
            with open('stock_game_data.json', 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存数据时出错: {e}")
    
    def register_player(self, username):
        """注册新玩家"""
        if not username or username.strip() == "":
            return False, "用户名不能为空"
            
        username = username.strip()
        if username in self.players:
            return False, "用户名已存在"
        
        self.players[username] = Portfolio(username)
        self.save_data()
        return True, f"欢迎 {username} 加入模拟炒股游戏!初始资金:100,000元"
    
    def get_leaderboard(self):
        """获取排行榜"""
        leaderboard = []
        for username, player in self.players.items():
            total_value = player.get_total_value(self.market)
            profit_rate = player.get_profit_rate(self.market)
            leaderboard.append({
                'username': username,
                'total_value': total_value,
                'profit_rate': profit_rate
            })
        
        leaderboard.sort(key=lambda x: x['total_value'], reverse=True)
        return leaderboard

def display_menu():
    """显示主菜单"""
    print("\n" + "="*50)
    print("           🚀 模拟炒股游戏 ��")
    print("="*50)
    print("1. 注册/登录")
    print("2. 查看股票行情")
    print("3. 买入股票")
    print("4. 卖出股票")
    print("5. 查看我的账户")
    print("6. 查看排行榜")
    print("7. 查看交易历史")
    print("8. 退出游戏")
    print("="*50)

def display_stock_market(market):
    """显示股票行情"""
    print("\n📈 股票行情")
    print("-" * 80)
    print(f"{'代码':<8} {'名称':<12} {'当前价格':<10} {'涨跌幅':<8} {'成交量':<10}")
    print("-" * 80)
    
    for stock in market.stocks.values():
        change_rate = stock.get_change_rate()
        change_symbol = "��" if change_rate > 0 else "��" if change_rate < 0 else "➡️"
        print(f"{stock.code:<8} {stock.name:<12} {stock.price:<10.2f} {change_symbol}{change_rate:>6.2f}% {stock.volume:<10,}")

def display_portfolio(player, market):
    """显示投资组合"""
    print(f"\n�� {player.username} 的投资组合")
    print("-" * 60)
    print(f"现金余额: {player.cash:,.2f} 元")
    print(f"总资产: {player.get_total_value(market):,.2f} 元")
    print(f"收益率: {player.get_profit_rate(market):.2f}%")
    print("-" * 60)
    
    if player.positions:
        print("持仓明细:")
        print(f"{'股票代码':<8} {'股票名称':<12} {'持仓数量':<8} {'当前价值':<12} {'盈亏':<8}")
        print("-" * 60)
        for stock_code, shares in player.positions.items():
            if stock_code in market.stocks:
                stock = market.stocks[stock_code]
                current_value = shares * stock.price
                # 这里可以添加成本价计算,暂时简化
                print(f"{stock_code:<8} {stock.name:<12} {shares:<8} {current_value:<12.2f} {'--':<8}")
    else:
        print("暂无持仓")

def display_transaction_history(player):
    """显示交易历史"""
    if not player.transaction_history:
        print("暂无交易记录")
        return
        
    print(f"\n�� {player.username} 的交易历史")
    print("-" * 80)
    print(f"{'时间':<19} {'类型':<6} {'股票代码':<8} {'股数':<6} {'价格':<8} {'总额':<12}")
    print("-" * 80)
    
    for transaction in player.transaction_history[-20:]:  # 只显示最近20条
        trans_type = "买入" if transaction['type'] == 'buy' else "卖出"
        print(f"{transaction['timestamp']:<19} {trans_type:<6} {transaction['stock_code']:<8} "
              f"{transaction['shares']:<6} {transaction['price']:<8.2f} {transaction['total']:<12.2f}")

def validate_input(prompt, input_type="str", min_value=None, max_value=None):
    """验证用户输入"""
    while True:
        try:
            user_input = input(prompt).strip()
            if input_type == "int":
                value = int(user_input)
                if min_value is not None and value < min_value:
                    print(f"❌ 输入值不能小于 {min_value}")
                    continue
                if max_value is not None and value > max_value:
                    print(f"❌ 输入值不能大于 {max_value}")
                    continue
                return value
            elif input_type == "float":
                value = float(user_input)
                if min_value is not None and value < min_value:
                    print(f"❌ 输入值不能小于 {min_value}")
                    continue
                if max_value is not None and value > max_value:
                    print(f"❌ 输入值不能大于 {max_value}")
                    continue
                return value
            else:
                if not user_input:
                    print("❌ 输入不能为空")
                    continue
                return user_input
        except ValueError:
            print("❌ 输入格式错误,请重新输入")

def main():
    """主游戏循环"""
    game = GameManager()
    current_player = None
    
    print("🎮 欢迎来到模拟炒股游戏!")
    print("💡 提示:游戏会自动保存您的交易记录")
    
    while True:
        try:
            display_menu()
            choice = input("\n请选择操作 (1-8): ").strip()
            
            if choice == '1':
                # 注册/登录
                username = validate_input("请输入用户名: ")
                
                if username in game.players:
                    current_player = game.players[username]
                    print(f"✅ 欢迎回来,{username}!")
                else:
                    success, message = game.register_player(username)
                    print(message)
                    if success:
                        current_player = game.players[username]
            
            elif choice == '2':
                # 查看股票行情
                game.market.update_all_prices()
                display_stock_market(game.market)
            
            elif choice == '3':
                # 买入股票
                if not current_player:
                    print("❌ 请先登录")
                    continue
                
                display_stock_market(game.market)
                stock_code = validate_input("请输入要买入的股票代码: ")
                if stock_code not in game.market.stocks:
                    print("❌ 股票代码不存在")
                    continue
                
                shares = validate_input("请输入要买入的股数: ", "int", 1)
                stock = game.market.stocks[stock_code]
                success, message = current_player.buy_stock(stock_code, shares, stock.price)
                print(message)
                if success:
                    game.save_data()
            
            elif choice == '4':
                # 卖出股票
                if not current_player:
                    print("❌ 请先登录")
                    continue
                
                if not current_player.positions:
                    print("❌ 您没有持仓")
                    continue
                
                display_portfolio(current_player, game.market)
                stock_code = validate_input("请输入要卖出的股票代码: ")
                if stock_code not in current_player.positions:
                    print("❌ 您没有持有该股票")
                    continue
                
                max_shares = current_player.positions[stock_code]
                shares = validate_input(f"请输入要卖出的股数 (最多 {max_shares} 股): ", "int", 1, max_shares)
                
                stock = game.market.stocks[stock_code]
                success, message = current_player.sell_stock(stock_code, shares, stock.price)
                print(message)
                if success:
                    game.save_data()
            
            elif choice == '5':
                # 查看我的账户
                if not current_player:
                    print("❌ 请先登录")
                    continue
                
                display_portfolio(current_player, game.market)
            
            elif choice == '6':
                # 查看排行榜
                if not game.players:
                    print("❌ 暂无玩家数据")
                    continue
                    
                leaderboard = game.get_leaderboard()
                print("\n🏆 排行榜")
                print("-" * 60)
                print(f"{'排名':<4} {'用户名':<12} {'总资产':<15} {'收益率':<8}")
                print("-" * 60)
                
                for i, player_data in enumerate(leaderboard, 1):
                    rank_emoji = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else f"{i:2d}"
                    print(f"{rank_emoji:<4} {player_data['username']:<12} {player_data['total_value']:<15,.2f} {player_data['profit_rate']:>6.2f}%")
            
            elif choice == '7':
                # 查看交易历史
                if not current_player:
                    print("❌ 请先登录")
                    continue
                
                display_transaction_history(current_player)
            
            elif choice == '8':
                # 退出游戏
                print("👋 感谢游玩模拟炒股游戏!再见!")
                game.save_data()
                break
            
            else:
                print("❌ 无效选择,请重新输入")
            
            input("\n按回车键继续...")
            
        except KeyboardInterrupt:
            print("\n\n⚠️ 检测到中断信号,正在保存数据...")
            game.save_data()
            print("👋 游戏已保存,再见!")
            break
        except Exception as e:
            print(f"❌ 发生错误: {e}")
            print("请重新开始游戏")
            input("按回车键继续...")

if __name__ == "__main__":
    main()

在这里插入图片描述
在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西城男孩(0t0)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值