黑马程序员技术交流社区

标题: 交流贴 [打印本页]

作者: 魁拔之魂    时间: 2019-6-14 20:08
标题: 交流贴

老听说金字塔支持Python了,而且很牛X,一直想了解一下,就边学边玩,写了一个网格交易的策略,经过验证,还不错,金字塔的Python版用于算法交易还是可以,从交易下单,到成交过程订单状态的回报,都很准确。
相对于VBA使用对象的方式来调用,Python更直观,简洁。

需要增强的地方(可能我还没学会):
1、希望增加对INI文件读写的功能,我使用import ConfigParser不支持
2、希望增加对界面方面的支持,Python有支持图形的库
--------------------------------------------------------------

# 本Python代码主要用于策略交易
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
from PythonApi import *
import time
from decimal import Decimal

#  参数定义区,这里定义的参数可以直接在context对象中获取。--(选择实现)
#def parameter():
#    input_par("myvalues1",5,1,20,1)
#    input_par("myvalues2",10,1,20,1)


#  在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。--(必须实现)
def init(context):
    # 在context中保存全局变量
    context.s1 = "ZQZC05"   #动力煤
    context.lastbuy=0         #末次买入开仓单号
    context.lastsell=0        #末次卖出开仓单号
    context.lastbuyping=0   #末次平多单单号
    context.lastsellping=0  #末次平空单单号
    context.jiange=1        #间隔
    context.vol=1           #每档手数
    context.firstvol=5      #初始手数
    context.fx=1            #交易方向 1-多 2-空
    context.price=561.2       #初始参考价
    context.maxvol=8*context.vol    #最大手数
    settimer(GridTrade,2000)        #2秒执行一次
   
    print(context.s1+"策略启动") #调试打印输出
   
def setorderid(context):
    #检查未成交订单,将单号赋值给全局变量,避免启动策略时变量的值为0
    #print("获取未成交订单编号")
    Orders=get_orders(context.s1,0)    #取未成交单
    context.lastbuy=0
    context.lastbuyping=0
    context.lastsell=0
    context.lastsellping=0
    if not(Orders == None):
        for order in Orders:
            orderID=order.order_id    #委托单号
            sBuySell=order.side                #买卖
            sKp=order.position_effect        #开平
            sStatus=order.status             #状态
            #print(str(orderID)+','+sBuySell+','+sKp+','+sStatus)
            if context.lastbuy==0 and sBuySell=="buy" and sKp=="open" and sStatus=="submitted":
                context.lastbuy=order.order_id    #单号
            if context.lastsell==0 and sBuySell=="sell" and sKp=="open" and sStatus=="submitted":
                context.lastsell=order.order_id    #单号
            if context.lastbuyping==0 and sBuySell=="sell" and sKp=="close" and sStatus=="submitted":
                context.lastbuyping=order.order_id    #单号
            if context.lastsellping==0 and sBuySell=="buy" and sKp=="close" and sStatus=="submitted":
                context.lastsellping=order.order_id    #单号
            
        #print('开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))

