金融科技之交易:动量效应选股策略

金融科技之交易:动量效应选股策略

  • 策略内容:
  • 代码整理
    • 角度计算
      • 标准化处理
      • 数据准备
      • 回归线的斜率
      • 两点连线的斜率
      • 由斜率计算角度
      • 计算模块的整合
    • 绘制叠加图
    • UI界面控件:
      • QLabel
      • QLineEdit
      • QPushButton
      • QComboBox
      • QTableWidget
    • 信号与槽函数
      • 选择目标股票表格
      • 开始筛选
      • 展示筛选结果
      • 双击单元格打开详细信息窗口
      • 更换展示的K线图和超级叠加图
      • 双击打开东方财富股票行情页面
    • 子线程
  • 待完善的工作

这是本蒟蒻在实习时做的一个小项目,主要是筛选与大盘偏离的股票,并制作成带有UI界面的exe文件,供基金经理使用。在征得公司同意后将其整理发布,记录自己的学习历程。

策略内容:

动量效应:动量效应一般又称“惯性效应”。是指股票的收益率有延续原来的运动方向的趋势,即过去一段时间收益率较高的股票在未来获得的收益率仍会高于过去收益率较低的股票。

在这里,我们用股票相对于上证综指的超额收益来表示收益率。我们希望筛选出在过去的一段时间内超额收益在特定范围的股票。
但是超额收益作为一个数值对于大部分的人来说并不直观,所以我们可以用股票的价格线与指数的价格线之间的夹角的角度来直观地感受超额收益。

而价格线的绘制可以有两种方法:1.逻辑回归线 2.第一天和最后一天的价格点的连线。同时价格要转换成价格相较于第一天的增幅,这样可以将股票和指数的两个起始点放在同一个点上。
如下图:
在这里插入图片描述
在这里插入图片描述

同时要注意数据的标准化,将角度的计算放在我们熟悉的单位长度相等的笛卡尔坐标系下,这样计算出来的结果才更接近我们直观观察的角度。

代码整理

因为本蒟蒻水平有限,接触编程的时间不长。如果有代码不规范、语句冗余等问题还希望不吝赐教。

同时因为源码细节较多,这里只给出核心的代码。

这里先给出效果图:

图片图片图片

图片

角度计算

标准化处理

因为参与运算的数据氛围不一致。价格变化率的绝对值一般不超过(-5,5)。而日期时间的序号是从0到数十或数百(由选择的时间范围觉得)。这样计算出的直线的斜率都是很小的值。所以将数据进行标准化处理,这样计算出的斜率才和观察的相近。因为我们估算直线斜率一般会把看到的直线默认为是在两个坐标轴的单位长度和压缩比率相同的坐标系中。

这里使用最大最小标准化处理,将价格变化率和日期序列都映射到【0,1】。

  def MaxMinNormalization(self,x, min, max):"""[0,1] normaliaztion"""x = (x - min) / (max - min)return x

数据准备

将tushare中获取的数据进行初步处理。包括计算价格涨幅、标准化处理等

#这里的st、index都是从tushare中获取的数据。st_x = array([i for i in range(0, len(st['close']))])#日期转换成序号st_x = self.MaxMinNormalization(st_x, 0, len(st['close']) - 1)#标准化处理st_x = array([st_x]).T# T为矩阵转置把1xn变成nx1index_x = array([i for i in range(0, len(index['close']))])index_x = self.MaxMinNormalization(index_x, 0, len(index['close']) - 1)        index_x = array([index_x]).T#计算涨幅st_y = array([(close - st['close'][0]) / st['close'][0] for close in st['close']])index_y = array([(close - index['close'][0]) / index['close'][0] for close in index['close']])min = hstack((st_y, index_y)).min()max = hstack((st_y, index_y)).max()#因为两条直线要画在同一个图中,所以要一起进行标准化处理,最大和最小值是股票和指数共同的最大值和最小值。st_y = self.MaxMinNormalization(st_y, min, max)st_y = array([st_y]).Tindex_y = self.MaxMinNormalization(index_y, min, max)index_y = array([index_y]).T#标准化处理

回归线的斜率

