1

前言

一般而言,在学习或练习python的初级阶段,在Jupyter Notebook(spyder或pycharm)上进行逐条执行语句和代码,这样可以起到交互的良好效果。但是如果要进行大一点的项目实践,这种毫无规划的逐条执行语句与指令就显得不太适用了。为了使代码得到最大程度的重复使用,并且各模块之间逻辑更清晰,这时就有必要去学习模块化的抽象设计了。模块化的抽象设计基本思路是把主要框架和算法流程描述出来,再补充相应的细节。面向对象编程(Object-Oriented Programming)是模块化设计的重要方法之一,是Python金融量化进阶学习的必经之路

本文主要介绍了面向对象编程的基础知识,并以股票数据管理为例,介绍面向对象编程的具体应用,本文完整源码分享在知识星球上,可扫描下方二维码加入获取。后续推文将会以更复杂的形式呈现面向对象编程在实现股票策略量化回测系统中的应用。

2

class类编程入门

0

1

class类的定义

类实际上是具有相同属性与方法的对象集合。python定义类的语法有两种:

class 类名称:

def 定义属性和方法:

pass

class 类名称(继承类名称):

def 定义属性和方法:

pass

class后面是类名称,小括号里的继承类名称表示定义的类继承自哪一类。如果没有继承,则填object。比如下面定义一个股票stock类,属性和方法先不写,使用pass(跳过)表示。比如下面创建一个stock的类。

#定义一个股票的类
class stock(object):pass
#创建了stock这个类之后,便可以使用“stock()”来创建实例
s=stock()
s
#输出结果:<__main__.stock at 0x21f3f5aa160>

s是一个创建自stock类的实例。Python是一种动态语言,能够动态地绑定一个实例的属性与方法,如给s绑定一个code的代码属性:

s.code='000001.SZ'
s.code
#输出结果:'000001.SZ'

同理,也可以从stock类创建一个s1的实例,并绑定代表价格的属性:

s1=stock()
s1.price=15.8
s1.price
#输出结果:15.8

通过动态绑定可以拥有不同的属性,但是这样不利于项目的开发与维护。若希望创建自同一个类的实例拥有一些共同的属性,则可以通过定义一个特殊的函数__init__方法(注意下划线是在英文语境下输入两次),来绑定在创建实例时非填不可的属性。

__init__()第一个参数根据惯例为self,用于代指被实例化出来的对象,参数code和price是用于给对象的属性赋值,比如一个股票的类假设有代码和价格两个属性,则定义stock的类可以写成:

class stock(object):def __init__(self,code,price):self.code=codeself.price=price

python通过遵循一定的属性和方法命名规则来达到访问控制的效果:

  • 以单下划线开头的名字代表protect(受保护的),如self._price

  • 以双下划线开头的名字代表private,如self.__init_change(self):

  • 以双下划线开头结尾的名字代表系统保留定义,如__init__(self)、__str__(self)、__len__(self)

创建实例时,__init__方法中的参数,除了self不用输入外,其他参数非填不可,否则会报错。

在创建完类的名称后,可以加入一些文字说明,简要阐述类的主要内容,以方便使用者快速了解该类的功能,这些注释存储成字符串的形式。注意python注释的写法,单行注释前面加“#”,多行注释使用三引号。

class stock(object):'''stock类中包含属性code和price'''def __init__(self,code,price):self.code=codeself.price=price
#查看类中的注释内容
print(stock.__doc__)
输出结果:stock类中包含属性code和price

假如将上述代码保存为StockClass.py本地文件(可以使用Anaconda的Spyder来写脚本程序),保存在jupyter当前运行路径中,则可以通过导入类名的方式来使用类。

from StockClass import stock
print(stock.__doc__)

0

2

类的调用方法

类的调用方法主要有三种:(1)类的实例;(2)静态方法(@装饰器);(3)类的方法(clc)

实例调用最常见,一般使用“类名.方法”。静态方法由类调用,无默认参数。将实例方法参数中的self去掉,然后在方法定义上方加上@staticmethod(前面加@是python函数的装饰器方法),就成为静态方法。类方法由类调用,采用@classmethod装饰,至少传入一个cls(代指类本身,类似self)参数。执行类方法时,自动将调用该方法的类赋值给cls,建议使用类名.类方法的调用方式。

实例调用法:

class StockCode:def __init__(self,name,code):self.name=nameself.code=codedef get_stock(self):return (self.name,self.code)
s=StockCode('中国平安','601318.SH')
s.get_stock()
#输出结果:('中国平安', '601318.SH')

静态方法调用

class Codes(object):@staticmethoddef get_code(s):if len(s)==6:return (s+'SH') if s.startswith('6') else (s+'SZ')else:print('股票代码必须为6位数字!')
Codes.get_code('00001')
Codes.get_code('000001')
#输出结果:股票代码必须为6位数字!
#'000001SZ'