#网格交易主程序     
def GridTrade(context):   
    if istradertime(context.s1)==False:    #不在交易时间,不进入交易段
        return
        
    setorderid(context)           #获取未成交订单号,保存到全局变量

    nAmount=get_account(19)    #可用资金
    if nAmount<=10000:
        print('账户可用资金低于10000了,退出交易。')
        return
            
    portfolio=get_portfolio(context.s1,0)    #获取持仓量
    if context.fx==1:
        iDuoTotal=portfolio.buy_quantity
        nCurOrdPrice = round(context.price - ((iDuoTotal -context.firstvol) * context.jiange) / context.vol, 1)
    else:
        iKongTotal=portfolio.sell_quantity
        nCurOrdPrice = round(context.price - ((context.firstvol - iKongTotal) * context.jiange) / context.vol, 1)
        
    #print('档位价:'+str(nCurOrdPrice)+',开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))
               
    nPrice=get_dynainf (context.s1,7)    #获取最新价
    if context.fx==1:    #做多
        if (context.lastbuy==0 and iDuoTotal<context.maxvol):
            nOrdPrice=nCurOrdPrice-context.jiange
            context.lastbuy=buy_open(context.s1,"Limit",nOrdPrice,context.vol)
            print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',开多')
        if (context.lastbuyping==0 and iDuoTotal>0):
            nOrdPrice=nCurOrdPrice+context.jiange
            context.lastbuyping=sell_close(context.s1,"Limit",nOrdPrice,context.vol)
            print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',平多')
    if context.fx==2 and iKongTotal<context.maxvol:    #做空
        if (context.lastsell==0):
            nOrdPrice=nCurOrdPrice+context.jiange
            context.lastsell=sell_open(context.s1,"Limit",nOrdPrice,context.vol)
            print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',开空')
        if (context.lastsellping==0 and iKongTotal>0):
            nOrdPrice=nCurOrdPrice-context.jiange
            context.lastsellping=buy_close(context.s1,"Limit",nOrdPrice,context.vol)
            print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',平空')
            
# before_trading此函数会在每天基准合约的策略交易开始前被调用,当天只会被调用一次。--(选择实现)
def before_trading(context):
    pass


# 你选择的品种的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新。--(必须实现)
def handle_bar(context):
    # 开始编写你的主要的算法逻辑。
    pass
   
   
# after_trading函数会在每天交易结束后被调用,当天只会被调用一次。 --(选择实现)
def after_trading(context):
    pass
   
# order_status当委托下单,成交,撤单等与下单有关的动作时,该方法就会被调用。---(选择实现)
def order_status(context,order):
    #print('订单成交')
    #print(order.order_book_id)
    #print(str(order.order_id)+','+order.status+','+order.order_book_id)
    #print('开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))
    #如果是成交,将对应的委托单撤销
    if (order.status=="tradeing" and order.order_book_id==context.s1):
        print(str(order.order_id)+'全部成交')
        if order.order_id==context.lastbuy:        #买入成交
            if context.lastbuyping!=0:
                cancel_order (context.lastbuyping)
                print("买入成交之后撤平仓单,"+str(context.lastbuyping))
                context.lastbuyping=0
        if order.order_id==context.lastbuyping:    #平多成交
            if context.lastbuy!=0:
                cancel_order (context.lastbuy)
                print("平多成交之后撤开仓单,"+str(context.lastbuy))
                context.lastbuy=0
        if order.order_id==context.lastsell:        #卖出成交
            if context.lastsellping!=0:
                cancel_order (context.lastsellping)
                print("卖出成交之后撤平仓单,"+str(context.lastsellping))
                context.lastsellping=0
               
        if order.order_id==context.lastsellping:    #平空成交
            if context.lastsell!=0:
                cancel_order (context.lastsell)
                print("平空成交之后撤开仓单,"+str(context.lastsell))
                context.lastsell=0
   
    #如果是撤单,将对应的变量设置为0            
    if (order.status=="cancelled" and order.order_book_id==context.s1):
        if order.order_id==context.lastbuy:        #买入撤单
            print("买入开仓撤单,"+str(context.lastbuy))
            context.lastbuy=0
        if order.order_id==context.lastbuyping:    #平多撤单
            print("平多单撤单,"+str(context.lastbuyping))
            context.lastbuyping=0
        if order.order_id==context.lastsell:       #卖出撤单
            print("卖出开仓撤单,"+str(context.lastsell))
            context.lastsell=0
        if order.order_id==context.lastsellping:   #平空撤单
            print("平空单撤单,"+str(context.lastsellping))
            context.lastsellping=0
            
            
                           

# order_action当查询交易接口信息时返回的通知---(选择实现)
#def order_action(context,type, account, datas)
#       pass

# exit函数会在测评结束或者停止策略运行时会被调用。---(选择实现)
def exit(context):
    killtimer(GridTrade)    #终止计时器




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2