#线性回归
regr_st = LinearRegression().fit(st_x, st_y) #训练,得到股票的回归线
regr_index = LinearRegression().fit(index_x, index_y)#得到指数的回归线
st_coef=regr_st.coef_[0][0],
index_coef =regr_index.coef_[0][0])
#分别是股票和指数回归线的斜率

两点连线的斜率

st_coef = list(st_y)[-1][0]-list(st_y)[0][0])/list(st_x)[-1][0]
index_coef =list(index_y)[-1][0]-list(index_y)[0][0])/list(index_x)[-1][0]

由斜率计算角度

x = array([1, st_coef])  # 方向向量
y = array([1, index])Lx = sqrt(x.dot(x))
Ly = sqrt(y.dot(y))
# 求得斜线的长度
cos_angle = x.dot(y) / (Lx * Ly)
# 求得cos_sita的值再反过来计算,绝对长度乘以cos角度为矢量长度
angle = arccos(cos_angle) * 360 / 2 / 3.1415926

计算模块的整合

将上面介绍的整合成一个类

import tushare as ts
import datetime
from sklearn.linear_model import LinearRegression
from numpy import array,hstack,sqrt,arccosclass clac():#数据标准化处理函数def MaxMinNormalization(self,x, min, max):"""[0,1] normaliaztion"""x = (x - min) / (max - min)return x#得到两个直线的斜率def get_coef(self,st, index,type):st_x = array([i for i in range(0, len(st['close']))])st_x = self.MaxMinNormalization(st_x, 0, len(st['close']) - 1)# T为矩阵转置把1xn变成nx1st_x = array([st_x]).Tindex_x = array([i for i in range(0, len(index['close']))])index_x = self.MaxMinNormalization(index_x, 0, len(index['close']) - 1)# T为矩阵转置把1xn变成nx1index_x = array([index_x]).Tst_y = array([(close - st['close'][0]) / st['close'][0] for close in st['close']])index_y = array([(close - index['close'][0]) / index['close'][0] for close in index['close']])min = hstack((st_y, index_y)).min()max = hstack((st_y, index_y)).max()st_y = self.MaxMinNormalization(st_y, min, max)st_y = array([st_y]).Tindex_y = self.MaxMinNormalization(index_y, min, max)index_y = array([index_y]).Tif type == '回归线':  # 是回归线版本# regr为回归过程,fit(x,y)进行回归regr_st = LinearRegression().fit(st_x, st_y)regr_index = LinearRegression().fit(index_x, index_y)return regr_st.coef_[0][0], regr_index.coef_[0][0]else:#是两点连线return (list(st_y)[-1][0]-list(st_y)[0][0])/list(st_x)[-1][0],(list(index_y)[-1][0]-list(index_y)[0][0])/list(index_x)[-1][0]def get_angle(self,x, y):#计算两个直线的角度# x和y是方向向量Lx = sqrt(x.dot(x))Ly = sqrt(y.dot(y))# 相当于勾股定理,求得斜线的长度cos_angle = x.dot(y) / (Lx * Ly)# 求得cos_sita的值再反过来计算,绝对长度乘以cos角度为矢量长度angle = arccos(cos_angle) * 360 / 2 / 3.1415926return angledef angle(self,st_code,months):#最终的包装,由外部调用#获取数据pro = ts.pro_api('你的token')start_date = datetime.datetime.today() - datetime.timedelta(days=int(30*months))start_date = start_date.date().strftime("%Y%m%d")st_price = pro.daily(ts_code=st_code, start_date=start_date, fields='ts_code,trade_date,close')end_date=st_price['trade_date'][0]st_price=st_price.sort_values(["trade_date"], ascending=True).reset_index(drop=True)start_date = st_price['trade_date'][0]index_close = pro.index_daily(ts_code='000001.SH', start_date=start_date, end_date=end_date,fields='ts_code,trade_date,close')index_close = index_close.sort_values(["trade_date"], ascending=True).reset_index(drop=True)#得到斜率st_coef, index_coef = self.get_coef(st_price, index_close,'回归线')x = array([1, st_coef])  # 回归线的方向向量y = array([1, index_coef])angle0 = self.get_angle(x, y)if st_coef < index_coef:angle0 = -1 * angle0st_coef, index_coef = self.get_coef(st_price, index_close, '两点连线')x = array([1, st_coef])  # 两点连线方向向量y = array([1, index_coef])angle1 = self.get_angle(x, y)if st_coef < index_coef:angle1 = -1 * angle1return (angle0,angle1)

