小白量化《穿云箭集群量化》(9)用指标公式实现miniQMT全自动交易
在穿云箭量化平台中,支持3中公式源码运行模式,还支持在Python策略中使用仿指标公式源码运行,编写策略。
我们先看如何使用指标公式源码。
#编程_直接使用通达信自编指标公式显示K线指标
import os,sys
sys.path.append(os.path.abspath('.'))
sys.path.append(os.path.abspath('..'))
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import HP_tdx as htdx#小白通达信行情库
from HP_formula import * #小白股票指标公式函数库
import HP_tdxgs as hgs #小白通达信公式库
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
tdxapi=htdx.TdxInit(ip='180.153.18.171')
code='600019'
df=hgs.get_security_bars(nCategory=4,nMarket = -1,code=code)
print(df)
#df.to_csv( "股票数据源.csv" , encoding= 'gbk')
#df2=pd.read_csv("股票数据源.csv" , encoding= 'gbk')
#KDJ指标
gs='''
N:=9;
M1:=3;
M2:=3;
RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;
K:SMA(RSV,M1,1), CIRCLEDOT,COLORFF0000,LINETHICK2;
D:SMA(K,M2,1), LINETHICK3 , COLOR00FF00 ;
J:3*K-2*D, LINETHICK2, COLOR0000FF;
'''
#MACD指标
gs2='''
SHORT:=12;
LONG:=26;
MID:=9;
DIF:EMA(CLOSE,SHORT)-EMA(CLOSE,LONG);
DEA:EMA(DIF,MID);
MACD2:(DIF-DEA)*2,COLORSTICK;
'''
#LHXJ 猎狐先觉
gs3='''
VAR1=(CLOSE*2+HIGH+LOW)/4;
VAR2=EMA(VAR1,13)-EMA(VAR1,34);
VAR3=EMA(VAR2,5);
ZLQP:(-2)*(VAR2-VAR3)*3.8;
ZLKP:2*(VAR2-VAR3)*3.8;
'''
#绘制图形
plt.figure(1,figsize=(10,6), dpi=100)
#绘制主图指标
ax1=plt.subplot(311)
#绘制副图指标
ax2=plt.subplot(312)
#绘制副图指标
ax3=plt.subplot(313)
tgs1=hgs.Tdxgs()
tgs1.loaddf(df)
mydf=tgs1.rungs(gs)
print('KDJ指标:\n',gs)
print('公式变量:',tgs1.bl)
print('输出变量:',tgs1.bl2)
tgs1.brawline(ax1)
print(mydf)
#mydf.to_csv( "股票数据KDJ返回结果.csv" , encoding= 'gbk')
#mydf2=pd.read_csv("股票数据KDJ返回结果.csv" , encoding= 'gbk')
#print(gs2)
tgs2=hgs.Tdxgs()
tgs2.loaddf(df)
mydf2=tgs2.rungs(gs2)
tgs2.brawline(ax2)
#print(gs2)
tgs3=hgs.Tdxgs()
tgs3.loaddf(df)
mydf3=tgs3.rungs(gs3)
tgs3.brawline(ax3)
plt.show()
程序运行结果,
我们可以在穿云箭量化平台上使用指标公式源码一键生成easytrader策略和miniQMT自动交易策略。
我们可以直接使用有买卖信号的专家系统公式,也可以自定义BUY和SELL信号,也支持B和S交易信号。
上图是通达信KD专家系统公式,我们点按钮显示图形,能够正常显示买卖信号。
我们直接点【生成miniQMT交易】按钮,生成miniQMT全自动交易策略源代码,源代码如下,用户只要修改程序路径和用户,就可以直接在穿云箭量化软件高级版面中进行实盘。
也可以将策略中的自编指标,更换为其他自编公式源码。
策略名='高级_miniQMT公式策略'
import pandas as pd
import time,os
import HP_tdx as htdx #小白量化行情模块
import HP_global as hg #建立高级全局数据域hg
from HP_formula import * #小白量化公式模块
from HP_factor import * #小白量化因子公式及Alpha公式模块
import HP_factor as hf #小白量化因子公式及Alpha公式模块
import HP_formula as gs #小白量化公式模块
import HP_quant as hpq #穿云箭量化模块
from HP_quant import * #穿云箭量化模块
import HP_tdx as htdx #通达信行情模块
import HP_tdxgs as tgs #公式运行模块
import random, time, logging, datetime, json, akshare
from xtquant import xtdata, xttrader, xtconstant
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
import HP_xbdata as hpx
import HP_mqmt as hqmt
trader = hqmt.Trader()
##########修改帐户信息########################
qmt_path='D:\\华宝证券QMT实盘交易端'
account_id = ""
#############################################
session_id = random.randint(20000, 60000)
qmt_dir = qmt_path + '\\userdata_mini'
account_type = "STOCK" # 账号类型,可选STOCK、CREDIT
xtdata.data_dir = qmt_path + '\\datadir'
connect_result = trader.set_trader(qmt_dir, session_id)
trader.set_account(account_id, account_type=account_type)
print("交易连接成功!") if connect_result == 0 else print("交易连接失败!")
mygs=tgs.Tdxgs()
def initialize(context):
#context.istest=True
context.zh='xiaoba' #账户
context.zhlx='回测' #账户类型,2个汉字
context.firstcash=1000000.00 #初始现金
context.cash=context.firstcash
context.portfolio.available_cash=context.firstcash
# 设置我们要操作的股票池
#g.stocks=hpq.get_universe()
#g.stocks=['000001.SZ','000776.SZ','600030.SH']
#codes=htdx.getzxgfile('G2022X500.blk')
codes=hpq.get_universe()
g.cwsj={} #财务数据
codes2=[]
for m,c in codes:
if m==0:
cc=c+'.SZ'
elif m==1:
cc=c+'.SH'
codes2.append(cc)
cw=xtdata.get_instrument_detail(cc)
g.cwsj[cc]=cw
#print(m,cc,cw)
g.stocks=codes2
hpq.set_universe(g.stocks)
hpq.log.info('----策略环境信息-----')
print('量化模块版本: ',hpq.ver)
print('量化模块最后修改日期: ',hpq.mdate)
print('svrip: ',hpq.svrip)
print('svrport: ',hpq.svrport)
print('\n----开始运行策略-----\n')
print('策略名:'+策略名)
qhcsj2=time.strftime('%Y%m%d %H:%M:%S',time.localtime(time.time()))
print('开始运行时间:'+qhcsj2)
# 设定基准
set_benchmark('000001.SH')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
set_times(6) #设置多少圈读一次持仓
hg.hqsl=0 #行情数量
hg.seemsg=False
asset = trader.xt_trader.query_stock_asset(trader.account)
context.portfolio.total_value=asset.total_asset #总资产
context.portfolio.available_cash=asset.cash #'可用金额'
context.portfolio.positions_value=asset.market_value #'股票市值'
context.portfolio.locked_cash=asset.frozen_cash #冻结金额
holding=hqmt.query_holding(trader)
g.zstime=datetime.datetime.now()
g.codezs=[]
g.holds=[] #持仓证券代码
print(asset.total_asset,asset.cash)
for i in range(len(holding)):
股票代码=holding[i][0]['股票代码']
g.holds.append(股票代码)
if 股票代码 not in context.portfolio.positions:
context.portfolio.positions[股票代码]=hpq.Position(股票代码)
context.portfolio.positions[股票代码].total_amount=holding[i][0]['持仓']
context.portfolio.positions[股票代码].closeable_amount=holding[i][0]['可用持仓']
context.portfolio.positions[股票代码].acc_avg_cost=holding[i][0]['成本']
context.portfolio.positions[股票代码].value=holding[i][0]['持仓市值']
context.ccs=g.holds
hpq.context=context
g.MAX=50
g.hd=0.003 #滑点
g.zsfd=-0.03 #止损幅度
g.amount=100 #买入数量
g.xdzj=10000.00 #买入金额,下单资金
g.cs=0 #策略运行次数
#中文Python学习交流群 934165481
g.gs='''{自编指标公式,最好用专家系统公式}
N:=9;
M1:=3;
RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;
K:=SMA(RSV,M1,1);
D:=SMA(K,M1,1);
J:=3*K-2*D;
ENTERLONG:CROSS(J,D);
EXITLONG:CROSS(D,J);
'''
# 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次
def market_open(context):
starttime = datetime.datetime.now()
g.cs=g.cs+1
#开始撤单
if g.cs%2==1:
wtc=hqmt.query_order(trader,'') #获取委托池
for i in range(len(wtc)):
wt=wtc[i]
if wt['委托状态']=='已报' or wt['委托状态']=='部分成交':
订单编号=wt['订单编号']
hqmt.trade_cancel_order(trader,订单编号)
##获取账户资金
asset = trader.xt_trader.query_stock_asset(trader.account)
context.portfolio.total_value=asset.total_asset #总资产
context.portfolio.available_cash=asset.cash #'可用金额'
context.portfolio.positions_value=asset.market_value #'股票市值'
context.portfolio.locked_cash=asset.frozen_cash #冻结金额
##获取持仓
holding=hqmt.query_holding(trader)
print(len(holding))
g.holds=[] #持仓证券代码
for i in range(len(holding)):
security=股票代码=holding[i][0]['股票代码']
g.holds.append(股票代码)
tick=hqmt.get_tick_data(股票代码)
price=tick['lastPrice']
if 股票代码 not in context.portfolio.positions:
context.portfolio.positions[股票代码]=hpq.Position(股票代码)
context.portfolio.positions[股票代码].total_amount=holding[i][0]['持仓']
context.portfolio.positions[股票代码].closeable_amount=holding[i][0]['可用持仓']
context.portfolio.positions[股票代码].acc_avg_cost=holding[i][0]['成本']
context.portfolio.positions[股票代码].value=holding[i][0]['持仓市值']
context.portfolio.positions[股票代码].price=price
context.portfolio.positions[股票代码].issell=False
context.portfolio.positions[股票代码].isbuy=False
else:
context.portfolio.positions[股票代码].total_amount=holding[i][0]['持仓']
context.portfolio.positions[股票代码].closeable_amount=holding[i][0]['可用持仓']
context.portfolio.positions[股票代码].acc_avg_cost=holding[i][0]['成本']
context.portfolio.positions[股票代码].value=holding[i][0]['持仓市值']
context.portfolio.positions[股票代码].price=price
context.portfolio.positions[股票代码].issell=False
context.portfolio.positions[股票代码].isbuy=False
amos=holding[i][0]['可用持仓']
acc_avg_cost=context.portfolio.positions[股票代码].acc_avg_cost
#df=hqmt.get_day_line(security)
df=hqmt.get_day_line(security)
price = df.close.iloc[-1]
if security not in g.cwsj:
cw=xtdata.get_instrument_detail(security)
g.cwsj[security]=cw
if amos>0:
##响尾蛇导弹,自动止损和回撤止盈
sell=hf.autosell(security,price=price,cost=acc_avg_cost,withdraw=0.3,stoploss=g.zsfd,minp=0.02,t=99999)
if sell==2: #止损
p5=round(price*(1-g.hd),2)
x=order_target(security,0,p=p5)
hpq.log.info(context.current_dt+ " 止损卖出: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,amos,p5,amos*p5))
print(security,p5,amos,price)
time.sleep(0.1)
order_id = trader.xt_trader.order_stock(trader.account,security, xtconstant.STOCK_SELL,amos, xtconstant.FIX_PRICE, p5, '策略TTMJ', '止损')
context.portfolio.positions[security].sellprice=p5
context.portfolio.positions[security].issellprice=True
context.portfolio.positions[security].total_amount=0
context.portfolio.positions[security].closeable_amount=0
elif sell==1: #止盈
p5=round(price*(1-g.hd),2)
x=order_target(security,0,p=p5)
hpq.log.info(context.current_dt+ " 止盈卖出: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,amos,p5,amos*p5))
print(security,p5,amos,price)
time.sleep(0.1)
order_id = trader.xt_trader.order_stock(trader.account,security, xtconstant.STOCK_SELL,amos, xtconstant.FIX_PRICE, p5, '策略TTMJ', '止盈')
context.portfolio.positions[security].sellprice=p5
context.portfolio.positions[security].issellprice=True
context.portfolio.positions[security].total_amount=0
context.portfolio.positions[security].closeable_amount=0
df=hqmt.get_day_line(security)
if len(df)<1:
continue
price = df.close.iloc[-1]
close=price
high= df.high.iloc[-1]
low= df.low.iloc[-1]
#value = context.portfolio.positions[security].value
acc_avg_cost = context.portfolio.positions[security].acc_avg_cost #买入成本价
amos=context.portfolio.positions[security].closeable_amount #可卖数量
amos2=context.portfolio.positions[security].total_amount #总数量
CAPTIAL=df['capital']=g.cwsj[security]['FloatVolume']
mydf=gs.initmydf(df) ##初始化mydf表
C=CLOSE=gs.CLOSE
L=LOW=gs.LOW
H=HIGH=gs.HIGH
O=OPEN=gs.OPEN
V=VOL=mydf['volume']
AMO=AMOUNT=mydf['amount']
CAPTIAL=mydf['capital']=g.cwsj[security]['FloatVolume']
HSL=V/CAPTIAL ##换手率
pre_close=CLOSE.iloc[-1] #前收盘
ZX=AMO/(V+0.00001)/100
BL=(C-ZX)/(ZX+0.00001)
mydf=gs.initmydf(df) ##初始化mydf表
mygs.loaddf(mydf) #加载行情数据
mydf=mygs.execgs(g.gs) #运行指标公式
if 'ENTERLONG' in mydf.columns:
BUY=mydf['ENTERLONG'] #买点
elif 'BUY' in mydf.columns:
BUY=mydf['BUY'] #买点
elif 'B' in mydf.columns:
BUY=mydf['B'] #买点
if 'EXITLONG' in mydf.columns:
SELL=mydf['EXITLONG'] #卖点
elif 'SELL' in mydf.columns:
SELL=mydf['SELL'] #卖点
elif 'S' in mydf.columns:
SELL=mydf['S'] #卖点
cash=context.portfolio.available_cash #资金余额
if BUY>0 and amos2==0 and context.portfolio.positions[security].isbuy==False and context.onlysell==False : #保留资金
price2=round(price*(1+g.hd),2)
amount=g.xdzj/price2
g.amount=int(amount/100)*100
x=order_target(security,g.amount,p=price2)
context.portfolio.positions[security].isbuy=True
order_id = trader.xt_trader.order_stock(trader.account,security, xtconstant.STOCK_BUY, g.amount, xtconstant.FIX_PRICE, price2, 'strategy_name', 'remark')
context.portfolio.positions[security].total_amount=g.amount
if x !=None:
hpq.log.info(context.current_dt+" 买入: %s ,数量:%d,买入价格:%.2f,成交资金:%0.2f"%(security,x.amount,price,x.amount*price))
amos=context.portfolio.positions[security].closeable_amount #可卖数量
if SELL>0 and amos>0 and context.onlybuy==False:
price2=round(price*(1-g.hd),2)
x=order_target(security,0,p=price2)
context.portfolio.positions[security].issell=True
order_id = trader.xt_trader.order_stock(trader.account,security, xtconstant.STOCK_SELL, amos, xtconstant.FIX_PRICE, price2, 'strategy_name', 'remark')
hpq.log.info(context.current_dt+ " 卖出: %s ,数量:%d,卖出价格:%.2f,成交资金:%0.2f"%(security,amos,price2,amos*price2))
context.portfolio.positions[security].total_amount=0
endtime = datetime.datetime.now()
costtime=(endtime - starttime).seconds
t1=costtime-int(costtime/60)*60
t2=int(costtime/60)-int(int(costtime/60)/60)*60
t3=int(int(costtime/60)/60)
print('花费时间:%d:%d:%d'%(t3,t2,t1))
上面给了出了使用指标公式实现miniQMT全自动交易,如果没有miniQMT,也可以生成easytrader自动交易策略。
后面我们将介绍更多的量化交易技术。
超越自己是我的每一步!我的进步就是你的进步!