|
|
|
|
移动端

2.3.3 静态方法、类方法与属性(1)

《量化交易之路:用Python做股票量化分析》第2章量化语言——Python,第2部分(第2~6章)主要讲解了量化交易需要的基础知识及相关工具,如Python语言、NumPy、pandas、数据可视化及量化数学等知识,适合完全没有任何编程经验的读者从头开始阅读。本节为大家介绍静态方法、类方法与属性。

作者:阿布来源:机械工业出版社|2017-10-19 16:32

技术沙龙 | 6月30日与多位专家探讨技术高速发展下如何应对运维新挑战!


2.3.3  静态方法、类方法与属性(1)

1.属性(property)

TradeStrategy1类中的self.__buy_change_threshold被定义为私有变量,外部不能直接赋值,使用了@property来赋值,代码如下:

  1. @property  
  2. def buy_change_threshold(self):  
  3.     # getter函数  
  4.     return self.__buy_change_threshold  
  5. @buy_change_threshold.setter  
  6. def buy_change_threshold(self, buy_change_threshold):  
  7.     if not isinstance(buy_change_threshold, float):  
  8.         """  
  9.             上涨阀值需要为float类型  
  10.         """  
  11.         raise TypeError('buy_change_threshold must be float!')  
  12.     # 上涨阀值只取小数点后两位  
  13. self.__buy_change_threshold = round(buy_change_threshold, 2) 

第一个@property方法是一个getter函数,它使得buy_change_threshold成为一个属性, @ buy_change_threshold.setter属性添加了setter函数,这样外部的访问和设置形式如下。

访问:

  1. trade_strategy1 = TradeStrategy1()  
  2. trade_strategy1.buy_change_threshold 

输出如下:

  1. 0.07 

设置:

  1. trade_strategy1.buy_change_threshold = 0.08  
  2. trade_strategy1.buy_change_threshold 

输出如下:

  1. 0.08 

使用@property的目的是给实例增加除访问与修改之外的其他处理逻辑,比如buy_change_threshold.setter做了类型检查和将float阀值保留两位小数操作,不要写没有做任何其他额外操作的property。一些语言(如Java)认为所有访问都应该通过getter和setter,但是Python的最大特点就是简洁,而且使用@property降低了效率。

下面将交易买入阀值从0.07上升到0.1,即超过10%的当日涨幅才作为买入信号,结果可以看到,总盈亏下降到0.8%,代码如下:

  1. trade_strategy1 = TradeStrategy1()  
  2. # 买入阀值从0.07上升到0.1  
  3. trade_strategy1.buy_change_threshold = 0.1  
  4. trade_loop_back = TradeLoopBack(trade_days, trade_strategy1)  
  5. trade_loop_back.execute_trade()  
  6. print '回测策略1 总盈亏为:{}%'.format(  
  7.     reduce(lambda a, b: a + b, trade_loop_back.profit_array) * 100)  
  8. # 可视化profit_array,如图2-3所示  
  9. plt.plot(np.array(trade_loop_back.profit_array).cumsum()) 

输出如下,结果如图2-3所示。

  1. 回测策略1 总盈亏为:0.8% 

继续编写一个均值回复交易策略,当股价连续两个交易日下跌,且下跌幅度超过一个阀值(默认-10%)时,买入股票并持有s_keep_stock_threshold(10)天,代码如下:

  1. class TradeStrategy2(TradeStrategyBase):  
  2.     """  
  3.         交易策略2: 均值回复策略,当股价连续两个交易日下跌,  
  4.         且下跌幅度超过阀值默认s_buy_change_threshold(-10%),  
  5.         买入股票并持有s_keep_stock_threshold(10)天  
  6.     """  
  7.     # 买入后持有天数  
  8.     s_keep_stock_threshold = 10 
  9.     # 下跌买入阀值  
  10.     s_buy_change_threshold = -0.10  
  11.     def __init__(self):  
  12.         self.keep_stock_day = 0 
  13.     def buy_strategy(self, trade_ind, trade_day, trade_days):  
  14.         if self.keep_stock_day == 0 and trade_ind >= 1:  
  15.             """  
  16.                 当没有持有股票的时候self.keep_stock_day == 0 并且  
  17.                 trade_ind >= 1, 不是交易开始的第一天,因为需要yesterday数据  
  18.             """  
  19.             # trade_day.change < 0 bool:今天股价是否下跌  
  20.             today_down = trade_day.change < 0 
  21.             # 昨天股价是否下跌  
  22.             yesterday_down = trade_days[trade_ind - 1].change < 0 
  23.             # 两天总跌幅  
  24.             down_rate = trade_day.change + \  
  25.                         trade_days[trade_ind - 1].change  
  26.             if today_down and yesterday_down and down_rate < \  
  27.                     TradeStrategy2.s_buy_change_threshold:  
  28.                 # 买入条件成立:连跌两天,跌幅超过s_buy_change_threshold  
  29.                 self.keep_stock_day += 1  
  30.         elif self.keep_stock_day > 0:  
  31.             # self.keep_stock_day > 0代表持有股票,持有股票天数递增  
  32.             self.keep_stock_day += 1  
  33.     def sell_strategy(self, trade_ind, trade_day, trade_days):  
  34.         if self.keep_stock_day >= \  
  35.                 TradeStrategy2.s_keep_stock_threshold:  
  36.             # 当持有股票天数超过阀值s_keep_stock_threshold,卖出股票  
  37.             self.keep_stock_day = 0 
  38.     """  
  39.         稍后会详细讲解classmethod,staticmethod  
  40.     """  
  41.     @classmethod  
  42.     def set_keep_stock_threshold(cls, keep_stock_threshold):  
  43.         cls.s_keep_stock_threshold = keep_stock_threshold  
  44.     @staticmethod  
  45.     def set_buy_change_threshold(buy_change_threshold):  
  46.         TradeStrategy2.s_buy_change_threshold = buy_change_threshold 

下面实例化一个TradeStrategy2对象trade_strategy2,使用它和TSLA的504天真实交易数据构造的StockTradeDays类对象trade_days,来实例化回测对象trade_loop_back,并使用execute_trade()函数执行回测,代码如下:

  1. trade_strategy2 = TradeStrategy2()  
  2. trade_loop_back = TradeLoopBack(trade_days, trade_strategy2)  
  3. trade_loop_back.execute_trade()  
  4. print '回测策略2 总盈亏为:{}%'.format(  
  5.     reduce(lambda a, b: a + b, trade_loop_back.profit_array) * 100)  
  6. # 图2-4 所示  
  7. plt.plot(np.array(trade_loop_back.profit_array).cumsum()) 

输出如下,结果如图2-4所示。

  1. 回测策略2 总盈亏为:13.3% 

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Visual Studio 2005+SQL Server 2005数据库应用系

本书主要介绍采用Visual Studio 2005的C#语言为前台,SQL Server 2005数据库为后台的数据库系统开发技术。 全书分为15章,内容包括走进.NE...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