类调用法:

有的时候传入的参数并不是('中国平安','601318.SH')这样的格式,而是('中国平安-601318.SH')这样的,那该怎么做?首先要把这个拆分,但是要使用实例方法实现起来很麻烦,这个时候就可以使用类方法。

class StockCode:def __init__(self,stock,code):self.stock=stockself.code=code@classmethod# 装饰器,立马执行下面的函数def split(cls,sc):# cls是默认的这个类的init函数,sc是传入参数stock,code=map(str,sc.split('-'))# 这里转换成了格式化的结构dd = cls(stock,code)# 然后执行这个类第一个方法return dd
s=StockCode.split(('中国平安-601318.SH'))
#查看属性
s.stock,s.code
#输出结果:('中国平安', '601318.SH')

0

3

类的三大特征:封装、继承与多态

类有三个特征,分别是封装、继承和多态。封装简单理解是,将属性与方法放在某个对象内部,使外部无法访问。接着之前的例子,若要打印股票代码code和price,则可以先定义一个打印的函数,对之前的类修改如下:

class stock(object):def __init__(self,code,price):self.code=codeself.price=price#定义打印属性的函数def print_attr(self):print(f'股票代码为:{self.code}')print(f'股票价格为:{self.price}')
#使用“实例.方法”,即“实例名称.函数名()”的方式来调用
s1=stock('000001.SZ',15.8)
s1.print_attr()
#输出结果: 股票代码为:000001.SZ
#股票价格为:15.8

把方法写在对象内部,仍无法防止对象的属性被无关的函数意外改变或错误使用。为了对属性提供更加安全的保障,可以限制它们不被外界访问,可以在属性变量前面加上两个划线表示private属性,使其属性只能在类的内部进行访问,这时通过“实例.属性名称”从外部访问就会报错。通过priate属性访问限制,使对象内部状态得到保护,但若需要获取private属性,可以在类的内部编写一个获取属性的方法。

class stock(object):def __init__(self,code,price):self.__code=codeself.__price=pricedef get_attr(self):return(self.__code,self.__price)
s1=stock('000001.SZ',15.8)
s1.get_attr()
#输出结果:('000001.SZ', 15.8)

与从外部直接访问属性的设计相比,把方法封装在类中的好处是可以赋予方法一些行为规范。比如,若stock类需要修改code值的功能,则可以在类的内部增加一个set_code()的方法,且在定义该方法时,规定传入的值必须为字符串类型,否则报错。

class stock(object):def __init__(self,code,price):self.__code=codeself.__price=pricedef get_attr(self):return(self.__code,self.__price)def set_code(self,codevalue):if type(codevalue)!=str:return("错误,输入参数必须为字符型")self.__code=codevalue
s1=stock('000001.SZ',15.8)
print(s1.set_code(60000))
#重新定义是s1的代码
s1.set_code('600000.SH')
print(s1.get_attr())
#输出结果:
错误,输入参数必须为字符型('600000.SH', 15.8)

继承是充分利用已有的类功能,在其基础上进行扩展和定义新的类。继承概念的实现方式主要有2类:实现继承、接口继承。实现继承是指使用基类的属性和方法而无需额外编码的能力。接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构父类方法)。在使用python编写量化回测系统时经常会用到class类的继承功能。

#实现继承
class Strategy(object):def print_info(self):print('策略模块的功能是生成“多”或“空”的交易信号')
class my_strategy(Strategy):pass
ss=my_strategy()
ss.print_info()
#输出结果:
策略模块的功能是生成“多”或“空”的交易信号

继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Strategy实现了print_info()方法,因此,my_strategy作为它的子类,就自动拥有了print_info()方法。

#接口继承
#这里需要先引入一个抽象模块abc
from abc import ABCMeta, abstractmethod
#python中使用@表示装饰器的意思,具体可以参照python装饰器的相关教程
class Strategy(object):"""Strategy是一个抽象基类"""# abc.ABCMeta是实现抽象类的一个基础类__metaclass__ = ABCMeta#子类必须有这个方法,否则报错@abstractmethod  # 定义抽象方法,无需实现功能def generate_signals(self):"""输入数据产生多空的交易信号"""raise NotImplementedError("应包含方法:generate_signals()!")
#定义子类
class my_strategy2(Strategy):def generate_signals(self):pass
ss2.generate_signals()
#输出结果:实现交易信号功能
ss1.generate_signals()

尽管上面的接口很简单,但是当为每种特定类型的策略继承此类时,它将变得更加复杂。策略类的目标是为投资组合模块中提供多/空/持有信号。继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写;有了继承,才能有多态。多态的意思是,当子类(strategy2)与父类(Strategy)具有相同的方法(print_info())时,在实例子类的时候会自动调用子类的该方法(而不是父类的方法)。

