网赚论坛

 找回密码
 免费注册
查看: 371|回复: 0
打印 上一主题 下一主题

带你进入量化世界之-----MACD双向操作滑动止损代码分析

[复制链接]

14

主题

277

帖子

50

积分

Ⅰ级财主

Rank: 1

积分
50
跳转到指定楼层
楼主
发表于 2018-1-13 15:47:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
上一篇文章中我们大家领略了?30行代码的精简量化策略,本篇中作者将一步一步带领量化初学者更近一步地去发掘量化策略设计的乐趣。
正文继续,本次依然是用BTC的现货交易讲解,作者之前在金融、投资、证券等方面也完全是小白一枚。甚至都搞不懂期货的交易流程,
更是被眼花缭乱、听所未闻的名词、术语搞的头昏脑涨,(其实现在也是略懂!略懂!)。通过自己百度、查资料等一一补脑。
查阅了相关内容,心中有了基本的概念,结合自己略懂的JS语言,简单写了一个。最初不懂什么是K线、均线、MACD指标。
在这里简单说下,K线是记录一定周期内的市场行情,便于观察市场动态。均线是上一篇文章用到的指标,和MACD指标一样,都是反映市场行情趋势的指标。
这2种指标的概念、算法、公式推导等就不一一赘述了。不明白的请查百度。(我就是在百度看的!)

