当前位置:

首页 > 编程开发 > 如何使用Java实现基于资金流向的交易策略?

如何使用Java实现基于资金流向的交易策略?

一、摘要价格不是上就是下,长期而言,价格的涨跌概率应各是50%,那么要正确预测未来的价格,就需要实时获取影响价格的全部因素,然后给每个因素一个正确权重,最后作出客观理性分析。要把影响价格的全部因素罗列出来,可能会写满整个屏幕。概括为:全球经济环境、国家宏观政策、相关产业政策、供需关系、国际事件、利率与汇率、通货膨胀与紧缩、市场心理、未知因素等等。预测也就变成了一个工程浩大,又不可能完成的任务。所以很早的时候,我就明白市场不可预测。那么在市场中所有的预测,都变成了假设,交易也成了概率游戏,这就有意思了。二、

本文目录
    一、摘要

    价格不是上就是下,长期而言,价格的涨跌概率应各是50%,那么要正确预测未来的价格,就需要实时获取影响价格的全部因素,然后给每个因素一个正确权重,最后作出客观理性分析。要把影响价格的全部因素罗列出来,可能会写满整个屏幕。

    概括为:全球经济环境、国家宏观政策、相关产业政策、供需关系、国际事件、利率与汇率、通货膨胀与紧缩、市场心理、未知因素等等。预测也就变成了一个工程浩大,又不可能完成的任务。所以很早的时候,我就明白市场不可预测。那么在市场中所有的预测,都变成了假设,交易也成了概率游戏,这就有意思了。

    二、为何利用资金流向

    既然市场无法预测,那真的就无动于衷了吗?不,所有的宏观因素和微观因素都已经反映到价格上了,也就是说价格是全部因素相互作用的结果。我们只需要分析价格,就可以做出一个完整的交易策略。 如何使用Java实现基于资金流向的交易策略?

    先仔细想一想,为什么价格会涨?

    你可能会说,因为:国家对相关产业政策扶持、原产地又双叒叕下暴雨了、国际贸易战、MACD金叉了、别人都买了等等,当然这些也许都没错。事后看,总能找出推动价格上涨的理由。

    其实,价格的涨跌类似于水涨船高。价格的上涨离不开资金的推动,盘面上,如果买的人多过卖的人,价格就会上涨。反之,如果卖的人多过买的人,价格就会下跌。有了这个概念,我们就可以根据资金净流向反映出来的供求关系,对未来价格的走势给出合理的预期。

    三、资金流向原理

    与传统分析不同的是,资金流向分析根据一段时间序列的交易数据中,分析哪些成交是资金主动流入的,哪些成交是资金主动流出。然后,把该时间段主动流入的成交量减去主动流出的成交量,便可以知道该时间段的资金净流入。如果资金净流入为正,表示该品种供不应求;如果资金净流出,则表示该品种供过于求。

    如何使用Java实现基于资金流向的交易策略?

    读到这里,可能有人会疑问,在实际交易中,有人买有人卖才会成交。成交的单子必然是有多少买量就有多少卖量,资金进出一定是等量的。何来资金流入流出呢?其实严格来说,每一个买单必然对应一个相应的卖单,资金流入和资金流出一定是相等的。如果我们想要计算出哪些成交的单子是主动性买入的,哪些单子是主动性卖出的,只能用一个折中的方法,利用bar数据,根据成交量和价格来实现。

    四、资金流向计算方法

    资金流向的变化准确对应着实时的市场行为,通过整合bar数据,实时计算资金净流向。关于计算资金主动性流向有两种算法:

    • 第一种,如果当前单子的成交价是以对手价或超价成交的,买入成交价 >= 卖一价,代表买家更愿意以较高的价格完成交易,即计入资金主动性流入。

    • 第二种,如果当前成交价格 > 上次成交价格,那么可以理解为,当前的成交量主动推升了价格的上涨,即计入资金主动性流入。

    如何使用Java实现基于资金流向的交易策略?

    以上述第二种算法为例:

    某个品种在 10:00 的收盘价是 3450,在 11:00 的收盘价是3455,那么我们就把 10:00 ~ 11:00 的成交量计入资金主动性流入。反之则计入资金主动性流出。而本文是在第二种方法的基础上,加入了价格波动幅度这个因素,通过前后bar收盘价对比,把上涨或下跌的bar的成交量 * 波动幅度计入到一个序列,然后根据该序列进一步计算资金的主动性流入比率。

    五、交易逻辑

    本文从“量”的角度来刻画期货市场的资金流向,通过实时分析bar数据,建立判断短期价格走向的交易模型。一般的情况下,资金流向及价格走势可以分为四种基本状况:

    • 价格上升,同时单位时间内资金主动性净流入:这种情况下属于强势,未来价格继续上升概率更大;

    • 股价上升,同时单位时间内资金主动性净流出:这种情况下属于中强势,未来价格继续上升的速度大幅减弱;

    • 股价下跌,同时单位时间内资金主动性净流入:这种情况下属于弱势,未来价格继续下跌概率更大;

    • 股价下跌,同时单位时间内资金主动性净流出:这种情况下属于中弱势,未来价格继续下跌的速度大幅减弱; 如何使用Java实现基于资金流向的交易策略?

    主要变量,如下:

    • 前期低点(ll)

    • 前期高点(hh)

    • 主动性买入(barIn)

    • 主动性卖出(barOut)

    • 主动流入资金与主动流出资金的比值(barRatio)

    • 开仓阈值(openValve)

    • 当前持仓(myAmount)

    • 上根K线收盘价(close)

    出入场条件 一个好的量化交易策略,不仅需要稳定的收益,而且能够控制风险,在小概率时间出现时,避免出现较大亏损。在这里我们使用跟踪主动性资金流向策略,借助短期价格预测对商品期货行情方向进行分析,从而达到高收益、低风险的效果。 策略的步骤如下图: 如何使用Java实现基于资金流向的交易策略?

    • 多头开仓:如果当前无持仓,并且barRatio > openValve,买入开仓;

    • 空头开仓:如果当前无持仓,并且barRatio < 1 / openValve,卖出开仓;

    • 多头平仓:如果当前持有多仓,并且close < ll,卖出平仓;

    • 空头平仓:如果当前持有空仓,并且close > hh,买入平仓;

    六、编写策略源码

    获取并计算数据

    function data() {
        var self = {};
        var barVol = [];
        var bars = _C(exchange.GetRecords); //获取bar数据
        if (bars.length < len * 2) { //控制bar数据数组的长度
            return;
        }
        for (var i = len; i > 0; i--) {
            var barSub_1 = bars[bars.length - (i + 1)].Close - bars[bars.length - (i + 2)].Close; //计算当前收盘价与上个bar收盘价的价差
            if (barSub_1 > 0) { //如果价格涨了,就在数组里面添加正数
                barVol.push(bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low));
            } else if (barSub_1 < 0) { //如果价格跌了,就在数组里面添加负数
                barVol.push(-bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low));
            }
        }
        if (barVol.length > len) {
            barVol.shift(); //释放多余的数据
        }
        self.barIn = 0;
        self.barOut = 0;
        for (var v = 0; v < barVol.length; v++) {
            if (barVol[v] > 0) {
                self.barIn += barVol[v]; //合并全部主动流入的资金
            } else {
                self.barOut -= barVol[v]; //合并全部主动流出的资金
            }
        }
        self.barRatio = self.barIn / Math.abs(self.barOut); //计算主动流入资金与主动流出资金的比值
        bars.pop(); //删除未结束的bar数据
        self.close = bars[bars.length - 1].Close; //获取上根K线的收盘价
        self.hh = TA.Highest(bars, hgLen, 'High'); //获取前高
        self.ll = TA.Lowest(bars, hgLen, 'Low'); //获取前低
        return self;
    }

    通过发明者量化API中的GetRecords方法,直接获取bar数据。包含最高价、最低价、开盘价、收盘价、成交量、标准时间戳。如果最新的成交价大于上次的成交价,那么就把最新的成交量 * (最高价 - 最低价)计入主动性买入;如果最新的成交价小于上次的成交价,那么就把最新的成交量 * (最高价 - 最低价)计入主动性卖出;

    获取持仓数据

    function positions(name) {
        var self = {};
        var mp = _C(exchange.GetPosition); //获取持仓
        if (mp.length == 0) {
            self.amount = 0;
        }
        for (var i = 0; i < mp.length; i++) { //持仓数据处理
            if (mp[i].ContractType == name) {
                if (mp[i].Type == PD_LONG || mp[i].Type == PD_LONG_YD) {
                    self.amount = mp[i].Amount;
                } else if (mp[i].Type == PD_SHORT || mp[i].Type == PD_SHORT_YD) {
                    self.amount = -mp[i].Amount;
                }
                self.profit = mp[i].Profit;
            } else {
                self.amount = 0;
            }
        }
        return self;
    }

    通过发明者量化API中的GetPosition方法获取基础持仓数据,并对这些基础数据进一步处理,如果当前持有多单,那么就返回正持仓数量;如果当前持有空单,那么就返回负持仓数量。这样做的目的是方便计算开平仓逻辑。

    下单交易

    function trade() {
        var myData = data(); //执行data函数
        if (!myData) {
            return;
        }
        var mp = positions(contractType); //获取持仓信息
        var myAmount = mp.amount; //获取持仓数量
        var myProfit = mp.profit; //获取持仓浮动盈亏
        if (myAmount > 0 && myData.close < myData.ll) {
            p.Cover(contractType, unit); //多头平仓
        }
        if (myAmount < 0 && myData.close > myData.hh) {
            p.Cover(contractType, unit); //空头平仓
        }
        if (myAmount == 0) {
            if (myData.barRatio > openValve) {
                p.OpenLong(contractType, unit); //多头开仓
            } else if (myData.barRatio < 1 / openValve) {
                p.OpenShort(contractType, unit); //空头开仓
            }
        }
    }
    七、策略特点

    特点:

    核心参数少:模型设计思路清晰,核心参数只有3个。可优化空间很小,可以有效避免过度拟合。 较强的普适性:策略逻辑简单,具有高普适性,除农产品外适应大部分品种,可以进行多品种组合。

    改进:

    加入持仓量条件:单向(股票)市场资金流向可以根据价格涨跌、成交量等因素来界定资金的流入或流出。 但是,由于该策略并没有加入持仓量这个条件,使得统计主动性资金流向可能会失真。

    加入标准差条件:仅仅依靠资金流向来作开仓条件,可能会出现频繁的虚假信号,造成频繁开平仓。通过统计指定时间内的资金净流出的平均值,上下加上标准差,来过滤虚假信号。

    完整策略源码:
    /*backtest
    start: 2016-01-01 09:00:00
    end: 2019-12-31 15:00:00
    period: 1h
    exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
    */
    
    var p = $.NewPositionManager(); //调用商品期货交易类库
    
    //持仓数据处理
    function positions(name) {
        var self = {};
        var mp = _C(exchange.GetPosition); //获取持仓
        if (mp.length == 0) {
            self.amount = 0;
        }
        for (var i = 0; i < mp.length; i++) { //持仓数据处理
            if (mp[i].ContractType == name) {
                if (mp[i].Type == PD_LONG || mp[i].Type == PD_LONG_YD) {
                    self.amount = mp[i].Amount;
                } else if (mp[i].Type == PD_SHORT || mp[i].Type == PD_SHORT_YD) {
                    self.amount = -mp[i].Amount;
                }
                self.profit = mp[i].Profit;
            } else {
                self.amount = 0;
            }
        }
        return self;
    }
    
    //行情数据处理函数
    function data() {
        var self = {};
        var barVol = [];
        var bars = _C(exchange.GetRecords); //获取bar数据
        if (bars.length < len * 2) { //控制bar数据数组的长度
            return;
        }
        for (var i = len; i > 0; i--) {
            var barSub_1 = bars[bars.length - (i + 1)].Close - bars[bars.length - (i + 2)].Close; //计算当前收盘价与上个bar收盘价的价差
            if (barSub_1 > 0) { //如果价格涨了,就在数组里面添加正数
                barVol.push(bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low));
            } else if (barSub_1 < 0) { //如果价格跌了,就在数组里面添加负数
                barVol.push(-bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low));
            }
        }
        if (barVol.length > len) {
            barVol.shift(); //释放多余的数据
        }
        self.barIn = 0;
        self.barOut = 0;
        for (var v = 0; v < barVol.length; v++) {
            if (barVol[v] > 0) {
                self.barIn += barVol[v]; //合并全部主动流入的资金
            } else {
                self.barOut -= barVol[v]; //合并全部主动流出的资金
            }
        }
        self.barRatio = self.barIn / Math.abs(self.barOut); //计算主动流入资金与主动流出资金的比值
        bars.pop(); //删除未结束的bar数据
        self.close = bars[bars.length - 1].Close; //获取上根K线的收盘价
        self.hh = TA.Highest(bars, hgLen, 'High'); //获取前高
        self.ll = TA.Lowest(bars, hgLen, 'Low'); //获取前低
        return self;
    }
    
    //交易函数
    function trade() {
        var myData = data(); //执行data函数
        if (!myData) {
            return;
        }
        var mp = positions(contractType); //获取持仓信息
        var myAmount = mp.amount; //获取持仓数量
        var myProfit = mp.profit; //获取持仓浮动盈亏
        if (myAmount > 0 && myData.close < myData.ll) {
            p.Cover(contractType, unit); //多头平仓
        }
        if (myAmount < 0 && myData.close > myData.hh) {
            p.Cover(contractType, unit); //空头平仓
        }
        if (myAmount == 0) {
            if (myData.barRatio > openValve) {
                p.OpenLong(contractType, unit); //多头开仓
            } else if (myData.barRatio < 1 / openValve) {
                p.OpenShort(contractType, unit); //空头开仓
            }
        }
    }
    
    //程序主入口,从这里启动
    function main() {
        while (true) { //进入循环
            if (exchange.IO("status")) { //如果是开市时间
                _C(exchange.SetContractType, contractType); //订阅合约
                trade(); //执行trade函数
            }
        }
    }
    八、策略回测

    策略配置: 如何使用Java实现基于资金流向的交易策略? 回测绩效: 如何使用Java实现基于资金流向的交易策略? 如何使用Java实现基于资金流向的交易策略?

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。