python实现马丁策略的实例详解


Posted in Python onJanuary 15, 2021

马丁策略本来是一种赌博方法,但在投资界应用也很广泛,不过对于投资者来说马丁策略过于简单,所以本文将其改进并使得其在震荡市中获利,以下说明如何实现马丁策略。

策略

逢跌加仓,间隔由自己决定,每次加仓是当前仓位的一倍。
连续跌两次卖出,且卖出一半仓位。
如果爆仓则全仓卖出止损。
初始持仓设置为10%~25%,则可进行2到3次补仓。

初始化马丁策略类属性

def __init__(self,startcash, start, end):
 self.cash = startcash #初始化现金
 self.hold = 0 #初始化持仓金额
 self.holdper = self.hold /startcash #初始化仓位
 self.log = [] #初始化日志
 self.cost = 0 #成本价 
 self.stock_num = 0 #股票数量
 self.starttime = start #起始时间
 self.endtime = end #终止时间
 self.quantlog = [] #交易量记录
 self.earn = [] #总资产记录
 self.num_log = []
 self.droplog = [0]

为了记录每次买卖仓位的变化初始化了各种列表。

交易函数

首先导入需要的模块

import pandas as pd 
import numpy as np
import tushare as ts 
import matplotlib.pyplot as plt
def buy(self, currentprice, count):

 self.cash -= currentprice*count
 self.log.append('buy')
 self.hold += currentprice*count
 self.holdper = self.hold / (self.cash+ self.hold) 
 self.stock_num += count
 self.cost = self.hold / self.stock_num
 self.quantlog.append(count//100)
 print('买入价:%.2f,手数:%d,现在成本价:%.2f,现在持仓:%.2f,现在筹码:%d' %(currentprice ,count//100, self.cost, self.holdper, self.stock_num//100))
 self.earn.append(self.cash+ currentprice*self.stock_num)
 self.num_log.append(self.stock_num)
 self.droplog = [0]
 
 def sell(self, currentprice, count):
 self.cash += currentprice*count
 self.stock_num -= count
 self.log.append('sell')
 self.hold = self.stock_num*self.cost
 self.holdper = self.hold / (self.cash + self.hold)
 #self.cost = self.hold / self.stock_num
 print('卖出价:%.2f,手数:%d,现在成本价:%.2f,现在持仓:%.2f,现在筹码:%d' %(currentprice ,count//100, self.cost, self.holdper, self.stock_num//100))
 self.quantlog.append(count//100)    
 self.earn.append(self.cash+ currentprice*self.stock_num)
 self.num_log.append(self.stock_num)
 
 def holdstock(self,currentprice):
 self.log.append('hold')
 #print('持有,现在仓位为:%.2f。现在成本:%.2f' %(self.holdper,self.cost))
 self.quantlog.append(0)
 self.earn.append(self.cash+ currentprice*self.stock_num)
 self.num_log.append(self.stock_num)

持仓成本的计算方式是利用总持仓金额除以总手数,卖出时不改变持仓成本。持有则是不做任何操作只记录日志

数据接口

def get_stock(self, code):
 df=ts.get_k_data(code,autype='qfq',start= self.starttime ,end= self.endtime)
 df.index=pd.to_datetime(df.date)
 df=df[['open','high','low','close','volume']]
 return df

数据接口使用tushare,也可使用pro接口,到官网注册领取token。

token = '输入你的token'
pro = ts.pro_api()
ts.set_token(token)
 def get_stock_pro(self, code):
 code = code + '.SH'
 df = pro.daily(ts_code= code, start_date = self.starttime, end_date= self.endtime)
 return df

数据结构:

python实现马丁策略的实例详解

回测函数

def startback(self, data, everyChange, accDropday):
 """
 回测函数
 """
 for i in range(len(data)):
  if i < 1:
  continue
  if i < accDropday:
  drop = backtesting.accumulateVar(everyChange, i, i)
  #print('现在累计涨跌幅度为:%.2f'%(drop))
  self.martin(data[i], data[i-1], drop, everyChange,i)
  elif i < len(data)-2:
  drop = backtesting.accumulateVar(everyChange, i, accDropday)
  #print('现在累计涨跌幅度为:%.2f'%(drop))
  self.martin(data[i],data[i-1], drop, everyChange,i)
  else:
  if self.stock_num > 0:
   self.sell(data[-1],self.stock_num)
  else: self.holdstock(data[i])

因为要计算每日涨跌幅,要计算差分,所以第一天的数据不能计算在for循环中跳过,accDropday是累计跌幅的最大计算天数,用来控制入场,当累计跌幅大于某个数值且仓位为0%时可再次入场。以下是入场函数:

def enter(self, currentprice,ex_price,accuDrop):
 if accuDrop < -0.01:#and ex_price > currentprice:
  count = (self.cash+self.hold) *0.24 // currentprice //100 * 100
  print('再次入场')
  self.buy(currentprice, count)
 else: self.holdstock(currentprice)

入场仓位选择0.24则可进行两次抄底,如果抄底间隔为7%可承受最大跌幅为14%。

策略函数

def martin(self, currentprice, ex_price, accuDrop,everyChange,i):
 diff = (ex_price - currentprice)/ex_price
 self.droplog.append(diff)

 if sum(self.droplog) <= 0:
  self.droplog = [0]
 
 if self.stock_num//100 > 1:
  if sum(self.droplog) >= 0.04:
  if self.holdper*2 < 0.24:
   count =(self.cash+self.hold) *(0.25-self.holdper) // currentprice //100 * 100
   self.buy(currentprice, count)
  elif self.holdper*2 < 1 and (self.hold/currentprice)//100 *100 > 0 and backtesting.computeCon(self.log) < 5:
   self.buy(currentprice, (self.hold/currentprice)//100 *100)
   
  else: self.sell(currentprice, self.stock_num//100 *100);print('及时止损')

  elif (everyChange[i-2] < 0 and everyChange[i-1] <0 and self.cost < currentprice):# or (everyChange[i-1] < -0.04 and self.cost < currentprice):
   
  if (self.stock_num > 0) and ((self.stock_num*(1/2)//100*100) > 0):
   
   self.sell(currentprice, self.stock_num*(1/2)//100*100 )

   #print("现在累计涨跌幅为: %.3f" %(accuDrop))
  elif self.stock_num == 100: self.sell(currentprice, 100)
  else: self.holdstock(currentprice)
  else: self.holdstock(currentprice)
 else: self.enter(currentprice,ex_price,accuDrop)

首先构建了droplog专门用于计算累计涨跌幅,当其大于0时重置为0,每次购买后也将其重置为0。当跌幅大于0.04则买入,一下为流程图(因为作图软件Visustin为试用版所以有水印,两个图可以结合来看):

python实现马丁策略的实例详解
python实现马丁策略的实例详解

此策略函数可以改成其他策略甚至是反马丁,因为交易函数可以通用。

作图和输出结果

buylog = pd.Series(broker.log)
close = data.copy()
buy = np.zeros(len(close))
sell = np.zeros(len(close))
for i in range(len(buylog)):
 if buylog[i] == 'buy':
 buy[i] = close[i]
 elif buylog[i] == 'sell':
 sell[i] = close[i]

buy = pd.Series(buy)
sell = pd.Series(sell)
buy.index = close.index
sell.index = close.index
quantlog = pd.Series(broker.quantlog)
quantlog.index = close.index
earn = pd.Series(broker.earn)
earn.index = close.index

buy = buy.loc[buy > 0]
sell = sell.loc[sell>0]
plt.plot(close)
plt.scatter(buy.index,buy,label = 'buy')
plt.scatter(sell.index,sell, label = 'sell')
plt.title('马丁策略')
plt.legend()

#画图
plt.rcParams['font.sans-serif'] = ['SimHei']

fig, (ax1, ax2, ax3) = plt.subplots(3,figsize=(15,8))

ax1.plot(close)
ax1.scatter(buy.index,buy,label = 'buy',color = 'red')
ax1.scatter(sell.index,sell, label = 'sell',color = 'green')
ax1.set_ylabel('Price')
ax1.grid(True)
ax1.legend()

ax1.xaxis_date()
ax2.bar(quantlog.index, quantlog, width = 5)
ax2.set_ylabel('Volume')

ax2.xaxis_date()
ax2.grid(True)
ax3.xaxis_date()
ax3.plot(earn)
ax3.set_ylabel('总资产包括浮盈')
plt.show()

python实现马丁策略的实例详解

python实现马丁策略的实例详解

交易日志

到此这篇关于python实现马丁策略的实例详解的文章就介绍到这了,更多相关python马丁策略内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python实现文件名批量替换和内容替换
Mar 20 Python
Python自动登录126邮箱的方法
Jul 10 Python
Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】
Jun 07 Python
一条命令解决mac版本python IDLE不能输入中文问题
May 15 Python
Python装饰器用法实例总结
May 26 Python
python爬虫之线程池和进程池功能与用法详解
Aug 02 Python
Python3 log10()函数简单用法
Feb 19 Python
Python随机数函数代码实例解析
Feb 09 Python
Python如何通过百度翻译API实现翻译功能
Apr 02 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
Oct 15 Python
学会迭代器设计模式,帮你大幅提升python性能
Jan 03 Python
教你如何用python开发一款数字推盘小游戏
Apr 14 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 #Python
基于Python的接口自动化读写excel文件的方法
Jan 15 #Python
PyCharm 解决找不到新打开项目的窗口问题
Jan 15 #Python
python爬取微博评论的实例讲解
Jan 15 #Python
pycharm 复制代码出现空格的解决方式
Jan 15 #Python
pycharm 实现复制一行的快捷键
Jan 15 #Python
pycharm 快速解决python代码冲突的问题
Jan 15 #Python
You might like
PHP网页游戏学习之Xnova(ogame)源码解读(十一)
2014/06/25 PHP
javascript mouseover、mouseout停止事件冒泡的解决方案
2009/04/07 Javascript
jquery 常用操作整理 基础入门篇
2009/10/14 Javascript
jquery中的sortable排序之后的保存状态的解决方法
2010/01/28 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
js函数中onmousedown和onclick的区别和联系探讨
2013/05/19 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
jquery delay()介绍及使用指南
2014/09/02 Javascript
原生js实现移动开发轮播图、相册滑动特效
2015/04/17 Javascript
javascript拖拽效果延伸学习
2016/04/04 Javascript
深入浅析knockout源码分析之订阅
2016/07/12 Javascript
JS 60秒后重新发送验证码的实例讲解
2017/07/26 Javascript
解决vue项目报错webpackJsonp is not defined问题
2018/03/14 Javascript
Vue SPA单页应用首屏优化实践
2018/06/28 Javascript
IE浏览器下JS脚本提交表单后,不能自动提示问题解决方法
2019/06/04 Javascript
Python os模块介绍
2014/11/30 Python
Python的爬虫框架scrapy用21行代码写一个爬虫
2017/04/24 Python
python 并发编程 非阻塞IO模型原理解析
2019/08/20 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
tensorflow之tf.record实现存浮点数数组
2020/02/17 Python
Numpy中ndim、shape、dtype、astype的用法详解
2020/06/14 Python
New Balance法国官方网站:购买鞋子和服装
2019/09/01 全球购物
向全球直邮输送天然健康产品:iHerb.com
2020/05/03 全球购物
北京天润融通.net面试题笔试题
2012/02/20 面试题
会计专业推荐信
2013/10/29 职场文书
会计学生自我鉴定
2014/02/06 职场文书
会计系毕业求职信
2014/08/07 职场文书
绿色小区申报材料
2014/08/22 职场文书
学习实践科学发展观心得体会
2014/09/10 职场文书
六查六看剖析材料
2014/10/06 职场文书
会计实训报告范文
2014/11/04 职场文书
2014年幼师工作总结
2014/11/22 职场文书
装饰技术负责人岗位职责
2015/04/13 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书
Java版 单机五子棋
2022/05/04 Java/Android