用Tkinter打造自己的Python IDE开发工具(7)变量数据共享机制及小白量化策略编写 首先我设计的HP_开头的系列Python模块及源文件目前不开源,所有源文件只对读者自己使用学习,不得放到网上公开,所有HP_开头的源代码已经申请了软著.如果用于自己出售产品,需要支付一定费用. 很多读者将源代码名字由HP_开头,更换为其他文件名及模块开头,如用于商业行为,我们将追责. 上一片介绍了Python多文件共享变量与智能插件设计,我在开发定制量化程序时,发现与现有量化习惯出现冲突。 在量化策略编写中,以g.开头的变量作为全局变量。
#一个简单但是完整的量化策略:
def initialize(context):
# 定义一个全局变量, 保存要操作的股票
g.security = '000001.XSHE'
# 运行函数
run_daily(market_open, time='every_bar')
def market_open(context):
if g.security not in context.portfolio.positions:
order(g.security, 1000)
else:
order(g.security, -800)
这明显与上一篇文章介绍的使用文件模块域别名冲突。 小白量化2代使用如下定义。
import HP_global as g #建立全局数据域
因此,我们修改改为hg,小白研学实控系统(也称小白量化3金融模块),使用如下定义。
import HP_global as hg #建立全局数据域hg
那么怎么实现量化软件全局变量g.的定义呢? 我们在HP_quant.py模块中,使用如下方法来实现。
class GlobalVars(object):
'''用户全局变量g.处理模块'''
pass
在量化策略开始文件,或策略执行文件中使用如下命令,进行初始化。
g=GlobalVars()
后面就可以在策略文件或程序模块中使用g.开头的全局变量,实现在不同函数间的数据共享。 用类做为全局变量的好处:使用方便,任何函数都可以动态创建新的全局变量,供同一个模块的其他函数或类来使用。不能跨模块文件使用。 用类做为全局变量的不好处:全局类共享变量,只有设计者清楚,使用者很难理解和调试数据。 程序终止后,共享数据信息就消失了,当然设计者为了加密等特殊用途除外。 读者有空可以试试这2中全局变量定义的使用。 我目前利用这个金融模块设计的软件演示图如下。 下面是给朋友定做的量化软件。 策略框架编写,类似流行量化软件的格式。支持小白量化所有金融模块,可以使用仿股票公式或股票公式,下面是一个KDJ指标交易的策略示例。采用kdj指标交叉做买点,使用自动回撤止赢做止赢(卖点),-5%进行止损。
策略名='回测_KDJ自动交易'
import pandas as pd
import HP_tdx as htdx ##行情
from HP_formula import * #指标公式库
from HP_factor import * #因子公式库
import HP_formula as gs #指标公式库
import HP_quant as hpq #量化框架
from HP_quant import * #量化框架
import time
def initialize(context):
context.firstcash=1000000.00 #初始现金
context.cash=context.firstcash
context.portfolio.available_cash=context.firstcash
#回测区间
#hpq.test_date_start='2022-04-12 09:30:00'
#hpq.test_date_end='2018-12-31 15:00:00'
#hpq.test_date_end=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
# 初始化此策略
htdx.TdxInit(ip='40.73.76.10',port=7709)
# 设置我们要操作的股票池
##E:\changjiang\T0002\blocknew
#g.stocks = htdx.getzxgfile('E:\\changjiang\\T0002\\blocknew\\gpc20220317.blk')
#g.stocks = htdx.getzxgfile('C:\\zd_gfzq\\T0002\\blocknew\\gpc20220317.blk')
#g.stocks = htdx.getzxgfile('GPC20220317.blk')
#g.stocks=[(1, '600080'), (1, '600030'), (0, '000776'), (0, '000519'),(0,'000055'),(0,'000048'),(1,'603070')]
g.stocks=hpq.get_universe()
hpq.log.info('----开始回测-----\n股票池:')
#hpq.log.info(g.stocks)
#
#hpq.set_universe(g.stocks) ##设置股票池
# 设定沪深300作为基准
set_benchmark((1,'000001'))
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次
def handle_data(context, data):
# 循环每只股票
zs=0.05 #止损幅度
hd=0.002 #滑点比例
for m,security in context.universe[0]:
df=data[security].df
if len(df)<1:
continue
price = data[security].close
close=price
high= data[security].high
low= data[security].low
pre_close=data[security].pre_close
value = context.portfolio.positions[security].value
acc_avg_cost = context.portfolio.positions[security].acc_avg_cost
amos=context.portfolio.positions[security].total_amount
if amos>0 and context.onlybuy==False:
pp=price-acc_avg_cost
hc2=huichex(security,pp,99)
yl=huichemax(security)
yl2=(yl-acc_avg_cost)/acc_avg_cost
if yl2>=0.1:
hcd=0.03+yl2/10
dtzf=(high-price)/pre_close
hpq.log.info(context.current_dt+' 代码: %s,持仓:%d,回撤:%.3f,最高:%.2f,现价:%.2f,成本价:%.2f,最大获利:%.2f,现价获利:%.2f,市值:%0.2f'%(security,amos,hc2,high,price,acc_avg_cost,yl,pp,amos*price))
pm=yl*0.69
#pn=pm+acc_avg_cost
pn=(high+close)/2
pl=(acc_avg_cost-low)/acc_avg_cost
if pl>=zs: #止损
price2=acc_avg_cost*(1-zs)*(1-hd)
if price2>high:
price2=high*(1-hd)
x=order_target(security,0,p=price2)
# 记录这次卖出
hpq.log.info(context.current_dt+" 止损: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,x.amount,price2,x.amount*price2))
elif pp<pm and pm>=price*0.006 and yl2<0.1: #盘中回撤
pn=pn*(1-hd)
x=order_target(security,0,p=pn)
# 记录这次卖出
hpq.log.info(context.current_dt+" 盘中卖出: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,x.amount,pn,x.amount*pn))
elif hc2>0.3 and pp>=price*0.05: ##利润回撤30%以上,(a)股价小于30元且盈利为股价1%,
x=order_target(security,0)
## 记录这次卖出
hpq.log.info(context.current_dt+" 卖出: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,x.amount,price,x.amount*price))
try:
df=data[security].df
if len(df)<1:
continue
if security[0:3]=='300':
X=0.1
else:
X=0.08
mydf=gs.initmydf(df) ##初始化mydf表
CLOSE=gs.CLOSE
C=gs.C
O=gs.O
L=gs.L
H=gs.H
V=gs.V
LOW=gs.LOW
HIGH=gs.HIGH
OPEN=gs.OPEN
VOL=gs.VOL
LC=REF(C,1); #昨日收盘
ZF=(C-LC)/LC
#KDJ():
N=9
M1=3
M2=3
RSV = (CLOSE - LLV(LOW, N)) / (HHV(HIGH, N) - LLV(LOW, N)) * 100
K = SMA(RSV,M1,1)
D = SMA(K,M2,1)
J = 3*K-2*D
B=CROSS(J,K)
# 得到上一时间点股票收盘价
price = data[security].close
# 得到当前资金余额
cash = context.portfolio.available_cash
# 如果上一时间点价格大于三天平均价*1.005,并且有现金余额,买入
if list(B)[-1]>0 and cash > 0 and context.portfolio.positions[security].closeable_amount == 0 and ZF.iloc[-1]<0.095:
##下入买入单
xdzj=200000
price2=price*(1+hd)
x=order_value(security,xdzj,p=price2)
hc2=huichex(security,0.00,99,s=1)
if x !=None:
hpq.log.info(context.current_dt+" 买入: %s ,数量:%d,买入价格:%.2f,成交资金:%0.2f"%(security,x.amount,price,x.amount*price))
except Exception as e:
print('出错:',e)
hpq.log.info(context.current_dt+" 警告错误:%s"%e)
(实盘视频) 量化策略自动运行的视频。 上面策略的回测收益图,2021-01-02至2022-07-05,收益越100%,对比基准为沪深300指数。 (回测收益图) (实盘截图)
好了,欢迎继续关注我的博客。
超越自己是我的每一步!我的进步就是你的进步!
|