Yaser Abu-Mostafa在公开课说工程师,喝着咖啡等待机器运算出合理的结果,然后就完成了任务,坐等顾客付钱,这也是我写这篇文章以及代码的原因。
本文结构,暂时分为,三个部分
一,基础理论以及代码基础
二,机器学习在上的基础应用(Tensorflow + Python去做)
三,系统可靠性加固
代码在https://github.com/hzm1313/yc,代码冗余了其他一些东西,后面会用JAVA9的模块特性把模块给分出来,火币网的接口封装了WS,和restful,杠杆未封装
平台选择为火币网,说起来是因为以前火币网不用翻墙,可惜现在也要翻了,所以翻墙是必备的,可以用SSTAP去连接SSR结点,会将TCP,UDP连接也进行转发,原生的用IDEA调试总是有问题
点击我去搭建SSR <https://blog.csdn.net/dodan/article/details/78314652>
SSTAP下载链接,已经不维护了,可以自己选其他的
<https://www.sockscap64.com/sstap-enjoy-gaming-enjoy-sstap/>
量化交易定义
根据深圳交易所对量化交易的研究可知,量化交易是指投资者利用计算机技术、金融工程建模等手段将自己的金融操作方式,用很明确的方式去定义和描述,用以协助投资者进行投资决策,并且严格的按照所设定的规则去执行交易策略(买、卖)的交易方式。按照数学模型的理念和对计算机技术的利用方式,量化交易方式可以进一步细分为
自动化交易(Automatic Trading)、数量化投资(Quantitative Investment)、程序化交易(Program
Trading)、算法交易(Algorithm Trading)、以及高频交易(High Frequency Trading)
自动化交易
指将技术分析投资方式固化成计算机可以理解的模型、技术指标,计算机程序根据市场变化自动生成投资决策并付诸执行的交易方式。简而言之,自动化交易是技术分析投资方式的自动化。自动化交易可以避免投资人的心理变化和情绪波动,严格执行既定策略,是最基本的量化交易方式,在外汇交易和期货交易领域应用很广。
程序化交易
是从美国七十年代的证券市场上的系统化交易发展演变而来的,是伴随着股指期货与现货市场套利交易而兴起的数量化交易方式。纽约证券交易所(NYSE)把程序化交易定义为:Program
trading encompasses a wide range of portfolio-trading strategies involving the
purchase or sale of a basket of at least 15 stocks with a total value of $1
million or
more.即任何含有标普500指数15只股票以上,其价值100万美元以上的交易,属于程序化交易。纽约证券交易所的定义主要突出的是交易规模和集中性。程序化交易发展到今天,其含义已经远远超过了纽约证券交易所当初的定义。国泰君安证券对程序化交易给出了一个更为市场化的定义:根据一定的交易规模和规则生成买卖信号,由计算机自动执行买卖指令的交易过程。简单的说,就是利用计算机程序来控制买进卖出的事迹并自动执行。在这个定义中,突出的是交易模型、计算机程序对交易的重要性。随着量化技术的深入发展,程序化交易和算法交易的界限逐渐模糊,有些市场使用高频交易描述流行的量化交易方式。
高频交易
源于程序化交易和做市商机制,是指透过极高速的超级电脑分析高频交易数据中的价格变化模式,并且利用这些价格变化模式获利,通常高频交易利用服务器的地理位置优势(Co-location),在相对更快的时间内获得市场行情和执行大量交易指令,从而取得普通交易方式难以获得的利润空间。近年来,除了信息技术是的交易速度不断加快之外,交易平台日趋多元化也使得高频交易成为可能。
数量化交易
通过研究基本面去做,做爬虫爬信息去做
算法交易
更好的价格买入,因为你作为资金量较大的用户,买入,市场印象较大
算法交易,数量化交易(研究基本面)我研究不多,因为概念上对于大多数人并不是一个很优秀的实施概念,所以就不展开了,要是有什么好的文章或者思路也可以分享给我,感谢
自动化交易,高频交易,程序化交易是在本系统构建范围之内
代码构建思路
现在我写了2个策略
策略A,1分钟线上下跌30次,买入,上涨或者下跌0.005%卖出
策略B,网格策略,上涨5%,10%,15%,分别买入总价的30%,30%,40%,下跌反之,基准价,我开上帝模式,选了要给比较好的基准价
这是自动化交易
策略A进一步,1分钟下跌(N)次,选择一个比较优秀的下跌次数以及回测范围,去回测,动态的生成策略
策略B进一步,网格策略,上涨N%,买入总量/当前量的N%,去回测,动态生成优秀的策略
高频交易
比如说现在币安,火币网,币安下跌,火币网上涨,这个时候我拥有火币网的币,是否卖出,当然卖,为什么?因为根据历史回测来看,币安作为全球第二的市场,反应币火币网快。也可以参考CEX,这种可以对冲的市场,现在有自动搬砖的软件了,我也就重点实现了
火币网API,实现有RESTFUL,和websocket2种类型,websocket接口有行情接口,restful接口有行情和交易接口,但是restful行情接口有不好的地方,速度和历史数据没有websocket的久远
基于上面2个策略,我做了回测,效果都不是很好,因为现在我选取之前的时间段是单边下跌时间,所以回测结果基本上都是亏损,下面是代码代码放在我的GIT
<https://github.com/hzm1313/yc>
@Test public void baseStrategy() { //策略1
//连续下跌30分钟线,买入,直到,高于成本价0.5%,卖出,否则一直持有,手续费为0.4%,如果下跌超过1%,,无条件卖出 //读取数据 /*
List<HuobiDetailVO> huobiDetailVOList =
HuoBiApiUtils.importToFile("E:\\虚拟货币\\测试数据\\test_1min.xlsx");*/
List<List<String>> lists = ExceUtil.importFile(new
File("E:\\虚拟货币\\测试数据\\test.xlsx")); if (false) { List<Map<String, String>>
mapList = new ArrayList<>(); for (int fallTraigger = 1; fallTraigger < 30;
fallTraigger++) { //1W刀本金 BigDecimal amount = new BigDecimal("10000");
BigDecimal holdPrice = new BigDecimal("0"); BigDecimal holdNum = new
BigDecimal("0"); BigDecimal basePrice = new BigDecimal(lists.get(1).get(3));
BigDecimal open = new BigDecimal(lists.get(1).get(2)); BigDecimal close = new
BigDecimal(lists.get(1).get(3)); BigDecimal high = new
BigDecimal(lists.get(1).get(4)); BigDecimal low = new
BigDecimal(lists.get(1).get(5)); //触发的卖出价格 BigDecimal sellLowPrice = new
BigDecimal(lists.get(1).get(3)).multiply(new BigDecimal("0.99")); BigDecimal
sellHighPrice = new BigDecimal(lists.get(1).get(3)).multiply(new
BigDecimal("1.005")); int falNum = 0; for (int i = 2; i < lists.size(); i++) {
open = new BigDecimal(lists.get(i).get(2)); close = new
BigDecimal(lists.get(i).get(3)); high = new BigDecimal(lists.get(i).get(4));
low = new BigDecimal(lists.get(i).get(5)); if (holdNum.compareTo(new
BigDecimal("0")) == 0) { //持有本金,买入等待状态 if (close.compareTo(basePrice) < 0) {
falNum++; } else { falNum = 0; } if (falNum >= fallTraigger) { //买入手续费 amount =
amount.multiply(new BigDecimal("0.998")); holdPrice = close; holdNum =
amount.divide(holdPrice, 10, BigDecimal.ROUND_DOWN); amount = new
BigDecimal("0"); //System.out.println("买入价:" + holdPrice + " 买入数量:" + holdNum +
" 总价值:" + holdNum.multiply(holdPrice) + " 剩余钱:" + amount.toString());
sellLowPrice = new BigDecimal(lists.get(i).get(3)).multiply(new
BigDecimal("0.994")); sellHighPrice = new
BigDecimal(lists.get(i).get(3)).multiply(new BigDecimal("1.006")); falNum = 0;
} } else { //持有币,卖出等待状态\ //低于1.05卖出 if (close.compareTo(sellLowPrice) < 0 ||
close.compareTo(sellHighPrice) > 0) { holdPrice = close; amount =
holdNum.multiply(holdPrice).multiply(new BigDecimal("0.998"));
//System.out.println("卖出价:" + holdPrice + " 买出数量:" + holdNum +" 税后钱:"+amount);
holdNum = new BigDecimal("0"); } } basePrice = close; } if
(holdNum.compareTo(new BigDecimal("0")) > 0) { //强行卖出 amount =
holdNum.multiply(holdPrice).multiply(new BigDecimal("0.998")); }
System.out.println("fallTraigger:" + fallTraigger + " resultPrice:" +
amount.toString()); Map map = new HashMap<String, String>();
map.put("fallTraigger", fallTraigger); map.put("resultPrice",
amount.toString()); mapList.add(map); } mapList.sort((o1, o2) ->
o1.get("resultPrice").compareTo(o1.get("resultPrice"))); mapList.forEach(obj ->
{ System.out.println(String.valueOf(obj.get("fallTraigger")) + "===" +
obj.get("resultPrice")); }); } //策略2,网格策略
//为了拿一个好看的回测结果,我就上帝模式来一波,数据是自己去取的一个平均值
//步长5%,上涨5%,卖出30%,上涨10%,卖出30%,上涨15%,卖出40%, //下跌同理,简化了很多东西 for(int
stepType=1;stepType<4;stepType++){ BigDecimal stepLength = new
BigDecimal("0.5").multiply(new BigDecimal(stepType)); BigDecimal basePrice =
new BigDecimal("8000.5243315970"); //1W刀本金 BigDecimal amount = new
BigDecimal("10000"); BigDecimal holdNum = new BigDecimal("0"); BigDecimal
tradePrice = new BigDecimal("0"); BigDecimal close = new
BigDecimal(lists.get(1).get(3)); BigDecimal percent3 = new BigDecimal("0.30");
BigDecimal percent4 = new BigDecimal("0.40"); BigDecimal opPrice = null;
ReseauStratge trade[] = {new ReseauStratge(amount.multiply(percent3)),new
ReseauStratge(amount.multiply(percent3)),new
ReseauStratge(amount.multiply(percent4))}; for (int perIndex = 2; perIndex <
lists.size(); perIndex++) { close = new BigDecimal(lists.get(perIndex).get(3));
//买入/卖出 //对于每个阶段的资金来说,只有,买入,卖出2种状态 for(int
buyPercentNum=0;buyPercentNum<trade.length;buyPercentNum++){ opPrice = new
BigDecimal(basePrice.toString()); BigDecimal step = new BigDecimal("1.00");
if(trade[buyPercentNum].getCanBuy()) { //买入 for(int muNum = 1;
muNum<=buyPercentNum+1;muNum++){ step =
step.divide(stepLength,10,BigDecimal.ROUND_FLOOR); } opPrice =
opPrice.multiply(step); if(close.compareTo(opPrice)<=0) {
trade[buyPercentNum].setTradePrice(close); trade[buyPercentNum].setTradeNum(new
BigDecimal(trade[buyPercentNum].getHoldAmount().divide(close,10,BigDecimal.ROUND_FLOOR).toString()));
trade[buyPercentNum].setHoldNum(trade[buyPercentNum].getTradeNum());
trade[buyPercentNum].setTradeAmount(trade[buyPercentNum].getTradeNum().multiply(trade[buyPercentNum].getTradePrice()));
trade[buyPercentNum].setHoldAmount(trade[buyPercentNum].getHoldAmount().subtract(trade[buyPercentNum].getTradeAmount()));
trade[buyPercentNum].setCanBuy(false); holdNum =
holdNum.add(trade[buyPercentNum].getHoldNum()); amount =
amount.subtract(trade[buyPercentNum].getTradeAmount()); //
System.out.println("买入"+"holdNum:" + holdNum + " resultPrice:" +
amount.toString()+"总价值" + amount.add(holdNum.multiply(close))); } } else { //卖出
for(int muNum = 1; muNum<=buyPercentNum+1;muNum++){ step =
step.subtract(stepLength); } opPrice = opPrice.multiply(step);
if(close.compareTo(opPrice) >= 0) { trade[buyPercentNum].setTradePrice(close);
trade[buyPercentNum].setTradeAmount(trade[buyPercentNum].getHoldNum().multiply(trade[buyPercentNum].getTradePrice()));
trade[buyPercentNum].setHoldAmount(trade[buyPercentNum].getHoldAmount().add(trade[buyPercentNum].getTradeAmount()));
trade[buyPercentNum].setTradeNum(trade[buyPercentNum].getHoldNum());
trade[buyPercentNum].setHoldNum(new BigDecimal("0"));
trade[buyPercentNum].setCanBuy(true); amount =
amount.add(trade[buyPercentNum].getTradeAmount()); holdNum =
holdNum.subtract(trade[buyPercentNum].getTradeNum()); //
System.out.println("卖出"+"holdNum:" + holdNum + " resultPrice:" +
amount.toString()+"总价值" + amount.add(holdNum.multiply(close))); } } } }
System.out.println("holdNum:" + holdNum + " resultPrice:" + amount.toString()
+"总价值" + amount.add(holdNum.multiply(close))); } }
这就是交易的基础模型,价值还是有价值的,毕竟还是挣钱的,挣的特别少,1W刀,100刀-700刀,幅度太坑,2个月的回测,17年12月到18年的2月
holdNum:0E-10
resultPrice:10746.2908951017280000000000000000总价值10746.2908951017280000000000000000
holdNum:0E-10
resultPrice:10548.5590028459460000000000000000总价值10548.5590028459460000000000000000
holdNum:0E-10
resultPrice:10139.7957370829220000000000000000总价值10139.7957370829220000000000000000
能不能挣钱,就看steplength以及basePrice的设置
现在是定死的价格,所以如果做无限动态的化,可以考虑每天/每小时/重新设置basePrice,看自己的需求
这是2种基础的交易模型
然后这个时候需要引出风控了,因为在回测的时候,模型成功率在某段时间不高的时候,所以需要终止模型的运转,发出邮件通知自己
高频交易
(BitMex/Biance)与火币做对比
----代码暂时未写,不想爬虫,不想封接口了,都TM苦力活,要吐了,后面补进来---
交易模型已经构造完毕
交易系统,稳定,快速,易更改,可监控(其实redis一套可以弄完,不过是为了学习,会采取自己接触比较少的东西去做)
监控选用 Promethus,然后拉取数据,做可视化
稳定:代码看自己了
快速:并发的走起
更改:数据库配置的走起,然后RabbitMQ做消息队列推
存储: redis持久化搞
现在很多海外服务,所以用spring cloud,搭建微服务,做服务调用
java + python交互,做机器学习模型结果的交互
这是我整个系统的构造思路,代码会在git里面也会一步一步OVER掉所有需求
热门工具 换一换