代码中有以下全局变量,老规矩,先一一解释,老鸟可忽略。[td]
变量名初始值说明
Interval2000这个变量是轮询周期,就是程序暂停等待的时间量,单位是毫秒,1000毫秒为1秒,所以这个变量初始值为2秒。
STATE_FREE0这个是一个表示状态的变量,表示空闲。用于状态判断。
STATE_BUY1这个是一个表示状态的变量,表示多头持仓。 就是 买开仓。
STATE_SELL2状态变量,表示空头持仓。 就是卖开仓。
ORDER_INVALID3持仓状态变量,表示未持仓。
ORDER_VALID4表示持仓中…
stateSTATE_FREE状态变量,用空闲状态初始化。
SignalDelay0最初计划 信号延迟,暂时无用。
stopProfit0.002这个变量比较重要,止损率, 比如 本金 * 止损率(0.002) 表示 最多赔 本金的0.002倍,损失上限。
step0.5滑动止损的步长值。用于提升、下调 止损价的等级。
opAmount1固定的操作量。
profit0盈亏。

  • //经验1、 对象赋值 当对象 含有 成员函数时 以下赋值会有问题
  • /*
  • holdOrder = {
  • orderState: ORDER_VALID,
  • price: buyInfo.price,
  • amount: buyInfo.amount,
  • time: getTimeByNormal((new Date()).getTime()),
  • };
  • //应当这样赋值:
  • holdOrder.orderState = ORDER_VALID;
  • holdOrder.price = buyInfo.price;
  • holdOrder.amount = buyInfo.amount;
  • holdOrder.time = getTimeByNormal((new Date()).getTime());

  • */

  • function MACD_Cross(){
  • var records = exchange.GetRecords();
  • while(!records || records.length < 45){
  • records = exchange.GetRecords();
  • Sleep(Interval);
  • }
  • var macd = TA.MACD(records,12,26,9);
  • var dif = macd[0];
  • var dea = macd[1];
  • var column = macd[2];
  • var len = records.length;
  • if( (dif[len-1] > 0 && dea[len-1] > 0) && dif[len-1] > dea[len-1] && dif[len-2] < dea[len-2] && column[len-1] > 0.08 ){
  • return 1;
  • }
  • if( (dif[len-1] < 0 && dea[len-1] < 0) && dif[len-1] < dea[len-1] && dif[len-2] > dea[len-2] ){
  • return 2;
  • }
  • return 0;
  • }
  • var Interval = 500;
  • var STATE_FREE = 0;
  • var STATE_BUY = 1;
  • var STATE_SELL = 2;
  • var ORDER_INVALID = 3;
  • var ORDER_VALID = 4;
  • var state = STATE_FREE;
  • var SignalDelay = 0;
  • var stopProfit = 0.002;
  • var step = 0.5;
  • var opAmount = 1;
  • var profit = 0;
  • var holdOrder = {
  • orderState: ORDER_INVALID,
  • price: 0,
  • amount: 0,
  • time: null,
  • stopPrice: 0,
  • level: 1,
  • updateCurrentProfit: function(lastPrice,amount){
  • if(state === STATE_SELL){
  • return (lastPrice - this.price) * amount;
  • }
  • if(state === STATE_BUY){
  • return - (lastPrice - this.price) * amount;
  • }
  • },
  • SetStopPrice: function(ticker,stopState){
  • if(stopState === STATE_FREE){
  • return this.stopPrice;
  • }
  • if(stopState === STATE_BUY){
  • if(this.orderState === ORDER_INVALID){
  • return this.stopPrice;
  • }

  • if(this.stopPrice === 0){
  • this.stopPrice = this.price * ( 1 - stopProfit );
  • }
  • if( ticker.Last  this.level * step ){
  • this.stopPrice = this.price * (1 - stopProfit) + (ticker.Last - this.price );
  • this.level++;
  • }else{
  • this.stopPrice = this.stopPrice;
  • }
  • }
  • }else if( stopState === STATE_SELL){
  • if(this.orderState === ORDER_INVALID){
  • return this.stopPrice;
  • }

  • if(this.stopPrice === 0){
  • this.stopPrice = this.price * ( 1 + stopProfit );
  • }
  • if( ticker.Last >= this.price ){
  • this.stopPrice = this.price * ( 1 + stopProfit );
  • this.level = 1;
  • }else{
  • if( this.price - ticker.Last > this.level * step ){
  • this.stopPrice = this.price * (1 + stopProfit) - ( this.price - ticker.Last );
  • this.level++;
  • }else{
  • this.stopPrice = this.stopPrice;
  • }
  • }
  • }

  • return this.stopPrice;
  • },
  • initHoldOrder: function(){
  • this.orderState = ORDER_INVALID;
  • this.price = 0;
  • this.amount = 0;
  • this.time = null;
  • this.stopPrice = 0;
  • this.level = 1;
  • }
  • };

  • function scan(){
  • var sellInfo = null;
  • var buyInfo = null;
  • var opFun = null;
  • var singal = 0;
  • while(true){
  • var ticker = exchange.GetTicker();
  • if(!ticker){
  • continue;
  • }
  • holdOrder.SetStopPrice(ticker,state);
  • if(state === STATE_FREE && (singal = MACD_Cross()) !== 0 ){
  • holdOrder.initHoldOrder();
  • opFun = singal === 1 ? $.Buy : $.Sell ;
  • buyInfo = opFun(opAmount);

  • holdOrder.orderState = ORDER_VALID;
  • holdOrder.price = buyInfo.price;
  • holdOrder.amount = buyInfo.amount;
  • holdOrder.time = $.getTimeByNormal((new Date()).getTime());

  • state = singal === 1 ? STATE_BUY : STATE_SELL;
  • var account = $.GetAccount(exchange);
  • if(singal === 1){
  • Log("开多仓。","账户:",account);
  • }else{
  • Log("开空仓。","账户:",account);
  • }
  • break;
  • }else{
  • var lastPrice = holdOrder.price;
  • if( state === STATE_BUY && holdOrder.orderState === ORDER_VALID && ticker.Last < holdOrder.stopPrice ){
  • Log("多头止损平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
  • sellInfo = $.Sell(holdOrder.amount);

  • holdOrder.orderState = ORDER_INVALID;
  • holdOrder.price = sellInfo.price;
  • holdOrder.amount = sellInfo.amount;
  • holdOrder.time = $.getTimeByNormal((new Date()).getTime());

  • profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
  • state = STATE_FREE;
  • break;
  • }
  • if( state === STATE_SELL && holdOrder.orderState === ORDER_VALID && ticker.Last > holdOrder.stopPrice ){
  • Log("空头止损平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
  • sellInfo = $.Buy(holdOrder.amount);

  • holdOrder.orderState = ORDER_INVALID;
  • holdOrder.price = sellInfo.price;
  • holdOrder.amount = sellInfo.amount;
  • holdOrder.time = $.getTimeByNormal((new Date()).getTime());

  • profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
  • state = STATE_FREE;
  • break;
  • }
  • if(state === STATE_BUY && MACD_Cross() === 2 ){
  • sellInfo = $.Sell(holdOrder.amount);
  • Log("死叉平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试

  • holdOrder.orderState = ORDER_INVALID;
  • holdOrder.price = sellInfo.price;
  • holdOrder.amount = sellInfo.amount;
  • holdOrder.time = $.getTimeByNormal((new Date()).getTime());

  • profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
  • state = STATE_FREE;
  • break;
  • }
  • if(state === STATE_SELL && MACD_Cross() === 1 ){
  • sellInfo = $.Buy(holdOrder.amount);
  • Log("金叉平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试

  • holdOrder.orderState = ORDER_INVALID;
  • holdOrder.price = sellInfo.price;
  • holdOrder.amount = sellInfo.amount;
  • holdOrder.time = $.getTimeByNormal((new Date()).getTime());

  • profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
  • state = STATE_FREE;
  • break;
  • }
  • }
  • Sleep(Interval);
  • }
  • }

  • function main(){
  • var initAccount = $.GetAccount(exchange);
  • var nowAccount = initAccount;
  • var diffMoney = 0;
  • var diffStocks = 0;
  • var repair = 0;
  • var ticker = exchange.GetTicker();
  • Log("初始账户:",initAccount);
  • while(true){
  • scan();
  • ticker = exchange.GetTicker();
  • if(!ticker){
  • continue;
  • }
  • if(holdOrder.orderState == ORDER_VALID){
  • Log("当前持仓:",holdOrder);
  • }
  • if(holdOrder.orderState == ORDER_INVALID){
  • nowAccount = $.GetAccount(exchange);
  • diffMoney = nowAccount.Balance - initAccount.Balance;
  • diffStocks = nowAccount.Stocks - initAccount.Stocks;
  • repair = diffStocks * ticker.Last;
  • LogProfit(diffMoney + repair ,"RMB","现在账户:",nowAccount,"本次盈亏:",profit);
  • }
  • Sleep(Interval);
  • }}

复制代码


代码看累了,喝口水歇歇~流程图直观些~上图!
先说说关于滑动止损的原理。图片右边,再大致看下 程序执行流程。


大家可以先跑跑回测实验一下,记得要引用“数字货币交易类库”这个模板!另外写的简陋欢迎指正、修改。
代码纯属学习、交流使用,实盘慎用!
参考资料



  • 策略源码
  • github上的代码库BotVS的代码广场
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

广告合作|Archiver|手机版|小黑屋|财富吧

GMT+8, 2026-7-18 20:58 , Processed in 0.546000 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.1

© 2014-2021 财富吧

快速回复 返回顶部 返回列表