class Strategy(object):def print_info(self):print('策略模块的功能是生成“多”或“空”的交易信号')
#继承
class strategy1(Strategy):pass
#多态
class strategy2(Strategy):def print_info(self):print('这是个人的交易策略')
#实例化
strategy1().print_info()
strategy2().print_info()
#输出结果:
策略模块的功能是生成“多”或“空”的交易信号这是个人的交易策略

3

class类编程在金融量化中的应用

应用背景:使用tushare获取所有A股每日交易数据,保存到本地数据库,同时每日更新数据库;根据行情数据进行可视化和简单的策略分析与回测。由于篇幅有限,本文着重介绍股票数据管理(下载、数据更新)的面向对象编程应用实例。

#导入需要用到的模块
import numpy as np
import pandas as pd
from dateutil.parser import parse
from datetime import datetime,timedelta
#操作数据库的第三方包,使用前先安装pip install sqlalchemy
from sqlalchemy import create_engine
#tushare包设置
import tushare as ts
token='输入你在tushare上获得的token'
pro=ts.pro_api(token)
#使用python3自带的sqlite数据库
#本人创建的数据库地址为c:\zjy\db_stock\
file='sqlite:///c:\\zjy\\db_stock\\'
#数据库名称
db_name='stock_data.db'
engine = create_engine(file+db_name)
class Data(object):def __init__(self,start='20050101',end='20191115',table_name='daily_data'):self.start=startself.end=endself.table_name=table_nameself.codes=self.get_code()self.cals=self.get_cals()       #获取股票代码列表    def get_code(self):codes = pro.stock_basic(list_status='L').ts_code.valuesreturn codes#获取股票交易日历def get_cals(self):#获取交易日历cals=pro.trade_cal(exchange='')cals=cals[cals.is_open==1].cal_date.valuesreturn cals#每日行情数据def daily_data(self,code):try:df0=pro.daily(ts_code=code,start_date=self.start,end_date=self.end)            df1=pro.adj_factor(ts_code=code,trade_date='') #复权因子df=pd.merge(df0,df1)  #合并数据except Exception as e:print(code)print(e)return df#保存数据到数据库def save_sql(self):for code in self.codes:data=self.daily_data(code)data.to_sql(self.table_name,engine,index=False,if_exists='append')#获取最新交易日期def get_trade_date(self):#获取当天日期时间pass#更新数据库数据def update_sql(self):pass #代码省略#查询数据库信息            def info_sql(self):pass #代码省略

代码运行

#假设你将上述代码封装成class Data
#保存在'C:\zjy\db_stock'目录下的down_data.py中
import sys
#添加到当前工作路径
sys.path.append(r'C:\zjy\db_stock')
#导入py文件中的Data类
from download_data import Data
#实例类
data=Data()
#data.save_sql() #只需运行一次即可
data.update_sql()
data.info_sql() 

输出结果:
   数据已经是最新的!
   统计查询的总数:7747184
   数据期间:20050104——20191125
   数据库包含股票个数:3724

#另外又根据画图需要,从数据库中提取数据画K线图
#写了一个stock_plot类保存在plot_stock.py文件中
from plot_stock import stock_plot
shfz=stock_plot('双汇发展')
shfz.kline_plot() #普通K线图

#画修正版K线图
shfz.kline_plot(ktype=1)

4

结语

本文主要介绍了面向对象编程的基础知识和股票数据管理应用实例。

通常我们会以各种数据信息来刻画描述一个对象,而这个对象包含某些属性或特征。比如,将某只股票视为一个对象,那么该股票对象包含的信息可能有股票代码、公司名称、所属行业、收盘价等。这些用以描述对象特征的数据信息称为对象的属性(Attribute);而存取属性的函数则称为方法(Method),是该对象与外界沟通的接口。具有相同属性与方法的对象构成了一个类别(Class)。换句话说,类是一种将对象抽象化而形成的概念,而对象则是类具体实现的例子(实例)。以对象为基础的编程思想具有封装、继承和多态三大特征,在构建量化交易系统中发挥了非常重要的作用。后续推文将介绍使用面向对象编程的量化策略回测。

参考资料:廖雪峰的官方网站:Python3教程——面向对象编程。

关于Python金融量化

专注于分享Python在金融量化领域的应用。加入知识星球,可以免费获取30多g的量化投资视频资料、量化金融相关PDF资料、公众号文章Python完整源码、量化投资前沿分析框架,与博主直接交流、结识圈内朋友等。