绘制叠加图

在详细窗口界面展示了两个图像,一个是K线图,一个是指数叠加图。K线图是从东方财富网爬取下来的。已经在上面介绍过了。而指数叠加图需要我们自己绘制。在Pyqt5窗口中展示matplotlib绘制的图,需要创建画布。定义一个画布类:

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figureclass PlotCanvas(FigureCanvas):##画布def __init__(self, parent=None,width=5, height=4, dpi=100):#初始化fig = Figure(figsize=(width, height), dpi=dpi, edgecolor="blue")plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseself.axes = fig.add_subplot(111)self.parent=parentfig.subplots_adjust(left=0.1, bottom=0.1, top=0.9, right=0.9)FigureCanvas.__init__(self, fig)self.setParent(parent)FigureCanvas.setSizePolicy(self,QSizePolicy.Expanding,QSizePolicy.Expanding)FigureCanvas.updateGeometry(self)self.drawLine(self.parent.ui.comboBox_1.currentText())def drawLine(self,type):#绘制图像pro = ts.pro_api('请填入你的token')start_date = datetime.datetime.today() - datetime.timedelta(days=int(30 * self.parent.months))start_date = start_date.date().strftime("%Y%m%d")st = pro.daily(ts_code=self.parent.stCode, start_date=start_date, fields='ts_code,trade_date,close')end_date=st['trade_date'][0]st = st.sort_values(["trade_date"], ascending=True).reset_index(drop=True)st_close = [(close - st['close'][0]) / st['close'][0] for close in st['close']]start_date=st['trade_date'][0]index = pro.index_daily(ts_code='000001.SH', start_date=start_date,end_date=end_date, fields='ts_code,trade_date,close')index = index.sort_values(["trade_date"], ascending=True).reset_index(drop=True)index_close = [(close - index['close'][0]) / index['close'][0] for close in index['close']]index_date = ['{}-{}-{}'.format(date[:4],date[4:6],date[6:]) for date in index['trade_date']]st_x = array([i for i in range(0, len(st['trade_date']))])st_x = array([st_x]).Tindex_x = array([i for i in range(0, len(index['trade_date']))])index_x = array([index_x]).Tst_y = array([(close - st['close'][0]) / st['close'][0] for close in st['close']])index_y = array([(close - index['close'][0]) / index['close'][0] for close in index['close']])st_y = array([st_y]).Tindex_y = array([index_y]).Tself.st_x=st_xself.st_y=st_yself.index_x=index_xself.index_y=index_yself.axes.cla()self.axes.set_title("大盘指数叠加")def to_percent(temp, position):return '%1.0f' % (100 * tself.axes.yaxis.set_major_formatter(FuncFormatter(to_percent))  # 更改y轴的显示内容为百分数self.axes.plot(index_x, index_close, color='red', label='上证指数', linewidth=0.5)self.axes.plot(st_x, st_close, color='blue', label=self.parent.stCode, linewidth=0.5)self.axes.legend(loc='best')x=list(index_x[::len(index_x) // 4-1])self.axes.set_xticks(x)date=index_date[::len(index_date)//4-1]self.axes.set_xticklabels(date, rotation=15)st_x=self.st_xst_y=self.st_yindex_x=self.index_xindex_y=self.index_yif type=='回归线':regr_st = LinearRegression().fit(st_x, st_y)regr_index = LinearRegression().fit(index_x, index_y)self.axes.plot(st_x, regr_st.predict(st_x),color='blue', linestyle='-.',label='股票回归', linewidth=1)self.axes.plot(index_x, regr_index.predict(index_x), color='red',linestyle='-.', label='指数回归', linewidth=1)self.axes.legend(loc='best')else:self.axes.plot([st_x[0],st_x[-1]],[st_y[0],st_y[-1]],color='blue', linestyle='-.',label='股票连线', linewidth=1)self.axes.plot([index_x[0], index_x[-1]], [index_y[0], index_y[-1]], color='red', linestyle='-.', label='指数连线',linewidth=1)self.axes.legend(loc='best')

