java實現網格交易回測

以下是一個基于Java實現的簡單網格交易回測程序框架,以證券ETF(512880)為例。代碼包含歷史數據加載、網格策略邏輯和基礎統計指標:

import java.io.BufferedReader;
import java.io.FileReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;// K線數據對象
class KData {Date date;double open;double high;double low;double close;long volume;public KData(String[] data) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");this.date = sdf.parse(data[0]);this.open = Double.parseDouble(data[1]);this.high = Double.parseDouble(data[2]);this.low = Double.parseDouble(data[3]);this.close = Double.parseDouble(data[4]);this.volume = Long.parseLong(data[5]);}
}// 網格策略回測引擎
class GridStrategyBacktest {List<KData> historicalData;double initialCapital = 100000;  // 初始資金10萬元double cash = initialCapital;int position = 0;  // 持倉數量double gridStep = 0.05;  // 網格間距5%int gridLevels = 10;     // 網格層數double basePrice;        // 基準價(網格中心)List<String> trades = new ArrayList<>();  // 交易記錄double totalReturn = 0;int winCount = 0;int tradeCount = 0;public GridStrategyBacktest(List<KData> data, double basePrice) {this.historicalData = data;this.basePrice = basePrice;}// 執行回測public void runBacktest() {for (KData bar : historicalData) {double price = bar.close;// 計算當前價格對應的網格層級int targetLevel = (int) ((price - basePrice) / (basePrice * gridStep));// 計算應該持有的倉位int targetPosition = Math.min(gridLevels, Math.max(-gridLevels, targetLevel)) * 100;// 執行交易int volumeToTrade = targetPosition - position;if (volumeToTrade != 0) {executeTrade(bar.date, price, volumeToTrade);}}// 計算最終收益totalReturn = (cash + position * historicalData.get(historicalData.size()-1).close - initialCapital) / initialCapital;}private void executeTrade(Date date, double price, int volume) {double cost = Math.abs(volume) * price * 1.0003;  // 包含0.03%的交易費用if (volume > 0) {  // 買入if (cost > cash) return;cash -= cost;position += volume;trades.add(String.format("%tF - 買入 %d股 @ %.4f", date, volume, price));} else {          // 賣出if (-volume > position) return;cash += (-volume) * price * 0.9997;  // 扣除賣出手續費position += volume;trades.add(String.format("%tF - 賣出 %d股 @ %.4f", date, -volume, price));}tradeCount++;if ((volume > 0 && price < basePrice) || (volume < 0 && price > basePrice)) {winCount++;}}// 輸出統計結果public void printResults() {System.out.println("===== 回測結果 =====");System.out.printf("初始資金: %.2f\n", initialCapital);System.out.printf("最終資產: %.2f\n", cash + position * historicalData.get(historicalData.size()-1).close);System.out.printf("總收益率: %.2f%%\n", totalReturn * 100);System.out.printf("交易次數: %d\n勝率: %.2f%%\n", tradeCount, (double)winCount/tradeCount*100);System.out.println("\n最后5筆交易記錄:");trades.subList(Math.max(0, trades.size()-5), trades.size()).forEach(System.out::println);}
}public class ETFBacktester {public static void main(String[] args) {// 1. 加載歷史數據(示例數據格式:日期,開盤價,最高價,最低價,收盤價,成交量)List<KData> history = loadCSV("512880.csv");  // 需替換為實際數據文件路徑// 2. 設置網格參數double basePrice = 1.0;  // 根據歷史中位數設定網格基準價// 3. 運行回測GridStrategyBacktest backtester = new GridStrategyBacktest(history, basePrice);backtester.runBacktest();// 4. 輸出結果backtester.printResults();}private static List<KData> loadCSV(String filename) {List<KData> data = new ArrayList<>();try (BufferedReader br = new BufferedReader(new FileReader(filename))) {String line;br.readLine();  // 跳過標題行while ((line = br.readLine()) != null) {String[] values = line.split(",");data.add(new KData(values));}} catch (Exception e) {e.printStackTrace();}return data;}
}

代碼說明及使用步驟:

  1. 數據準備

    • 需要準備CSV格式的歷史數據文件(示例文件名:512880.csv)
    • 數據格式(按日期排序):
      日期,開盤價,最高價,最低價,收盤價,成交量
      2023-01-03,1.052,1.068,1.050,1.065,12345678
      ...
      
  2. 核心邏輯

    • 網格生成:以基準價(basePrice)為中心,上下各生成gridLevels層網格
    • 交易觸發:當價格突破網格層級時調整倉位
    • 費用計算:包含0.03%的買賣雙邊交易費用
  3. 關鍵參數

    double initialCapital = 100000;  // 初始資金
    double gridStep = 0.05;         // 5%網格間距
    int gridLevels = 10;            // 網格層數
    
  4. 輸出指標

    • 總收益率
    • 交易次數
    • 勝率(盈利交易占比)
    • 詳細交易記錄

擴展建議(可根據需求添加):

  1. 增強統計指標

    // 在GridStrategyBacktest類中添加:
    double maxDrawdown = 0;     // 最大回撤
    double peak = initialCapital;// 在每次交易后更新:
    double currentValue = cash + position * price;
    if (currentValue > peak) {peak = currentValue;
    } else {double dd = (peak - currentValue)/peak;if (dd > maxDrawdown) maxDrawdown = dd;
    }
    
  2. 參數優化功能

    public void optimizeParameters() {for (double step = 0.03; step < 0.08; step += 0.01) {for (int levels = 5; levels <= 15; levels += 2) {GridStrategyBacktest test = new GridStrategyBacktest(history, basePrice);test.gridStep = step;test.gridLevels = levels;test.runBacktest();System.out.printf("步長:%.2f 層數:%d 收益:%.2f%%\n", step, levels, test.totalReturn*100);}}
    }
    
  3. 可視化輸出

    // 使用JFreeChart庫生成收益曲線圖
    XYSeries series = new XYSeries("凈值曲線");
    for (int i = 0; i < historicalData.size(); i++) {double value = cash + position * historicalData.get(i).close;series.add(i, value / initialCapital);
    }
    

注意事項:

  1. 需要復權價格數據(建議使用后復權)
  2. 實際交易需考慮最小交易單位(A股ETF為100股整數倍)
  3. 可增加止盈止損邏輯:
    // 在executeTrade方法中添加:
    if (totalReturn > 0.3) {  // 收益率超過30%時清倉int sellVolume = position;executeTrade(date, price, -sellVolume);
    }
    

如需完整實現,建議結合第三方庫(如Ta4j用于技術指標計算)和數據庫(存儲歷史數據)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探秘 3D 展廳之卓越優勢,解鎖沉浸式體驗新境界

&#xff08;一&#xff09;打破時空枷鎖&#xff0c;全球觸達? 3D 展廳的首要優勢便是打破了時空限制。在傳統展廳中&#xff0c;觀眾需要親臨現場&#xff0c;且必須在展廳開放的特定時間內參觀。而 3D 展廳依托互聯網&#xff0c;讓觀眾無論身處世界哪個角落&#xff0c;只…

第十二屆藍橋杯 2021 C/C++組 直線

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 核心思路&#xff1a; 兩點確定一條直線&#xff1a; 思路詳解&#xff1a; 代碼&#xff1a; 第一種方式代碼詳解&#xff1a; 第二種方式代碼詳解&#xff1a; 題目&#xff1a;…

微信小程序藍牙連接打印機打印單據完整Demo【藍牙小票打印】

文章目錄 一、準備工作1. 硬件準備2. 開發環境 二、小程序配置1. 修改app.json 三、完整代碼實現1. pages/index/index.wxml2. pages/index/index.wxss3. pages/index/index.js 四、ESC/POS指令說明五、測試流程六、常見問題解決七、進一步優化建議 下面我將提供一個完整的微信…

ubuntu opencv 安裝

1.ubuntu opencv 安裝 在Ubuntu系統中安裝OpenCV&#xff0c;可以通過多種方式進行&#xff0c;以下是一種常用的安裝方法&#xff0c;包括從源代碼編譯安裝。請注意&#xff0c;安裝步驟可能會因OpenCV的版本和Ubuntu系統的具體版本而略有不同。 一、安裝準備 更新系統&…

【C++】class靜態常量

Usage: static const T 1 background static const成員屬于類&#xff0c;而不是類的實例&#xff0c;所以它們的初始化需要在類外進行(或者在C17之后可以用inline初始化)。 使用中可能遇到的情況&#xff1a; 在頭文件中聲明一個static const成員&#xff0c;然后在多個cpp…

Java 安全:如何防止 DDoS 攻擊?

一、DDoS 攻擊簡介 DDoS&#xff08;分布式拒絕服務&#xff09;攻擊是一種常見的網絡攻擊手段&#xff0c;攻擊者通過控制大量的僵尸主機向目標服務器發送海量請求&#xff0c;致使服務器資源耗盡&#xff0c;無法正常響應合法用戶請求。在 Java 應用開發中&#xff0c;了解 …

統計文件中單詞出現的次數并累計

# 統計單詞出現次數 fileopen("E:\Dasktape/python_test.txt","r",encoding"UTF-8") f1file.read() # 讀取文件 countf1.count("is") # 統計文件中is 單詞出現的次數 print(f"此文件中單詞is出現了{count}次")# 2.判斷單詞出…

C語言實現貪心算法

一、貪心算法核心思想 特征&#xff1a;在每一步選擇中都采取當前狀態下最優&#xff08;局部最優&#xff09;的選擇&#xff0c;從而希望導致全局最優解 適用場景&#xff1a;需要滿足貪心選擇性質和最優子結構性質 二、經典貪心算法示例 1. 活動選擇問題 目標&#xff1a…

《一文讀懂Transformers庫:開啟自然語言處理新世界的大門》

《一文讀懂Transformers庫:開啟自然語言處理新世界的大門》 GitHub - huggingface/transformers: ?? Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX. HF-Mirror Hello! Transformers快速入門 pip install transformers -i https:/…

Vue里面elementUi-aside 和el-main不垂直排列

先說解決方法 main.js少導包 import element-ui/lib/theme-chalk/index.css; //加入此行即可 問題復現 排查了一個小時終于找出來問題了&#xff0c;建議導包去看官方的文檔&#xff0c;作者就是因為看了別人的導包流程導致的問題 導包官網地址Element UI導包快速入門

MYSQL 常用字符串函數 和 時間函數詳解

一、字符串函數 1、?CONCAT(str1, str2, …) 拼接多個字符串。 SELECT CONCAT(Hello, , World); -- 輸出 Hello World2、SUBSTRING(str, start, length)?? 或 ?SUBSTR() 截取字符串。 SELECT SUBSTRING(MySQL, 3, 2); -- 輸出 SQ3、LENGTH(str)?? 與 ?CHAR_LENGTH…

Python-Agent調用多個Server-FastAPI版本

Python-Agent調用多個Server-FastAPI版本 Agent調用多個McpServer進行工具調用 1-核心知識點 fastAPI的快速使用agent調用多個server 2-思路整理 1&#xff09;先把每個子服務搭建起來2&#xff09;再暴露一個Agent 3-參考網址 VSCode配置Python開發環境&#xff1a;https:/…

Drools+自定義規則庫

文章目錄 前言一、創建規則庫二、SpringBootDrools程序1.Maven依賴2.application.yml3.Mapper.xml4.Drools配置類5.Service6.Contoller7.測試接口 前言 公司的技術方案想搭建Drools自定義規則庫配合大模型進行數據的校驗。本篇用來記錄使用SpringBoot配合Drools開發Demo程序。…

潮了 低配電腦6G顯存生成60秒AI視頻 本地部署/一鍵包/云算力部署/批量生成

最近發現了一個讓人眼前一亮的工具——FramePack&#xff0c;它能用一塊普通的6GB顯存筆記本GPU&#xff0c;生成60秒電影級的高清視頻畫面&#xff0c;效果堪稱炸裂&#xff01;那么我們就把他本地部署起來玩一玩、下載離線一鍵整合包&#xff0c;或者是用云算力快速上手。接下…

【藍橋杯選拔賽真題104】Scratch回文數 第十五屆藍橋杯scratch圖形化編程 少兒編程創意編程選拔賽真題解析

目錄 scratch回文數 一、題目要求 1、準備工作 2、功能實現 二、案例分析 1、角色分析 2、背景分析 3、前期準備 三、解題思路 四、程序編寫 五、考點分析 六、推薦資料 1、scratch資料 2、python資料 3、C++資料 scratch回文數 第十五屆青少年藍橋杯scratch編…

大廠面試-框架篇

前言 本章內容來自B站黑馬程序員java大廠面試題和小林coding 博主學習筆記&#xff0c;如果有不對的地方&#xff0c;海涵。 如果這篇文章對你有幫助&#xff0c;可以點點關注&#xff0c;點點贊&#xff0c;謝謝你&#xff01; 1.Spring 1.1 Spring框架中的單例bean是線程…

【AI 加持下的 Python 編程實戰 2_10】DIY 拓展:從掃雷小游戲開發再探問題分解與 AI 代碼調試能力(中)

文章目錄 DIY 實戰&#xff1a;從掃雷小游戲開發再探問題分解能力3 問題分解實戰&#xff08;自頂向下&#xff09;3.2 頁面渲染邏輯3.3 事件綁定邏輯 4 代碼實現&#xff08;自底向上&#xff09;4.1 頁面渲染部分4.2 事件綁定部分 寫在前面 本篇將利用《Learn AI-assisted Py…

微信小程序開發1------微信小程序中的消息提示框總結

微信小程序中的消息提示框主要分為以下幾種&#xff1a; 1. wx.showToast(Object object) 功能&#xff1a; 顯示消息提示框&#xff0c;一般用于顯示操作結果、狀態等。 特點&#xff1a; 提示框顯示在屏幕中間&#xff0c;持續一段時間后自動消失&#xff08;默認1.5秒&…

AI 場景落地:API 接口服務 VS 本地部署,哪種更適合?

在當前 AI 技術迅猛發展的背景下&#xff0c;企業在實現 AI 場景落地時&#xff0c;面臨著一個關鍵抉擇&#xff1a;是選擇各大廠商提供的 API 接口服務&#xff0c;還是進行本地化部署&#xff1f;這不僅關乎成本、性能和安全性&#xff0c;還涉及到技術架構、數據治理和長期戰…

Android 加殼應用運行流程 與 生命周期類處理方案

版權歸作者所有&#xff0c;如有轉發&#xff0c;請注明文章出處&#xff1a;https://cyrus-studio.github.io/blog/ DexClassLoader DexClassLoader 可以加載任意路徑下的 dex&#xff0c;或者 jar、apk、zip 文件&#xff08;包含classes.dex&#xff09;。常用于插件化、熱…