【手把手教你】Python面向对象编程入门及股票数据管理应用实例相关推荐

  1. 真良心干货保姆级手把手教你Python网络编程,学不会我去你家教你

    Python网络编程 基本概念(计算机网络基础) IP地址与端口 IP地址 端口 网络通信协议 网络通信协议 网络协议的分层 TCP/UDP 套接字编程 socket()函数介绍 UDP 编程 实现U ...

  2. 手把手教你python实现量价形态选股知乎_【手把手教你】Python实现量价形态选股...

    来源:雪球App,作者: Python金融量化,(https://xueqiu.com/1444657641/139331726) 01引言 在股票市场上,一切交易行为的成功皆为概率事件,交易获利的核 ...

  3. Computer:少儿编程—每个人都应该学习编程,它能教你如何思考—编程入门的简介(编程语言的特点种类开发工具对比人类语言)、编程应用、编程意义之详细攻略

    Computer:少儿编程-每个人都应该学习编程,它能教你如何思考-编程入门的简介(编程语言的特点&种类&开发工具&对比人类语言).编程应用.编程意义之详细攻略 导读:乔布斯说 ...

  4. Python面向对象编程:类继承和其衍生术语

    Python面向对象编程03:类继承和其衍生术语 前面我们讲到过正则表达式字符等,上一篇分享了面向对象编程和类的结构,最后稍微提到了继承. Python面向对象编程:深度认识类class_ Pytho ...

  5. python流程控制-实战案例手把手教你Python流程控制技巧

    原标题:实战案例手把手教你Python流程控制技巧 作者:PianoOrRock 来源: http://blog.csdn.net/pianoorrock/article/details/711315 ...

  6. python与人工智能编程-总算明白python人工智能编程入门案例

    Python是非常简洁的一种脚本语言,写同样的程序,代码量仅为java的三分一,除了性能没有Java强之外,它的优点还是相当多的.以下是小编为你整理的python人工智能编程入门案例 下载Active ...

  7. python快速编程入门教程-终于懂得python快速编程入门教程

    为了提高模块加载的速度,每个模块都会在__pycache__文件夹中放置该模块的预编译模块,命名为module.version.pyc,version是模块的预编译版本编码,一般都包含Python的版 ...

  8. 【Python基础】Python 面向对象编程(上篇)

    我的施工计划图 已完成专题包括: 1我的施工计划 2数字专题 3字符串专题 4列表专题 5流程控制专题 6编程风格专题 7函数使用专题 今天是面向对象编程的上篇:基础专题 Python 面向对象编程 ...

  9. python交互式编程在哪里_终于明了python交互式编程入门

    Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python交互式编程入门 环境配置:下载Python并 ...

最新文章

  1. 四种软件架构演进史,会一种就很牛逼了!
  2. Mac OS X下Maven的安装与配置
  3. 一个不错的资源共享微盘
  4. libxml中用到的Xpath语法说明
  5. RHEL6   Kickstart 无人值守安装
  6. 连续投影算法_中航国画荣获“2020 IAV国际视听嘉年华” 大屏幕投影显示行业三大奖项!...
  7. MySQL主从数据库配置和常见问题
  8. linux下boost库链接动态库失败
  9. iphone短信尚未送达_潮讯:iPhone12重大升级;华为麒麟被炒价;抖音上线云游戏;骚扰短信要凉了;一加刘作虎回归OPPO...
  10. android 搜索文件代码怎么写,android学习笔记(5)-一个搜索文件的APP(2)-搜索功能的实现...
  11. STM32工作笔记0009---认识FSMC和TTL电路
  12. 面向对象【day07】:新式类和经典类(八)
  13. PHP初级练习实战之公司留言板(原生)
  14. tomcat是一个应用服务器
  15. 电子购物网站导航制作
  16. 知瓜数据丨月入过亿的品牌“李宁”,如何成为直播营销的领头羊
  17. 瞎琢磨先生のJava工具类
  18. 如何将分表汇总到总表_如何快速将几个分表合并到一张表
  19. win10更新后wifi提示无法连接到该网络,终极解决方法
  20. 【Kafka】Kafka消费者相关策略

热门文章

  1. java毕业设计糖助手服务交流平台mybatis+源码+调试部署+系统+数据库+lw
  2. 你知道电源内部是怎么工作的吗
  3. Python源码解析-整数与引用计数器
  4. 300 毫秒点击延迟的来龙去脉
  5. 安卓内录声音软件scr_那款安卓手机软件可以内录视频?
  6. YB233单通道触摸感应芯片上电自复位 环境自适应,性价比高适用于 触摸台灯 移动电源小家电等替代传统触点按键
  7. 鲸鱼优化算法(WOA)(学习)
  8. pfsense使用tcpdump抓包
  9. 久坐提醒软件(Windows)
  10. 云原生技术助力混合云架构落地