UI界面控件:

UI界面的设计使用的是Python的pyqt5并借助了QT designer工具来辅助设置UI界面。

Pyqt5的内容很多,这里我们只介绍我们所用到的几个重要控件的常用方法,如果想了解更多pyqt5的内容,可以去网络上查找相关的介绍,CSDN中有很多介绍Pyqt5的文章。

QLabel

QLabel是标签,对应的是展示效果图中的“角度范围”、“时间范围“等文字信息。

QLabel中部分常用的方法是:

text()获得Qlabel的文本内容
setText()设置Qlabel的文本内容
setGeometry()设置Qlabel在窗口中的位置和大小
setFont()设置Qlabel中文本的字体
setPixmap()在QLabel中填充图片

QLineEdit

QLineEdit是单行文本输入框,即效果图中输入角度和月份数的三个框框。

text()获得QLineEdit中的文本内容
setGeometry()设置QLineEdit在窗口中的位置和大小
setGeometry()设置Qlabel在窗口中的位置和大小

QPushButton

QPushButton是按钮,即效果图中的”选择目标股票表格“和”开始筛选“两个按钮。

setText()设置按钮上的文本
setStyleSheet()设置按钮的样式,如背景颜色
setGeometry()设置Qlabel在窗口中的位置和大小

QComboBox

QComboBox是下拉框,即效果中的选择(回归线/两点连线/二者任一)的控件。

addItem()添加选项
currentText()获取选中的文本
setGeometry()设置Qlabel在窗口中的位置和大小

QTableWidget

QTableWidget是表格,即效果图中展示筛选结果的表格。

setColumnCount()设置列数
setRowCount()设置行数
setHorizontalHeaderItem()设置表头(一次设置一个)
setHorizontalHeaderLabels()设置表头(参数为列表,一次多个)
tableWidget.setItem()设置单元格内容
tableWidget.insertRow()插入一行单元格
tableWidget.setSpan()合并单元格
setGeometry()设置Qlabel在窗口中的位置和大小

信号与槽函数

上一个板块为UI添加控件,但设计出来的只是静态的窗口。点击按钮、选择下拉框都没有任何反应。如果我们希望点击按钮或者做其他事情时我们的程序可以执行某些功能。就需要利用信号与槽函数。Pyqt5的控件几乎都支持绑定信号和槽函数。信号可以理解为一个事件,比如单击\双击按钮、单击表格的文本框、改变下拉选择框当前的选项等等。槽函数就是与这些信号绑定的函数。当信号发生时,会自动执行与其绑定的槽函数。

下面给出该程序的槽函数与信号:

选择目标股票表格

有时候,我们并不想筛选全部的A股,而是只关注特定的若干只股票,有目的性地筛选。
单击”选择模板股票表格“按钮,可弹出一个文件选择框。选择含有存储目标股票代码的excel文件。
在这里插入图片描述

图片

该功能的槽函数如下:

def set_target_stock(self):try:filechoose = QFileDialog.getOpenFileName(self);filechoosed = filechoose[0]self.target_stock=list(pd.read_excel(filechoosed)['ts_code'])self.main_ui.label_7.setText(filechoosed)#更改窗口中的目标股票提示内容except:print(traceback.format_exc())

触发该槽函数的信号为单击该按钮:

self.main_ui.btn_set_target_stock.clicked.connect(self.set_target_stock)#btn_set_target_stock就是按钮控件

开始筛选

单击”开始筛选“按钮,执行程序。

该函数调用了一个自定义的子线程,该子线程执行筛选操作,其具体的内容会在后面介绍。

