零基础数据结构与算法——第七章:算法实践与工程应用-金融算法

发布于:2025-08-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

7.4.1 搜索引擎

7.4.2 推荐系统

7.4.3 金融算法

金融领域也广泛应用各种算法,如风险评估、交易策略、欺诈检测等。

金融领域使用的算法:

  1. 风险评估模型
public class CreditScoreModel {
    private double[] weights; // 特征权重
    
    public CreditScoreModel(double[] weights) {
        this.weights = weights;
    }
    
    public double calculateCreditScore(double[] features) {
        if (features.length != weights.length) {
            throw new IllegalArgumentException("Features length must match weights length");
        }
        
        double score = 0;
        for (int i = 0; i < features.length; i++) {
            score += features[i] * weights[i];
        }
        
        // 将分数映射到300-850的范围(标准信用分数范围)
        return 300 + (score * 550 / 100);
    }
    
    public String getCreditRating(double creditScore) {
        if (creditScore >= 800) return "Excellent";
        if (creditScore >= 740) return "Very Good";
        if (creditScore >= 670) return "Good";
        if (creditScore >= 580) return "Fair";
        return "Poor";
    }
}
  1. 交易策略
public class MovingAverageStrategy {
    private int shortPeriod; // 短期移动平均线周期
    private int longPeriod; // 长期移动平均线周期
    private List<Double> prices = new ArrayList<>(); // 历史价格
    
    public MovingAverageStrategy(int shortPeriod, int longPeriod) {
        this.shortPeriod = shortPeriod;
        this.longPeriod = longPeriod;
    }
    
    public void addPrice(double price) {
        prices.add(price);
    }
    
    public String getSignal() {
        if (prices.size() < longPeriod) {
            return "HOLD"; // 数据不足,无法生成信号
        }
        
        double shortMA = calculateMA(shortPeriod);
        double longMA = calculateMA(longPeriod);
        
        // 短期均线上穿长期均线,买入信号
        if (shortMA > longMA && calculateMA(shortPeriod, 1) <= calculateMA(longPeriod, 1)) {
            return "BUY";
        }
        
        // 短期均线下穿长期均线,卖出信号
        if (shortMA < longMA && calculateMA(shortPeriod, 1) >= calculateMA(longPeriod, 1)) {
            return "SELL";
        }
        
        return "HOLD";
    }
    
    private double calculateMA(int period) {
        return calculateMA(period, 0);
    }
    
    private double calculateMA(int period, int offset) {
        int start = prices.size() - period - offset;
        int end = prices.size() - offset;
        
        double sum = 0;
        for (int i = start; i < end; i++) {
            sum += prices.get(i);
        }
        
        return sum / period;
    }
}
  1. 欺诈检测
public class FraudDetection {
    private Map<String, List<Transaction>> userTransactions = new HashMap<>(); // 用户交易历史
    
    public void addTransaction(Transaction transaction) {
        userTransactions.computeIfAbsent(transaction.getUserId(), k -> new ArrayList<>())
                        .add(transaction);
    }
    
    public boolean isFraudulent(Transaction transaction) {
        List<Transaction> history = userTransactions.getOrDefault(transaction.getUserId(), Collections.emptyList());
        
        // 检查交易金额是否异常
        if (isAmountAnomalous(transaction, history)) {
            return true;
        }
        
        // 检查交易频率是否异常
        if (isFrequencyAnomalous(transaction, history)) {
            return true;
        }
        
        // 检查交易地点是否异常
        if (isLocationAnomalous(transaction, history)) {
            return true;
        }
        
        return false;
    }
    
    private boolean isAmountAnomalous(Transaction transaction, List<Transaction> history) {
        if (history.isEmpty()) return false;
        
        // 计算历史交易金额的平均值和标准差
        double sum = 0;
        for (Transaction t : history) {
            sum += t.getAmount();
        }
        double mean = sum / history.size();
        
        double variance = 0;
        for (Transaction t : history) {
            variance += Math.pow(t.getAmount() - mean, 2);
        }
        double stdDev = Math.sqrt(variance / history.size());
        
        // 如果交易金额超过平均值的3个标准差,认为是异常
        return transaction.getAmount() > mean + 3 * stdDev;
    }
    
    private boolean isFrequencyAnomalous(Transaction transaction, List<Transaction> history) {
        if (history.isEmpty()) return false;
        
        // 计算最近24小时内的交易次数
        long recentCount = history.stream()
                                 .filter(t -> t.getTimestamp() > transaction.getTimestamp() - 24 * 60 * 60 * 1000)
                                 .count();
        
        // 如果最近24小时内的交易次数超过10次,认为是异常
        return recentCount > 10;
    }
    
    private boolean isLocationAnomalous(Transaction transaction, List<Transaction> history) {
        if (history.isEmpty()) return false;
        
        // 获取最近一次交易
        Transaction lastTransaction = history.get(history.size() - 1);
        
        // 计算两次交易之间的地理距离
        double distance = calculateDistance(
            lastTransaction.getLatitude(), lastTransaction.getLongitude(),
            transaction.getLatitude(), transaction.getLongitude());
        
        // 计算两次交易之间的时间差(小时)
        double timeDiff = (transaction.getTimestamp() - lastTransaction.getTimestamp()) / (60 * 60 * 1000.0);
        
        // 如果距离太远且时间太短,认为是异常
        // 假设正常人的最大移动速度是1000公里/小时(飞机速度)
        return distance > 1000 * timeDiff;
    }
    
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        // 使用Haversine公式计算两点之间的距离
        double earthRadius = 6371; // 地球半径(公里)
        
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                 Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                 Math.sin(dLon / 2) * Math.sin(dLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        return earthRadius * c;
    }
    
    static class Transaction {
        private String userId;
        private double amount;
        private long timestamp;
        private double latitude;
        private double longitude;
        
        // 构造函数、getter和setter方法
        // ...
        
        public String getUserId() {
            return userId;
        }
        
        public double getAmount() {
            return amount;
        }
        
        public long getTimestamp() {
            return timestamp;
        }
        
        public double getLatitude() {
            return latitude;
        }
        
        public double getLongitude() {
            return longitude;
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到