五、实现公式系统
- 1. 公式系统需求
- 2. 公式系统的实现
- 2.1 公式命名实现
- 2.2 公式系统实现
- 3. 总结
我们现在已经有了完整的历史数据,但是需要根据数据来筛选股票,一定要用到公式系统。
比如,我想实现下面的条件:
- 今天涨幅大于5%
- 今天的成交量比过去5天成交量平均值(又叫量比)多3倍
- 今天的成交量比过去30天成交量最大值大2倍以上
每次都从新写程序是不可能的,所以需要定义一个公式命名规则,系统只是实现规则就行。
我们来整理一下规则的需求:
- 所有的计算结果都是同一天的计算结果。
就是说某一天的所有的计算结果都要汇集到同一天,比如收盘价,昨天收盘价的信息也要放到今天来。
- 所有的命名都是直接命名。
如昨天收盘价定义为PRECLOSE,而不要定义为DAY(-1).CLOSE,命名和公式实现要分开。
好了,我们定义一下基本命名:
- 开盘 OPEN
- 最高 HIGH
- 最低 LOW
- 收盘 CLOSE
- 成交量 VOLUME
- 成交额 AMOUNT
需要在这个基础上实现如下扩充:
- 当日数据计算,如计算今天平均价
- 之前数据读取,如读取昨天收盘
- 多个数据平均值,如最近5天收盘的平均值(MA5)
- 多个数据最大值,如过去30天成交量最大值
- 多个数据最小值,如过去30天最低的最小值
- 某个条件计数,如连续上涨5天的天数
公式系统的核心就是公式命名和公式之间调用,比如:
定义了昨收PRECLOSE = DAY(-1).CLOSE
定义涨跌幅 GAINRATE = (CLOSE-PRECLOSE)/PRECLOSE
这里核心是计算如何能使用CLOSE和PRECLOSE,这在系统中是变量啊!
对呀,是变量啊,那就使用变量。
在Python试试:
Python 3.9.10 (tags/v3.9.10:f2f3f53, Jan 17 2022, 15:14:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exec("a=1")
>>> a
1
>>>
好了,剩下就是力气活了。
使用ini文件输入公式。
[Formula 1]
Name = TURNOVER
Type= 0
Formula = VOLUME/SHARE
[Formula 2]
Name = PRECLOSE
Type= 1
Offset = -1
Formula = CLOSE
[Formula 3]
Name = GAINRATE
Type= 0
Formula = (CLOSE/PRECLOSE-1)*100
根据不同Type进行计算。
for formula in self.FormulaList:
formulaName = formula[0]
formulaType = int(formula[1])
if (formulaType == 0): # 直接计算
try:
exec('{0}={1}'.format(formulaName, formula[2]))
data[formulaName] = eval(formulaName)
except:
pass
elif (formulaType == 1): # 获取数据,不计算
offset = int(formula[2])
if ((pos+offset) >= 0):
self.dataList[pos][formulaName] = self.dataList[pos + offset][formula[3]]
elif (formulaType == 2): # 计算平均值
begin = int(formula[2])
end = int(formula[3])
if ((pos+begin) >= 0):
calcValue = 0
for i in range(pos+begin, pos+end+1):
calcValue += self.dataList[i].get(formula[4], 0)
calcValue /= (end-begin+1)
self.dataList[pos][formulaName] = calcValue
elif (formulaType == 3): # 计算最大值
begin = int(formula[2])
end = int(formula[3])
MINVALUE = -1
calcValue = MINVALUE
for i in range(max(0, pos+begin), min(dataLen, pos+end+1)):
calcValue = max(
calcValue, self.dataList[i].get(formula[4], MINVALUE))
if (calcValue > MINVALUE):
self.dataList[pos][formulaName] = calcValue
elif (formulaType == 4): # 计算最小值
begin = int(formula[2])
end = int(formula[3])
MAXVALUE = 10000000
calcValue = MAXVALUE
for i in range(max(0, pos+begin), min(dataLen, pos+end+1)):
calcValue = min(
calcValue, self.dataList[i].get(formula[4], MAXVALUE))
if (calcValue < MAXVALUE):
self.dataList[pos][formulaName] = calcValue
elif(formulaType == 5): # 计算条件计数值
calcValue = 0
for i in range(pos-1, 0, -1):
if (self.dataList[i].get(formula[2], False)):
calcValue += 1
else:
break
self.dataList[pos][formulaName] = calcValue
3. 总结
已经可以根据公式计算出符合条件的股票,接下来要做的工作:
- 在界面中显示股票列表,同时显示选中的K线图
- 导出csv格式
- 演算成功率,微调公式
作为软件系统已经结束了,剩下的工作大家努力了。
本专栏已经结束,放弃接下来的内容了,剩下的是常规内容了!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)