def run(self):try:if self.main_ui.btn_run.text()=='开始筛选':#开始执行self.main_ui.btn_run.setText('正在筛选')self.main_ui.btn_run.setStyleSheet("background-color: rgb(255, 0, 0);")type=self.main_ui.comboBox.currentText()#下拉框的选项angle1=int(self.main_ui.angle_range1.text())angle2=int(self.main_ui.angle_range2.text())months=int(self.main_ui.time_range.text())#在窗口中输入的三个变量,angle_rang1等三个空间都是QLineEditself.thread = thread_run(self.target_stock,angle1,angle2,months,type)#这里创建子线程,并传入参数self.thread._signal.connect(self.update)#设置子线程的信号与槽函数,子线程返回筛选结果时会执行update函数.self.thread.start()#开始执行else:#停止执行self.thread.terminate()#关闭子线程self.thread.wait()self.main_ui.tableWidget.insertRow(0)self.main_ui.tableWidget.setSpan(0, 0, 1, 4)redBrush = QtGui.QBrush(QtGui.QColor(255, 0, 0))item = QtWidgets.QTableWidgetItem(str(datetime.datetime.now().strftime("%H:%M:%S")+':暂停筛选'))self.main_ui.tableWidget.setItem(0, 0, item)self.main_ui.tableWidget.item(0, 0).setForeground(redBrush)#在表格中插入一行,并写入提示信息。self.main_ui.btn_run.setText('开始筛选')self.main_ui.btn_run.setStyleSheet("background-color: rgb(255, 255, 255);")except:print(traceback.format_exc())

信号:

self.main_ui.btn_run.clicked.connect(self.run)

展示筛选结果

子线程会将满足条件的股票的代码和角度发送到槽函数update中。

def update(self, msg):#用于更新表格
#msg返回就是线程返回的内容if msg=='finish':self.main_ui.tableWidget.insertRow(0)  # 插入一行self.main_ui.tableWidget.setSpan(0, 0, 1, 4)redBrush = QtGui.QBrush(QtGui.QColor(255, 0, 0))item = QtWidgets.QTableWidgetItem(str(datetime.datetime.now().strftime("%H:%M:%S") + ':筛选完成'))self.main_ui.tableWidget.setItem(0, 0, item)self.main_ui.tableWidget.item(0, 0).setForeground(redBrush)self.main_ui.btn_run.setText('开始筛选')self.main_ui.btn_run.setStyleSheet("background-color: rgb(255, 255, 255);")returntry:st_code=msg.split(',')[0]angle0=msg.split(',')[1]#回归线角度angle1=msg.split(',')[2]#两点连线角度st_code=st_code[-2:].lower()+\st_code[:6]url='http://hq.sinajs.cn/list='+st_codedata=requests.get(url).textdata=data.split('"')data=data[1].split(',')#从新浪财经获取股票名称、今开、昨收self.main_ui.tableWidget.insertRow(0)#插入一行item0 = QtWidgets.QTableWidgetItem(msg.split(',')[0])item1 = QtWidgets.QTableWidgetItem(data[0])item2 = QtWidgets.QTableWidgetItem(data[1])item3 = QtWidgets.QTableWidgetItem(data[2])item4 = QtWidgets.QTableWidgetItem(angle0)item5 = QtWidgets.QTableWidgetItem(angle1)self.main_ui.tableWidget.setItem(0, 0, item0)self.main_ui.tableWidget.setItem(0, 1, item1)self.main_ui.tableWidget.setItem(0, 2, item2)self.main_ui.tableWidget.setItem(0, 3, item3)self.main_ui.tableWidget.setItem(0, 4, item4)self.main_ui.tableWidget.setItem(0, 5, item5)#填入表格except:print(traceback.format_exc())

该槽函数与信号的绑定是在上面的 run()函数中设置的:

self.thread._signal.connect(self.update)

双击单元格打开详细信息窗口

双击筛选结果中表格的某一列,可以弹出新窗口,新窗口中可以展示一支股票更多的信息,比如K线图和超级叠加图。

槽函数:

def more_Information(self,x,y):#x和y是信号自动传送的值,是被双击的单元格的位置try:stCode = self.main_ui.tableWidget.item(x, 0).text()stName=self.main_ui.tableWidget.item(x,1).text()angle=(self.main_ui.tableWidget.item(x,4).text(),self.main_ui.tableWidget.item(x,5).text())type=self.main_ui.comboBox.currentText()#被双击的单元格对应的股票的信息获取参数window = moreInfWindow(stCode,stName,int(self.main_ui.time_range.text()),angle,type=type)window.show()window.exec_()#打开新窗口,这里的moreInfWindow是一个新的窗口,具体参见源代码。except:print(traceback.format_exc())

信号:

