import numpy as np
import talib
import time
import jqdata
import talib
import smtplib
from email.mime.text import MIMEText
from email.header import Header
## 初始化函数,设定基准等等
def initialize(context):
#上海期货交易所产品
'''AG8888.XSGE 白银期货指数 PB8888.XSGE 铅期货指数
AU8888.XSGE 黄金期货指数 RB8888.XSGE 螺纹钢期货指数
AL8888.XSGE 铝期货指数 RU8888.XSGE 天然橡胶期货指数
BU8888.XSGE 石油沥青期货指数 SN8888.XSGE 锡期货指数
CU8888.XSGE 铜期货指数 WR8888.XSGE 线材期货指数
FU8888.XSGE 燃料油期货指数 ZN8888.XSGE 锌期货指数
HC8888.XSGE 热轧卷板期货指数 NI8888.XSGE 镍期货指数
SP8888.XSGE 纸浆主力合约
'''
g.stockkind='AG'
g.stockcode=str('AG9999.XSGE')
#g.stockkind='AU'
#g.stockkind='RB'
# 设定XX期货作为基准
set_benchmark('AG9999.XSGE')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
# log.set_level('order', 'error')
# 输出内容到日志 log.info()
log.info('初始函数开始运行且全局只运行一次')
# 开盘前运行
run_daily( before_market_open, time='09:00', reference_security='AG9999.XSGE')
### 期货相关设定 ###
# 设定账户为金融账户
set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='index_futures')])
# 期货类每笔交易时的手续费是:买入时万分之0.23,卖出时万分之0.23,平今仓为万分之23
set_order_cost(OrderCost(open_commission=0.000023, close_commission=0.000023,close_today_commission=0.0023), type='index_futures')
# 设定保证金比例
set_option('futures_margin_rate', 0.15)
# 设置期货交易的滑点
set_slippage(StepRelatedSlippage(2))
# 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'IF8888.CCFX'或'IH1602.CCFX'是一样的)
# 注意:before_open/open/close/after_close等相对时间不可用于有夜盘的交易品种,有夜盘的交易品种请指定绝对时间(如9:30)
## 开盘前运行函数
def before_market_open(context):
# 输出运行时间
log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))
# 给微信发送消息(添加模拟交易,并绑定微信生效)
# send_message('美好的一天~')
#stocklist=[]
## 获取主力合约
g.domin=get_dominant_future(g.stockkind, date=context.previous_date)
print (g.domin)
#买入信号
g.sign=0
#当日清仓标志
g.clear=0
## 开盘时运行函数
def handle_data(context,data):
log.info('函数运行时间(market_open):'+str(context.current_dt.time()))
timeArray = context.current_dt.time().strftime('%H:%M:%S')
#timeArray = time.strptime(context.current_dt.time(), "%H:%M:%S")
clocktime=int(str(timeArray)[-5:-3])
if clocktime % 5 == 0:
deal(context)
else:
pass
def deal(context):
## 交易
# 获取当月合约交割日期
end_data = get_CCFX_end_date(g.domin)
#判断g.sign 做macd交易判断
df=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='15m',fields='close')
df2=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='60m',fields='close')
df3=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='240m',fields='close')
df4=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='1d',fields='close')
macd_15min=macd(df['close'])[0]
macd_60min=macd(df2['close'])[0]
macd_1h=macd_60min
macd_4h=macd(df3['close'])[0]
macd_4h_diff=macd(df3['close'])[1]
macd_4h_dea=macd(df3['close'])[2]
macd_1d=macd(df4['close'])[0]
#print (macd_15min)
#print (macd_60min)
#止损清仓判断
if tralling_stop(context, g.stockcode)==1:
#止损多头
order_target(g.domin, 0, side='long')
g.sign=0
g.clear=1
elif tralling_stop(context, g.stockcode)==-1:
#止损空头
order_target(g.domin, 0, side='short')
g.sign=0
g.clear=-1
#开仓同时保证自己当日没有过当前方向的清仓
'''
if macd_15min[-1]>0 and macd_15min[-2]<=0 and macd_60min[-1]>0 and g.clear<1:
g.sign=1
elif macd_15min[-1]<0 and macd_15min[-2]>=0 and macd_60min[-1]<0 and g.clear>-1:
g.sign=-1
'''
'''
if macd_1h[-1]>0 and macd_1h[-2]<=0 and macd_1d[-1]>0 and g.clear<1:
g.sign=1
elif macd_1h[-1]<0 and macd_1h[-2]>=0 and macd_1d[-1]<0 and g.clear>-1:
g.sign=-1
'''
#单纯macd
if macd_4h[-1]>0>macd_4h[-2] and macd_4h_diff[-1]>0 and macd_4h_dea[-1]>0:
g.sign=1
elif macd_4h[-1]<0=0,开多仓
if (len(context.portfolio.short_positions) >= 0 and len(context.portfolio.long_positions) == 0):
log.info('开多仓---:')
if len(context.portfolio.short_positions) >0 :
# 平仓空头
order_target(g.domin, 0, side='short')
# 做多头合约
print('开多头合约')
if context.portfolio.available_cash>3500:
order_value(g.domin, 0.9*context.portfolio.available_cash , side='long')
g.sign=1
else:
print ('没钱开仓')
#空头交易
if (g.sign == -1):
if (context.current_dt.date() == end_data):
# return
pass
else:
#如果多仓>=0,开空仓
if (len(context.portfolio.short_positions) >= 0 and len(context.portfolio.long_positions) == 0):
log.info('开空仓---:')
if len(context.portfolio.long_positions) >0 :
# 平仓多头
order_target(g.domin, 0, side='long')
# 开空头合约
print('开空头合约')
if context.portfolio.available_cash>3500:
order_value(g.domin, 0.9*context.portfolio.available_cash , side='short')
g.sign=-1
else:
print ('没钱开仓')
else:
pass
def fasong(message,targetmail):
'''发送邮箱'''
sender = '[email protected]' #企业263邮箱
'''接收邮箱'''
receiver = targetmail
'''发送邮件主题'''
subject = 'message stock'
'''发送邮箱服务器'''
smtpserver = 'smtp.163.com'
'''发送邮箱用户/密码'''
username = '[email protected]'
password = 'XXXXX'
'''中文需参数‘utf-8’ ,单字节字符不需要'''
msg = MIMEText(message,'plain','utf-8')
msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = 'XX'
msg['To'] = targetmail
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
print ("Email has been sent out!")
########################## 获取期货合约信息,请保留 #################################
# 获取金融期货合约到期日
def get_CCFX_end_date(future_code):
# 获取金融期货合约到期日
return get_security_info(future_code).end_date
###############
def macd(close):
macdDIFF, macdDEA, macd = talib.MACDEXT(close, fastperiod=12, fastmatype=1, slowperiod=26, slowmatype=1, signalperiod=9, signalmatype=1)
macd = macd * 2
list1=[macd,macdDIFF,macdDEA]
return list1
def tralling_stop(context, stock_code):
ATR_timeperiod=14
# 获取stock_code股票的历史数据
Data_ATR=get_price(stock_code ,count=ATR_timeperiod+10, end_date=context.current_dt, frequency='15m',fields=['close','high','low'])
close_ATR = Data_ATR['close']
high_ATR = Data_ATR['high']
low_ATR = Data_ATR['low']
# 计算stock_code股票的AT
atr = talib.ATR(high_ATR, low_ATR, close_ATR)
highest20 = max(close_ATR[-20:])
lowest20 = min(close_ATR[-20:])
if ((highest20 - close_ATR[-1]) > (2*atr[-1])) and len(context.portfolio.long_positions) >0:
print('ATR多头止损')
return 1
elif ((close_ATR[-1] - lowest20 ) > (2*atr[-1])) and len(context.portfolio.short_positions) >0:
print('ATR空头止损')
return -1
else:
return 0