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

7.4.1 搜索引擎

7.4.2 推荐系统

7.4.3 金融算法

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

金融领域使用的算法:

  1. 风险评估模型
java 复制代码
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. 交易策略
java 复制代码
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. 欺诈检测
java 复制代码
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;
        }
    }
}
相关推荐
不正经学生8 分钟前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
毕竟是shy哥3 小时前
计算YOLO数据集中每个类的目标数
算法·yolo·机器学习
M78佐菲3 小时前
Linux学习笔记:TCP协议
linux·笔记·学习·tcp/ip·算法
晊晌_h4 小时前
嵌入式从0到精通——数据结构总结[特殊字符]
数据结构·算法·排序算法
我找到地球的支点啦5 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
罗西的思考5 小时前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(3)--- RAG
人工智能·算法·机器学习
浪里镖客6 小时前
位姿转换矩阵写法-个人习惯(计算机理解其实是相反的)
线性代数·算法·矩阵
小白羊丨9 小时前
如何诊断 Prompt 模板导致的效果下降?
人工智能·算法·prompt
OPEN-F10 小时前
C++11/14新特性精讲:移动语义与智能指针实战
开发语言·c++·算法
lisin-lee-cooper10 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法