self.main_ui.tableWidget.cellDoubleClicked.connect(self.more_Information)

更换展示的K线图和超级叠加图

图片

如上图,详细窗口会展示股票的一些数据同时展示该股吧的K线图和与指数的超级叠加图,以及对应的回归线或者两点连线。

可以选择想要展示的K线图的时间范围和叠加图中的直线类型(回归线或者两点连线)。

K线图槽函数:

def Kpic(self):codest={'SH':'1','SZ':'0'}Ksize = {'1年':'-3','6月':'-4','3月':'-6','1月':'-8'}size=Ksize[self.ui.comboBox.currentText()[:2]]#获取图片stimgUrl='http://webquoteklinepic.eastmoney.com/GetPic.aspx?nid='+codest[self.stCode[-2:]]+'.'+self.stCode[:-3]+'&UnitWidth={}&imageType=KXL&EF=&Formula=RSI&AT=0'.format(size)# print(cbimgUrl)print(stimgUrl)try:response = requests.get(stimgUrl)wb_data = response.contentwith open('stimg.png', 'wb') as f:f.write(wb_data)pix = QPixmap('stimg.png')self.ui.imagelb.setPixmap(pix)#在标签中填充图片except:pass

K线图信号:

self.ui.comboBox.currentIndexChanged.connect(self.Kpic)

叠加图槽函数:(这里用到了画布,m是一个画布,会在后面介绍)

def Lpic(self):self.m.axes.cla()#清空重画self.m.drawLine(self.ui.comboBox_1.currentText())self.m.draw()

叠加图信号:

self.ui.comboBox_1.currentIndexChanged.connect(self.Lpic)

双击打开东方财富股票行情页面

若想要了解更多关于某只股票的信息,可以双击详细信息窗口中的表格,会打开东方财富相应股票的页面。

图片

槽函数:

def openUrl(self):url="http://quote.eastmoney.com/{}.html".format(self.stCode[-2:].lower()+ self.stCode[0:6])QtGui.QDesktopServices.openUrl(QtCore.QUrl(url))

信号:

self.ui.tableWidget.cellDoubleClicked.connect(self.openUrl)

子线程

筛选的任务是在子线程中完成的。因为如果不使用子线程,在筛选完成之前我们的程序不能做任何操作,也无法暂停。所以我们需要调用子线程,由主线程控制子线程的执行和停止。

主线程的对应函数以及在上面给出,也就是run()函数。这里再贴一下:

def run(self):try:if self.main_ui.btn_run.text()=='开始筛选':#开始执行self.main_ui.btn_run.setText('正在筛选')self.main_ui.btn_run.setStyleSheet("background-color: rgb(255, 0, 0);")type=self.main_ui.comboBox.currentText()#下拉框的选项angle1=int(self.main_ui.angle_range1.text())angle2=int(self.main_ui.angle_range2.text())months=int(self.main_ui.time_range.text())#在窗口中输入的三个变量,angle_rang1等三个空间都是QLineEdit          self.thread = thread_run(self.target_stock,angle1,angle2,months,type)#这里创建子线程,并传入参数self.thread._signal.connect(self.update)#设置子线程的信号与槽函数,子线程返回筛选结果时会执行update函数.self.thread.start()#开始执行,会自动执行thread中的run()else:#停止执行self.thread.terminate()#关闭子线程self.thread.wait()self.main_ui.tableWidget.insertRow(0)self.main_ui.tableWidget.setSpan(0, 0, 1, 4)redBrush = QtGui.QBrush(QtGui.QColor(255, 0, 0))item = QtWidgets.QTableWidgetItem(str(datetime.datetime.now().strftime("%H:%M:%S")+':暂停筛选'))self.main_ui.tableWidget.setItem(0, 0, item)self.main_ui.tableWidget.item(0, 0).setForeground(redBrush)#在表格中插入一行,并写入提示信息。self.main_ui.btn_run.setText('开始筛选')self.main_ui.btn_run.setStyleSheet("background-color: rgb(255, 255, 255);")except:print(traceback.format_exc())

现在给出子线程类:

