下载地址:https://pan38.com/xiazai/index.php?id=15 提取码:0fa4
兄弟们,今天咱们整点硬核的!手搓一个股票持仓生成器,连交割单都能模拟,纯Java实现,金融小白也能秒懂!💪
一、先上效果图(脑补版)


┌────────────┬──────┬───────┬─────────┬─────────┐
│ 股票代码 │ 持仓 │ 成本价 │ 当前价 │ 盈亏 │
├────────────┼──────┼───────┼─────────┼─────────┤
│ SH600519 │ 100 │ 1800.0│ 1950.0 │ +15000.0│
│ SZ300750 │ 200 │ 450.0 │ 520.0 │ +14000.0│
│ US-AAPL │ 50 │ 150.0 │ 175.0 │ +1250.0 │
└────────────┴──────┴───────┴─────────┴─────────┘
📝 最近交割单:
2023-10-20 买入 SH600519 100股 @1800.0元
2023-10-19 卖出 SZ000001 50股 @15.6元
二、核心代码实现
- 股票实体类(先搞个对象!)
java
import java.util.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 股票持仓类
class StockPosition {
private String stockCode; // 股票代码
private String stockName; // 股票名称
private int quantity; // 持仓数量
private double costPrice; // 成本价
private double currentPrice; // 当前价
// 构造函数(帅气的初始化)
public StockPosition(String stockCode, String stockName,
int quantity, double costPrice, double currentPrice) {
this.stockCode = stockCode;
this.stockName = stockName;
this.quantity = quantity;
this.costPrice = costPrice;
this.currentPrice = currentPrice;
}
// 计算盈亏(赚了还是亏了?)
public double getProfitLoss() {
return (currentPrice - costPrice) * quantity;
}
// 计算盈亏比例
public double getProfitLossRate() {
return costPrice == 0 ? 0 : (currentPrice - costPrice) / costPrice * 100;
}
// 持仓市值
public double getMarketValue() {
return currentPrice * quantity;
}
// Getter方法(别问为啥要写,Java Bean规范!)
public String getStockCode() { return stockCode; }
public String getStockName() { return stockName; }
public int getQuantity() { return quantity; }
public double getCostPrice() { return costPrice; }
public double getCurrentPrice() { return currentPrice; }
// 更新当前价格(行情变动!)
public void updatePrice(double newPrice) {
this.currentPrice = newPrice;
}
// 增加持仓(加仓!)
public void addPosition(int addQuantity, double addPrice) {
// 计算新的平均成本价
double totalCost = this.costPrice * this.quantity + addPrice * addQuantity;
this.quantity += addQuantity;
this.costPrice = totalCost / this.quantity;
}
// 减少持仓(减仓!)
public void reducePosition(int reduceQuantity) {
if (reduceQuantity <= this.quantity) {
this.quantity -= reduceQuantity;
}
}
}
交割单记录类(每一笔交易都要记下来!)
java
// 交易记录类(交割单)
class TransactionRecord {
private LocalDateTime timestamp; // 交易时间
private String stockCode; // 股票代码
private String stockName; // 股票名称
private String type; // 交易类型:BUY/SELL
private int quantity; // 数量
private double price; // 价格
private double commission; // 手续费// 交易类型常量
public static final String BUY = "买入";
public static final String SELL = "卖出";public TransactionRecord(String stockCode, String stockName,
String type, int quantity, double price) { this.timestamp = LocalDateTime.now(); this.stockCode = stockCode; this.stockName = stockName; this.type = type; this.quantity = quantity; this.price = price; // 模拟手续费:千分之三 this.commission = price * quantity * 0.003;}
// 格式化输出(看着整齐)
@Override
public String toString() {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return String.format("%s %s %s %d股 @%.2f元 手续费:%.2f元", timestamp.format(formatter), type, stockCode + "(" + stockName + ")", quantity, price, commission);}
// Getter方法
public LocalDateTime getTimestamp() { return timestamp; }
public String getStockCode() { return stockCode; }
public String getType() { return type; }
public double getAmount() { return price * quantity; }
}- 持仓管理器(核心大脑!)
java
import java.util.*;
import java.util.stream.Collectors;
// 持仓管理器
class StockPortfolio {
private Map positions; // 持仓字典
private List transactions; // 交易记录
private Random random = new Random();
// 常见股票池(假装我们有这些股票)
private Map<String, String> stockPool = new HashMap<String, String>() {
{
put("SH600519", "贵州茅台");
put("SH600036", "招商银行");
put("SZ000858", "五粮液");
put("SZ300750", "宁德时代");
put("US-AAPL", "苹果公司");
put("US-TSLA", "特斯拉");
put("HK00700", "腾讯控股");
}};
public StockPortfolio() {
positions = new HashMap<>();
transactions = new ArrayList<>();
}
// 买入股票(梭哈!)
public void buyStock(String stockCode, int quantity, double price) {
String stockName = stockPool.getOrDefault(stockCode, "未知股票");
// 记录交易
TransactionRecord record = new TransactionRecord(
stockCode, stockName, TransactionRecord.BUY, quantity, price);
transactions.add(record);
// 更新持仓
if (positions.containsKey(stockCode)) {
positions.get(stockCode).addPosition(quantity, price);
} else {
StockPosition position = new StockPosition(
stockCode, stockName, quantity, price, price);
positions.put(stockCode, position);
}
System.out.println("✅ 买入成功: " + record);
}
// 卖出股票(止盈止损!)
public void sellStock(String stockCode, int quantity, double price) {
if (!positions.containsKey(stockCode)) {
System.out.println("❌ 没有该股票持仓: " + stockCode);
return;
}
StockPosition position = positions.get(stockCode);
if (position.getQuantity() < quantity) {
System.out.println("❌ 持仓不足,当前持仓: " + position.getQuantity());
return;
}
String stockName = stockPool.getOrDefault(stockCode, "未知股票");
// 记录交易
TransactionRecord record = new TransactionRecord(
stockCode, stockName, TransactionRecord.SELL, quantity, price);
transactions.add(record);
// 更新持仓
position.reducePosition(quantity);
if (position.getQuantity() == 0) {
positions.remove(stockCode);
}
System.out.println("✅ 卖出成功: " + record);
}
// 模拟行情更新(价格随机波动)
public void updateMarketPrices() {
System.out.println("\n📊 行情更新中...");
for (StockPosition position : positions.values()) {
// 价格随机波动 ±5%
double currentPrice = position.getCurrentPrice();
double changePercent = (random.nextDouble() - 0.5) * 0.1; // ±5%
double newPrice = currentPrice * (1 + changePercent);
position.updatePrice(newPrice);
System.out.printf(" %s: %.2f -> %.2f (%.2f%%)\n",
position.getStockCode(),
currentPrice,
newPrice,
changePercent * 100);
}
}
// 显示当前持仓(重头戏!)
public void displayPositions() {
if (positions.isEmpty()) {
System.out.println("\n📭 当前没有持仓");
return;
}
System.out.println("\n📈 当前持仓:");
System.out.println("┌────────────┬────────────┬──────┬─────────┬─────────┬─────────┬────────────┐");
System.out.println("│ 股票代码 │ 股票名称 │ 持仓 │ 成本价 │ 当前价 │ 盈亏 │ 盈亏比例 │");
System.out.println("├────────────┼────────────┼──────┼─────────┼─────────┼─────────┼────────────┤");
double totalProfit = 0;
double totalMarketValue = 0;
for (StockPosition position : positions.values()) {
double profit = position.getProfitLoss();
double profitRate = position.getProfitLossRate();
double marketValue = position.getMarketValue();
totalProfit += profit;
totalMarketValue += marketValue;
// 颜色标记:盈利红色,亏损绿色(控制台版)
String profitColor = profit >= 0 ? "↑" : "↓";
String profitStr = String.format("%s%.2f", profitColor, profit);
String rateStr = String.format("%.2f%%", profitRate);
System.out.printf("│ %-10s │ %-10s │ %4d │ %7.2f │ %7.2f │ %8s │ %10s │\n",
position.getStockCode(),
position.getStockName(),
position.getQuantity(),
position.getCostPrice(),
position.getCurrentPrice(),
profitStr,
rateStr);
}
System.out.println("└────────────┴────────────┴──────┴─────────┴─────────┴─────────┴────────────┘");
System.out.printf("总市值: %.2f元 | 总盈亏: %.2f元\n\n", totalMarketValue, totalProfit);
}
// 显示交割单(交易历史)
public void displayTransactions() {
if (transactions.isEmpty()) {
System.out.println("\n📭 暂无交易记录");
return;
}
System.out.println("\n📝 交易记录(交割单):");
System.out.println("────────────────────────────────────────────────────────────────────────────");
// 按时间倒序显示最近的10条记录
List<TransactionRecord> recentTransactions = transactions.stream()
.sorted((a, b) -> b.getTimestamp().compareTo(a.getTimestamp()))
.limit(10)
.collect(Collectors.toList());
for (TransactionRecord record : recentTransactions) {
System.out.println(" " + record);
}
System.out.println("────────────────────────────────────────────────────────────────────────────");
System.out.println("共 " + transactions.size() + " 条交易记录");
}
// 生成随机交易(测试用)
public void generateRandomTransactions(int count) {
List<String> stockCodes = new ArrayList<>(stockPool.keySet());
for (int i = 0; i < count; i++) {
String stockCode = stockCodes.get(random.nextInt(stockCodes.size()));
int quantity = random.nextInt(500) + 100;
double price = random.nextDouble() * 500 + 50;
if (random.nextBoolean()) {
buyStock(stockCode, quantity, price);
} else {
// 如果有持仓才卖
if (positions.containsKey(stockCode)) {
int maxQty = positions.get(stockCode).getQuantity();
if (maxQty > 0) {
quantity = Math.min(quantity, maxQty);
sellStock(stockCode, quantity, price);
}
}
}
// 随机更新一次行情
if (random.nextDouble() > 0.7) {
updateMarketPrices();
}
}
}
}
主程序(启动!)
java
public class StockPortfolioSimulator {public static void main(String[] args) {
System.out.println("🚀 股票持仓生成器 v1.0"); System.out.println("=====================\n"); // 创建投资组合 StockPortfolio portfolio = new StockPortfolio(); // 模拟一些初始交易 System.out.println("🎯 模拟初始交易..."); portfolio.buyStock("SH600519", 100, 1800.0); portfolio.buyStock("SZ300750", 200, 450.0); portfolio.buyStock("US-AAPL", 50, 150.0); // 显示持仓 portfolio.displayPositions(); // 更新行情 portfolio.updateMarketPrices(); // 显示更新后的持仓 portfolio.displayPositions(); // 随机生成一些交易 System.out.println("\n🎲 随机生成交易记录..."); portfolio.generateRandomTransactions(5); // 显示最终持仓 portfolio.displayPositions(); // 显示交割单 portfolio.displayTransactions(); // 模拟一些卖出操作 System.out.println("\n💸 模拟卖出操作..."); portfolio.sellStock("SH600519", 50, 1900.0); // 最终状态 System.out.println("\n📊 最终状态:"); portfolio.displayPositions(); portfolio.displayTransactions(); System.out.println("\n✨ 模拟完成!"); System.out.println("\n💡 使用建议:"); System.out.println("1. 可接入真实行情API替换随机价格"); System.out.println("2. 可添加数据库持久化存储"); System.out.println("3. 可扩展为Web应用或桌面应用"); System.out.println("4. 可添加技术指标计算功能");}
}
三、运行效果示例
bash🚀 股票持仓生成器 v1.0
🎯 模拟初始交易...
✅ 买入成功: 2023-10-27 10:30:15 买入 SH600519(贵州茅台) 100股 @1800.00元 手续费:540.00元
✅ 买入成功: 2023-10-27 10:30:15 买入 SZ300750(宁德时代) 200股 @450.00元 手续费:270.00元
✅ 买入成功: 2023-10-27 10:30:15 买入 US-AAPL(苹果公司) 50股 @150.00元 手续费:22.50元
📈 当前持仓:
┌────────────┬────────────┬──────┬─────────┬─────────┬─────────┬────────────┐
│ 股票代码 │ 股票名称 │ 持仓 │ 成本价 │ 当前价 │ 盈亏 │ 盈亏比例 │
├────────────┼────────────┼──────┼─────────┼─────────┼─────────┼────────────┤
│ SH600519 │ 贵州茅台 │ 100 │ 1800.00 │ 1800.00 │ ↑0.00 │ 0.00% │
│ SZ300750 │ 宁德时代 │ 200 │ 450.00 │ 450.00 │ ↑0.00 │ 0.00% │
│ US-AAPL │ 苹果公司 │ 50 │ 150.00 │ 150.00 │ ↑0.00 │ 0.00% │
└────────────┴────────────┴──────┴─────────┴─────────┴─────────┴────────────┘
总市值: 270000.00元 | 总盈亏: 0.00元
四、扩展功能建议
接入真实API:使用腾讯、新浪的免费股票API
图形界面:Swing或JavaFX实现可视化
数据持久化:用SQLite或MySQL保存数据
策略回测:添加简单的交易策略
风险分析:计算夏普比率、最大回撤等
五、总结
这波操作学会了没?用Java写金融系统其实也没那么难!从持仓管理到交割单记录,我们一套全搞定了。兄弟们可以自己扩展功能,比如加上K线图显示、技术指标计算啥的。
重要提醒:这只是模拟系统,千万别直接用于实盘交易!实盘需要更严谨的风控和验证。
一键三连啊兄弟们!代码都在这了,拿去魔改吧!有问题的评论区见,我会尽量回复!💥