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

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;
        }
    }
}
相关推荐
Cx330❀10 分钟前
【数据结构初阶】--排序(四):归并排序
c语言·开发语言·数据结构·算法·排序算法
余_弦32 分钟前
区块链中的密码学 —— 密钥派生算法
算法·区块链
亲爱的非洲野猪1 小时前
令牌桶(Token Bucket)和漏桶(Leaky Bucket)细节对比
网络·算法·限流·服务
NAGNIP1 小时前
一文读懂LLAMA
算法
烧冻鸡翅QAQ1 小时前
62.不同路径
算法·动态规划
番薯大佬1 小时前
编程算法实例-冒泡排序
数据结构·算法·排序算法
queenlll1 小时前
P2404 自然数的拆分问题(典型的dfs)
算法·深度优先
wydaicls1 小时前
用函数实现方程函数解题
人工智能·算法·机器学习
·白小白1 小时前
力扣(LeetCode) ——100. 相同的树(C语言)
c语言·算法·leetcode
CoovallyAIHub2 小时前
为什么85%的企业AI项目都失败了?
深度学习·算法·计算机视觉