class thread_run(clac,QtCore.QThread):#clac是自定义的计算角度的类,会在后面介绍。_signal = pyqtSignal(str)def __init__(self,st_list,angle1,angle2,months,type):self.st_list=st_listif self.st_list==None:#如果没有设置目标股票,就默认筛选全部A股pro=ts.pro_api('你自己的tushare的token')self.st_list = list(pro.stock_basic(exchange='', list_status='L', fields='ts_code')['ts_code'])self.months=monthsself.angle1=angle1self.angle2=angle2self.type=typeQtCore.QThread.__init__(self)clac.__init__(self)def run(self):for st in self.st_list:try:angle=self.angle(st,self.months)#clac类的方法被继承过来。angle是一个元组,第一个值是回归线角度,第二个是两点连线角度print(angle)if  angle[0]>=self.angle1 and angle[0] <=self.angle2 and (self.type=='回归线' or self.type=='两者任一'):self._signal.emit(st+','+str(round(angle[0],4))+','+str(round(angle[1],4)))#筛选出一个满足条件的股票,将其数据作为信号发送给update函数time.sleep(0.5)continueif  angle[1]>=self.angle1 and angle[1] <=self.angle2 and (self.type=='两点连线' or self.type=='两者任一'):self._signal.emit(st+','+str(round(angle[0],4))+','+str(round(angle[1],4)))time.sleep(0.5)continueexcept:print(traceback.format_exc())self._signal.emit('finish')#全部的股票筛选完毕

待完善的工作

1.通过历史数据回测,得到结果最好的角度范围
2.第三种角度的计算方法:找在某一时间段内的最大角度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380860.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

量化投资:研报文本挖掘选股策略

核心观点: ●借力研报&#xff0c;打造开放的量化选股模型 传统的多因子量化选股模型是封闭的&#xff0c;缺乏捕捉市场热点的能力&#xff0c;通过大数据技术&#xff0c;从财经媒体和分析师研报中捕捉热点和政策的变化&#xff0c;可以打造开放的量化选股模型。 分析师个股…

Pytorch源码搜索与分析

PyTorch的的代码主要由C10、ATen、torch三大部分组成的。其中&#xff1a; C10 C10&#xff0c;来自于Caffe Tensor Library的缩写。这里存放的都是最基础的Tensor库的代码&#xff0c;可以运行在服务端和移动端。PyTorch目前正在将代码从ATen/core目录下迁移到C10中。C10的代…

利用Python+Gephi生成刀塔霸业棋子关系图

刀塔霸业版本&#xff1a;2019年7月24日 Gephi下载地址&#xff1a;Download 目录 代码 Gephi效果图 词云图 更新 代码 代码如下&#xff1a; # -*- coding: utf-8 -*- """ author: d0t4 date: 2019/7/29 desc: 生成刀塔霸业中各棋子的关系…

用狼的处世哲学做SOHO 一

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01; &#xff0d;&#xff0d;创业者要有象狼一…

P450进阶款无人机室内定位功能研测

在以往的Prometheus 450&#xff08;P450&#xff09;无人机上&#xff0c;我们搭载的是Intel Realsense T265定位模块&#xff0c;使用USB连接方式挂载到机载计算机allspark上&#xff0c;通过机载上SDK驱动T265运行并输出SLAM信息&#xff0c;以此来实现室内定位功能。 为进…

autocad全国计算机考试试题,2015年职称计算机考试试题:AutoCAD模拟题及答案

1. 画完一幅图后&#xff0c;在保存该图形文件时用_______作为扩展名。 A.cfg B.dwt C.bmp D.dwg 2. 要始终保持物体的颜色与图层的颜色一致&#xff0c;物体的颜色应设置为_______。 A.BYLAYER B.BYBLOCK C.COLOR D.RED 3. 在屏幕上用平移“PAN”命令将某图形沿X方向及Y方向各…

LibreCAD windows 编译

一、安装 VS2019&#xff0c;QT&#xff0c;QT VS 插件 二、boost下载 下载boost_1_71_0-msvc-14.2-64.exe文件(含源码和编译好的库) Boost C Libraries - Browse /boost-binaries/1.71.0 at SourceForge.netFree peer-reviewed portable C source librarieshttps://sourcef…

VBA for AutoCAD

Download the Microsoft Visual Basic for Applications Module (VBA) 2016 Downloads AutoCAD 2016 VBA module 32-bit (exe - 70206Kb)

