本文目录导读:

我来为你提供一个Java股票数据监控系统的完整案例,这个系统会模拟实时获取股票数据、分析和报警功能。
系统架构
StockMonitorSystem/
├── model/
│ └── Stock.java
├── service/
│ ├── StockDataFetcher.java
│ └── StockMonitor.java
├── handler/
│ └── AlertHandler.java
└── Main.java
完整代码实现
股票数据模型 (Stock.java)
package model;
import java.math.BigDecimal;
import java.time.LocalDateTime;
public class Stock {
private String code;
private String name;
private BigDecimal currentPrice;
private BigDecimal openPrice;
private BigDecimal highPrice;
private BigDecimal lowPrice;
private BigDecimal previousClose;
private long volume;
private LocalDateTime updateTime;
public Stock(String code, String name) {
this.code = code;
this.name = name;
this.updateTime = LocalDateTime.now();
}
// Getter和Setter方法
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public BigDecimal getCurrentPrice() { return currentPrice; }
public void setCurrentPrice(BigDecimal currentPrice) {
this.currentPrice = currentPrice;
}
public BigDecimal getOpenPrice() { return openPrice; }
public void setOpenPrice(BigDecimal openPrice) { this.openPrice = openPrice; }
public BigDecimal getHighPrice() { return highPrice; }
public void setHighPrice(BigDecimal highPrice) { this.highPrice = highPrice; }
public BigDecimal getLowPrice() { return lowPrice; }
public void setLowPrice(BigDecimal lowPrice) { this.lowPrice = lowPrice; }
public BigDecimal getPreviousClose() { return previousClose; }
public void setPreviousClose(BigDecimal previousClose) {
this.previousClose = previousClose;
}
public long getVolume() { return volume; }
public void setVolume(long volume) { this.volume = volume; }
public LocalDateTime getUpdateTime() { return updateTime; }
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
// 计算涨跌幅
public double getChangePercent() {
if (previousClose == null || previousClose.compareTo(BigDecimal.ZERO) == 0) {
return 0.0;
}
return currentPrice.subtract(previousClose)
.divide(previousClose, 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal(100))
.doubleValue();
}
@Override
public String toString() {
return String.format("Stock{code='%s', name='%s', price=%.2f, change=%.2f%%}",
code, name, currentPrice, getChangePercent());
}
}
股票数据获取器 (StockDataFetcher.java)
package service;
import model.Stock;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
public class StockDataFetcher {
private Map<String, Stock> stockDatabase;
private ThreadLocalRandom random;
public StockDataFetcher() {
this.stockDatabase = new HashMap<>();
this.random = ThreadLocalRandom.current();
initializeStocks();
}
private void initializeStocks() {
// 初始化一些模拟股票数据
addStock("000001", "平安银行", new BigDecimal("12.50"));
addStock("000002", "万科A", new BigDecimal("15.80"));
addStock("600519", "贵州茅台", new BigDecimal("1680.00"));
addStock("000858", "五粮液", new BigDecimal("135.50"));
addStock("300750", "宁德时代", new BigDecimal("220.30"));
}
private void addStock(String code, String name, BigDecimal price) {
Stock stock = new Stock(code, name);
stock.setCurrentPrice(price);
stock.setOpenPrice(price);
stock.setPreviousClose(price);
stock.setHighPrice(price);
stock.setLowPrice(price);
stock.setVolume(0);
stockDatabase.put(code, stock);
}
// 获取单个股票数据(模拟实时数据)
public Stock fetchStockData(String code) {
Stock stock = stockDatabase.get(code);
if (stock == null) {
throw new IllegalArgumentException("Stock not found: " + code);
}
// 模拟价格波动(-2% 到 +2%)
double fluctuation = (random.nextDouble() - 0.5) * 4; // -2% 到 +2%
BigDecimal oldPrice = stock.getCurrentPrice();
BigDecimal newPrice = oldPrice.multiply(
new BigDecimal(1 + fluctuation / 100)
).setScale(2, BigDecimal.ROUND_HALF_UP);
// 更新股票数据
stock.setPreviousClose(oldPrice);
stock.setCurrentPrice(newPrice);
stock.setHighPrice(newPrice.compareTo(stock.getHighPrice()) > 0 ?
newPrice : stock.getHighPrice());
stock.setLowPrice(newPrice.compareTo(stock.getLowPrice()) < 0 ?
newPrice : stock.getLowPrice());
stock.setVolume(stock.getVolume() + random.nextLong(1000, 10000));
return stock;
}
// 获取所有股票数据
public List<Stock> fetchAllStocks() {
List<Stock> stocks = new ArrayList<>();
for (String code : stockDatabase.keySet()) {
stocks.add(fetchStockData(code));
}
return stocks;
}
// 批量获取指定股票数据
public List<Stock> fetchStocks(List<String> codes) {
List<Stock> stocks = new ArrayList<>();
for (String code : codes) {
stocks.add(fetchStockData(code));
}
return stocks;
}
}
股票监控器 (StockMonitor.java)
package service;
import model.Stock;
import handler.AlertHandler;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
public class StockMonitor {
private StockDataFetcher dataFetcher;
private AlertHandler alertHandler;
private Map<String, MonitorConfig> monitorConfigs;
private ScheduledExecutorService scheduler;
private volatile boolean isRunning;
// 监控配置类
public static class MonitorConfig {
private String stockCode;
private BigDecimal priceUpperLimit;
private BigDecimal priceLowerLimit;
private double changePercentLimit;
private long checkInterval; // 毫秒
public MonitorConfig(String stockCode, BigDecimal upperLimit,
BigDecimal lowerLimit, double changePercent,
long interval) {
this.stockCode = stockCode;
this.priceUpperLimit = upperLimit;
this.priceLowerLimit = lowerLimit;
this.changePercentLimit = changePercent;
this.checkInterval = interval;
}
// Getter方法
public String getStockCode() { return stockCode; }
public BigDecimal getPriceUpperLimit() { return priceUpperLimit; }
public BigDecimal getPriceLowerLimit() { return priceLowerLimit; }
public double getChangePercentLimit() { return changePercentLimit; }
public long getCheckInterval() { return checkInterval; }
}
public StockMonitor() {
this.dataFetcher = new StockDataFetcher();
this.alertHandler = new AlertHandler();
this.monitorConfigs = new ConcurrentHashMap<>();
this.scheduler = Executors.newScheduledThreadPool(5);
}
// 添加监控配置
public void addMonitorConfig(MonitorConfig config) {
monitorConfigs.put(config.getStockCode(), config);
}
// 移除监控配置
public void removeMonitorConfig(String stockCode) {
monitorConfigs.remove(stockCode);
}
// 开始监控
public void startMonitoring() {
isRunning = true;
System.out.println("股票监控系统启动...");
for (MonitorConfig config : monitorConfigs.values()) {
startMonitoringStock(config);
}
}
// 监控单个股票
private void startMonitoringStock(MonitorConfig config) {
scheduler.scheduleAtFixedRate(() -> {
if (!isRunning) return;
try {
Stock stock = dataFetcher.fetchStockData(config.getStockCode());
checkAndAlert(stock, config);
} catch (Exception e) {
System.err.println("监控股票 " + config.getStockCode() +
" 时发生错误: " + e.getMessage());
}
}, 0, config.getCheckInterval(), TimeUnit.MILLISECONDS);
}
// 检查并发送警报
private void checkAndAlert(Stock stock, MonitorConfig config) {
List<String> alerts = new ArrayList<>();
// 检查价格上限
if (config.getPriceUpperLimit() != null &&
stock.getCurrentPrice().compareTo(config.getPriceUpperLimit()) > 0) {
alerts.add(String.format("价格超过上限: %.2f > %.2f",
stock.getCurrentPrice(), config.getPriceUpperLimit()));
}
// 检查价格下限
if (config.getPriceLowerLimit() != null &&
stock.getCurrentPrice().compareTo(config.getPriceLowerLimit()) < 0) {
alerts.add(String.format("价格低于下限: %.2f < %.2f",
stock.getCurrentPrice(), config.getPriceLowerLimit()));
}
// 检查涨跌幅
if (config.getChangePercentLimit() > 0 &&
Math.abs(stock.getChangePercent()) > config.getChangePercentLimit()) {
alerts.add(String.format("涨跌幅超过限制: %.2f%% > %.2f%%",
stock.getChangePercent(), config.getChangePercentLimit()));
}
// 发送警报
if (!alerts.isEmpty()) {
alertHandler.sendAlert(stock, alerts);
}
}
// 停止监控
public void stopMonitoring() {
isRunning = false;
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
}
System.out.println("股票监控系统已停止");
}
// 获取当前监控状态
public boolean isRunning() {
return isRunning;
}
}
警报处理器 (AlertHandler.java)
package handler;
import model.Stock;
import java.time.LocalDateTime;
import java.util.List;
public class AlertHandler {
// 发送警报
public void sendAlert(Stock stock, List<String> alertMessages) {
System.out.println("\n========================================");
System.out.println("⚠️ 股票警报 - " + LocalDateTime.now());
System.out.println("股票代码: " + stock.getCode());
System.out.println("股票名称: " + stock.getName());
System.out.println("当前价格: ¥" + String.format("%.2f", stock.getCurrentPrice()));
System.out.println("涨跌幅: " + String.format("%.2f%%", stock.getChangePercent()));
System.out.println("\n警报原因:");
for (String message : alertMessages) {
System.out.println(" - " + message);
}
System.out.println("========================================\n");
}
// 高级警报(支持更多通知方式)
public void sendAdvancedAlert(Stock stock, String alertType, String message) {
// 这里可以添加邮件通知、短信通知等
// 示例:控制台输出
System.out.printf("[%s] %s - %s: %s%n",
LocalDateTime.now(), alertType, stock.getCode(), message);
// 模拟发送邮件
sendEmailAlert(stock, message);
// 模拟发送短信
sendSMSAlert(stock, message);
}
private void sendEmailAlert(Stock stock, String message) {
// 实际应用中这里会实现邮件发送逻辑
System.out.println("📧 发送邮件通知: " + stock.getCode() + " - " + message);
}
private void sendSMSAlert(Stock stock, String message) {
// 实际应用中这里会实现短信发送逻辑
System.out.println("📱 发送短信通知: " + stock.getCode() + " - " + message);
}
}
主程序 (Main.java)
import model.Stock;
import service.StockDataFetcher;
import service.StockMonitor;
import service.StockMonitor.MonitorConfig;
import java.math.BigDecimal;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("===== 股票数据监控系统 =====");
System.out.println("版本 1.0.0");
System.out.println();
// 创建监控系统
StockMonitor monitor = new StockMonitor();
// 设置监控规则
setupMonitoringRules(monitor);
// 启动监控
monitor.startMonitoring();
// 显示实时数据
displayRealtimeData(monitor);
// 运行一段时间后停止(实际应用中会持续运行)
System.out.println("系统将在30秒后自动停止...");
Thread.sleep(30000);
// 停止监控
monitor.stopMonitoring();
System.out.println("系统演示结束");
}
private static void setupMonitoringRules(StockMonitor monitor) {
// 为不同股票设置不同的监控规则
// 监控贵州茅台:价格超过1700或低于1650时报警,涨跌幅超过1%报警
monitor.addMonitorConfig(new MonitorConfig(
"600519", // 股票代码
new BigDecimal("1700"), // 价格上限
new BigDecimal("1650"), // 价格下限
1.0, // 涨跌幅限制 1%
2000 // 检查间隔 2秒
));
// 监控宁德时代:价格超过230或低于210时报警,涨跌幅超过2%报警
monitor.addMonitorConfig(new MonitorConfig(
"300750",
new BigDecimal("230"),
new BigDecimal("210"),
2.0,
1500
));
// 监控万科A:涨跌幅超过3%报警
monitor.addMonitorConfig(new MonitorConfig(
"000002",
null, // 不设置价格上限
null, // 不设置价格下限
3.0,
3000
));
System.out.println("已配置 " + 3 + " 个监控规则");
}
private static void displayRealtimeData(StockMonitor monitor) {
StockDataFetcher fetcher = new StockDataFetcher();
// 创建线程定期显示数据
new Thread(() -> {
while (monitor.isRunning()) {
try {
Thread.sleep(5000); // 每5秒刷新一次
System.out.println("\n--- 实时股票数据 ---");
List<Stock> stocks = fetcher.fetchAllStocks();
for (Stock stock : stocks) {
System.out.println(stock);
}
System.out.println("--------------------\n");
} catch (InterruptedException e) {
break;
}
}
}).start();
}
}
运行示例输出
===== 股票数据监控系统 =====
版本 1.0.0
已配置 3 个监控规则
股票监控系统启动...
--- 实时股票数据 ---
Stock{code='000001', name='平安银行', price=12.63, change=1.04%}
Stock{code='000002', name='万科A', price=15.72, change=-0.51%}
Stock{code='600519', name='贵州茅台', price=1665.20, change=-0.88%}
Stock{code='000858', name='五粮液', price=136.80, change=0.96%}
Stock{code='300750', name='宁德时代', price=215.60, change=-2.14%}
--------------------
========================================
⚠️ 股票警报 - 2024-01-15T10:30:25.123
股票代码: 300750
股票名称: 宁德时代
当前价格: ¥215.60
涨跌幅: -2.14%
警报原因:
- 涨跌幅超过限制: 2.14% > 2.00%
========================================
系统将在30秒后自动停止...
股票监控系统已停止
系统演示结束
扩展建议
-
真实数据源集成
- 使用新浪财经API、腾讯股票API等
- 集成WebSocket实时数据流
-
数据持久化
- 使用数据库存储历史数据
- 实现数据导出功能
-
高级功能
- 技术指标计算(MACD、RSI等)
- 自定义策略引擎
- 回测系统
-
通知方式
- 邮件通知(JavaMail)
- 微信通知(企业微信API)
- 短信通知(阿里云短信)
这个系统提供了一个完整的股票监控框架,你可以根据实际需求进行扩展和定制。