cad.net开发

最近要做一个cad文件的7参数坐标转换的程序&#xff0c;想基于cad进行二次开发&#xff0c;初次学习。 为了方便快捷开发&#xff0c;基于cad.net进行二次开发&#xff0c;网上查了很多资料&#xff0c;有基于acad等各种&#xff0c;总是遇到这样那样的问题&#xff0c;经过自…

2022年03月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;双精度浮点数的输入输出 输入一个双精度浮点数&#xff0c;保留8位小数&#xff0c;输出这个浮点数。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 只有一行&#xff0c;一个双精度浮点数。 输出 一行&#xff0c;保留8位小数的浮点数。 样例输…

Michael.W基于Foundry精读Openzeppelin第24期——ERC165Storage.sol

0. 版本 [openzeppelin]&#xff1a;v4.8.3&#xff0c;[forge-std]&#xff1a;v1.5.6 0.1 ERC165Storage.sol Github: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/utils/introspection/ERC165Storage.sol ERC165Storage合约是ERC165…

【Java学习】System.Console使用

背景 在自学《Java核心技术卷1》的过程中看到了对System.Console的介绍&#xff0c;编写下列测试代码&#xff0c; public class ConsoleTest {public static void main(String[] args) {Console cs System.console();String name cs.readLine("AccountInfo: ");…

React UI组件库

1 流行的开源React UI组件库 1 material-ui(国外) 官网: Material UI: React components based on Material Design github: GitHub - mui/material-ui: MUI Core: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Go…

【网约车】 网约车管理解决方案

背景 自2014年7月以来&#xff0c;一些互联网企业陆续推出网络预约出租汽车服务&#xff0c;对于满足社会公众多样化、差异性出行需求发挥了积极作用。面对新一代信息技术的发展与相关行业的快速渗透&#xff0c;行业监管部门要顺应新技术和新应用的发展趋势&#xff0c;从促进…

Python实现微信小程序自动约车

目录 一、Fiddler抓取小程序包 二、分析抓到的包 一、获取全部车辆列表 二、获取班车停靠点 三、Python实现预约车辆 一、获取明天的日期 二、获取班车id 三、获取车辆停靠点 四、Server酱实现消息提示 四、利用宝塔面板&#xff0c;进行定时执行脚本&#xff0c;实现自动约…

微信小程序汽车租赁平台+后台管理系统

《微信小程序汽车租赁平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的汽车租赁前台和Java做的后台管理系统&#xff1a; 微信小程序——汽车租赁前台涉及技术&#xff1a;WXML 和 WXSS、JavaScript Ja…

有没有软件支持批量查询官方界面的快递号码

如果你想做好电子商务或物流行业&#xff0c;你一定不能虎头蛇尾。前端效率不够&#xff0c;必须做好后端的及时跟踪和维护。当大量快递以集中方式发出时&#xff0c;必须及时跟踪物流信息&#xff0c;掌握快递的动态。今天&#xff0c;小编将安利一个实用的辅助查询软件&#…

搭上锂电池公司Livent高速增长的顺风车

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 作为世界上为数不多的拥有完整产业链的锂生产商之一&#xff0c;Livent &#xff08;LTHM&#xff09;处于可以充分利用锂需求繁荣的位置。该公司正在做出明智的资本分配决策&#xff0c;继续扩大其上游和中游产能&#xf…

微信小程序使用物流查询插件

微信小程序使用物流查询插件 文章目录 微信小程序使用物流查询插件添加插件添加成功使用方式声明使用插件引入插件包 效果图 物流查询插件 添加插件 登录微信公众平台后台—>设置—>第三方设置—>添加插件搜索&#xff1a;物流服务 添加成功 使用方式 根据插件的开发…

顺丰快递单号查询接口物流路由跟踪信息快递鸟api对接教程

目录 1.完成前期准备工作2.API接口3.请求参数&#xff08;Headers&#xff09;4.请求参数&#xff08;Body&#xff09;5.返回参数&#xff08;Return&#xff09;6.请求完整报文&#xff08;示例&#xff09;7.成功返回报文&#xff08;示例&#xff09;8.失败返回报文&#x…