您现在的位置:程序化交易>> 期货公式>> 金字塔等>> 金字塔模型>>正文内容

金字塔Python网格交易策略源码[金字塔模型]

相关标签:

 


  发布一个Python网格交易策略
 
 
 
#老听说金字塔支持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():
    settimer(GridTrade,200000)        #200秒执行一次        
    input_par("lastbuy",0,0,9,1)    #末次买入开仓单号
    input_par("lastsell",0,0,9,1)    #末次卖出开仓单号
    input_par("lastbuyping",0,0,9,1)    #末次平多单单号
    input_par("lastsellping",0,0,9,1)    #末次平空单单号
    input_par("jiange",2,0,5,1)    #间隔
    input_par("vol",1,0,9,1)    #每档手数
    input_par("firstvol",1,0,9,1)    #初始手数
    input_par("fx",1,1,2,1)    #交易方向 1-多 2-空
    input_par("maxvol",1,0,9,1)    #最大手数
 
#  在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。--(必须实现)
 
def init(context):
    settimer(GridTrade,10000)        #10秒执行一次
    # 在context中保存全局变量
    context.s1 = "SQFU00"   #交易代码
    #settimer(GridTrade,20000)        #2秒执行一次
    #引用PEL指标公式"my_test"的ma5日均线指标值。PEL指标必须提前存在或者构建。
    context.price = int( history_bars(context.s1,1,\'1m\',\'open\') )           
    context.priceO = int( history_bars(context.s1,1,\'1m\',\'open\') )           
    context.priceH = int( history_bars(context.s1,1,\'1m\',\'high\') )
    context.priceL = int( history_bars(context.s1,1,\'1m\',\'low\') )
    context.priceC = int( history_bars(context.s1,1,\'1m\',\'close\') )    
 
    print("T0 D+K/策略启动/"+context.s1+\'/参考价=\'+str(context.price)+\'/价O=\'+str(context.priceO)+\'/价H=\'+str(context.priceH)+\'/价L=\'+str(context.priceL)+\'/价C=\'+str(context.priceC))
    log_debug_info(\'C:\\T0DK.txt\',"T0 D+K/策略启动/"+context.s1+\'/参考价=\'+str(context.price)+\'/价O=\'+str(context.priceO)+\'/价H=\'+str(context.priceH)+\'/价L=\'+str(context.priceL)+\'/价C=\'+str(context.priceC))
        
def setorderid(context):
    settimer(GridTrade,20000)        #20秒执行一次    
    #检查未成交订单,将单号赋值给全局变量,避免启动策略时变量的值为0
    #print("获取未成交订单编号")
    log_debug_info(\'C:\\T0DK.txt\',"获取未成交订单编号")
    
    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)
            log_debug_info(\'C:\\T0DK.txt\',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))
        log_debug_info(\'C:\\T0DK.txt\',\'开多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',开空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
 
#网格交易主程序     
def GridTrade(context):
    settimer(GridTrade,60000)        #60秒执行一次        
    nAmount0=get_account(53)    #帐户有效检查
    if nAmount0==False:
        
        #print(\'账户=\'+str(nAmount0)+\'登陆推出了,退出交易。\')
        log_debug_info(\'C:\\T0DK.txt\',\'账户\'+str(nAmount0)+\'登陆推出了,退出交易。\')
        return
        
    if istradertime(context.s1)==False:    #不在交易时间,不进入交易段
        
        #print("不在交易时间,不进入交易段")
        log_debug_info(\'C:\\T0DK.txt\',"不在交易时间,不进入交易段")
        return
    
    setorderid(context)           #获取未成交订单号,保存到全局变量
    
    nAmount=get_account(19)    #可用资金
    if nAmount<=0:
        print(\'账户可用资金\'+str(nAmount)+\'低于0了/登陆推出了,退出交易。\')
        log_debug_info(\'C:\\T0DK.txt\',\'账户可用资金低于0了,退出交易。\')
        return
            
    portfolio=get_portfolio(context.s1,0)    #获取持仓量
    if context.fx==1:
        iDuoTotal=portfolio.buy_quantity
        DTnCurOrdPrice = round(context.priceH - ((iDuoTotal -context.firstvol) * context.jiange) / context.vol, 1)
 
    if context.fx==1:
        iKongTotal=portfolio.sell_quantity
        KTnCurOrdPrice = round(context.priceL - ((context.firstvol - iKongTotal) * context.jiange) / context.vol, 1)
        
    #print(\'档位价:\'+str(nCurOrdPrice)+\',开多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',开空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
    log_debug_info(\'C:\\T0DK.txt\',\'空档位价:\'+str(KTnCurOrdPrice)+\'多档位价:\'+str(DTnCurOrdPrice)+\',开多:\'+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):
            DTnOrdPrice=DTnCurOrdPrice-context.jiange
            context.lastbuy=buy_open(context.s1,"Limit",DTnOrdPrice,context.vol)
            #print(\'档位价:\'+str(nCurOrdPrice)+\',委托价:\'+str(nOrdPrice)+\',开多\')
            log_debug_info(\'C:\\T0DK.txt\',\'档位价:\'+str(DTnCurOrdPrice)+\',委托价:\'+str(DTnOrdPrice)+\',开多\')
            
        if (context.lastbuyping==0 and iDuoTotal>0):
            DTnOrdPrice=DTnCurOrdPrice+context.jiange
            context.lastbuyping=sell_close(context.s1,"Limit",DTnOrdPrice,context.vol)
            #print(\'档位价:\'+str(nCurOrdPrice)+\',委托价:\'+str(nOrdPrice)+\',平多\')
            log_debug_info(\'C:\\T0DK.txt\',\'档位价:\'+str(DTnCurOrdPrice)+\',委托价:\'+str(DTnOrdPrice)+\',平多\')
            
    if context.fx==1: #and iKongTotal<context.maxvol:    #做空
        if (context.lastsell==0 and iKongTotal<context.maxvol):
            KTnOrdPrice=KTnCurOrdPrice+context.jiange
            context.lastsell=sell_open(context.s1,"Limit",KTnOrdPrice,context.vol)
            #print(\'档位价:\'+str(nCurOrdPrice)+\',委托价:\'+str(nOrdPrice)+\',开空\')
            log_debug_info(\'C:\\T0DK.txt\',\'档位价:\'+str(KTnCurOrdPrice)+\',委托价:\'+str(KTnOrdPrice)+\',开空\')
            
        if (context.lastsellping==0 and iKongTotal>0):
            KTnOrdPrice=KTnCurOrdPrice-context.jiange
            context.lastsellping=buy_close(context.s1,"Limit",KTnOrdPrice,context.vol)
            #print(\'档位价:\'+str(nCurOrdPrice)+\',委托价:\'+str(nOrdPrice)+\',平空\')
            log_debug_info(\'C:\\T0DK.txt\',\'档位价:\'+str(KTnCurOrdPrice)+\',委托价:\'+str(KTnOrdPrice)+\',平空\')
            
# 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(\'订单成交\')
    log_debug_info(\'C:\\T0DK.txt\',\'订单成交\')
    #print(order.order_book_id)
    log_debug_info(\'C:\\T0DK.txt\',order.order_book_id)
    #print(str(order.order_id)+\',\'+order.status+\',\'+order.order_book_id)
    log_debug_info(\'C:\\T0DK.txt\',str(order.order_id)+\',\'+order.status+\',\'+order.order_book_id)
    #print(\'开多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',开空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
    log_debug_info(\'C:\\T0DK.txt\',\'开多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',开空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
    #如果是成交,将对应的委托单撤销
    log_debug_info(\'C:\\T0DK.txt\',"如果是成交,将对应的委托单撤销")
    
    if (order.status=="tradeing" and order.order_book_id==context.s1):
        #print(str(order.order_id)+\'全部成交\')
        log_debug_info(\'C:\\T0DK.txt\',str(order.order_id)+\'全部成交\')
        
        if order.order_id==context.lastbuy:        #买入成交
            if context.lastbuyping!=0:
                cancel_order (context.lastbuyping)
                #print("买入成交之后撤平仓单,"+str(context.lastbuyping))
                log_debug_info(\'C:\\T0DK.txt\',"买入成交之后撤平仓单,"+str(context.lastbuyping))
                
                context.lastbuyping=0
        if order.order_id==context.lastbuyping:    #平多成交
            if context.lastbuy!=0:
                cancel_order (context.lastbuy)
                #print("平多成交之后撤开仓单,"+str(context.lastbuy))
                log_debug_info(\'C:\\T0DK.txt\',"平多成交之后撤开仓单,"+str(context.lastbuy))
                
                context.lastbuy=0
        if order.order_id==context.lastsell:        #卖出成交
            if context.lastsellping!=0:
                cancel_order (context.lastsellping)
                #print("卖出成交之后撤平仓单,"+str(context.lastsellping))
                log_debug_info(\'C:\\T0DK.txt\',"卖出成交之后撤平仓单,"+str(context.lastsellping))
                
                context.lastsellping=0
                
        if order.order_id==context.lastsellping:    #平空成交
            if context.lastsell!=0:
                cancel_order (context.lastsell)
                #print("平空成交之后撤开仓单,"+str(context.lastsell))
                log_debug_info(\'C:\\T0DK.txt\',"平空成交之后撤开仓单,"+str(context.lastsell))
                
                context.lastsell=0
    
    #如果是撤单,将对应的变量设置为0 
    log_debug_info(\'C:\\T0DK.txt\',"如果是撤单,将对应的变量设置为0 ")               
 
    if (order.status=="cancelled" and order.order_book_id==context.s1):
        if order.order_id==context.lastbuy:        #买入撤单
            #print("买入开仓撤单,"+str(context.lastbuy))
            log_debug_info(\'C:\\T0DK.txt\',"买入开仓撤单,"+str(context.lastbuy))
            
            context.lastbuy=0
        if order.order_id==context.lastbuyping:    #平多撤单
            #print("平多单撤单,"+str(context.lastbuyping))
            log_debug_info(\'C:\\T0DK.txt\',"平多单撤单,"+str(context.lastbuyping))
            
            context.lastbuyping=0
        if order.order_id==context.lastsell:       #卖出撤单
            #print("卖出开仓撤单,"+str(context.lastsell))
            log_debug_info(\'C:\\T0DK.txt\',"卖出开仓撤单,"+str(context.lastsell))
            
            context.lastsell=0
        if order.order_id==context.lastsellping:   #平空撤单
            #print("平空单撤单,"+str(context.lastsellping))
            log_debug_info(\'C:\\T0DK.txt\',"平空单撤单,"+str(context.lastsellping))
            
            context.lastsellping=0
 
# order_action当查询交易接口信息时返回的通知---(选择实现)
#注意:该事件函数仅在融资融券、新股申购操作刷新动作时才会触发,一般账户无效。
#def order_action(context):
    
    #pass
 
# exit函数会在测评结束或者停止策略运行时会被调用。---(选择实现)
def exit(context):
    
    #获得品种的浮动盈亏,(多空同时存在时,为多空浮动盈亏之和)
    zhan_bzj = get_account(28)
    #print(\'占用保证金总额\'+str(zhan_bzj))
    log_debug_info(\'C:\\T0DK.txt\', \'占用保证金总额\'+str(zhan_bzj))
    
    #获得帐户平仓盈亏
    pingcang_win_long = get_account(30)
    #print(\'帐户平仓盈亏\'+str(pingcang_win_long))
    log_debug_info(\'C:\\T0DK.txt\', \'帐户平仓盈亏\'+str(pingcang_win_long))
    
    #获得帐户浮动盈亏
    fudong_win_long = get_account(4)
    #print(\'帐户浮动盈亏\'+str(fudong_win_long))
    log_debug_info(\'C:\\T0DK.txt\', \'帐户浮动盈亏\'+str(fudong_win_long))
    
    #获得帐户手续费
    shouxufei = get_account(31)
    #print(\'帐户手续费\'+str(shouxufei))
    log_debug_info(\'C:\\T0DK.txt\', \'帐户手续费\'+str(shouxufei))
    
    #盈亏率和成本比计算
    #fudong_ykl = get_account(4)/get_account(28)*100
    #chengbenbi = get_account(30)/get_account(31)
    #log_debug_info(\'C:\\T0DK.txt\', \'浮动盈亏率\'+str(fudong_ykl)+\'/平仓成本比\'+str(chengbenbi))
        
    killtimer(GridTrade)    #终止计时器
    print("终止计时器")
    log_debug_info(\'C:\\T0DK.txt\', \'终止计时器\')
    return
 
 
#type参数 (get_account函数) 
# type    说明
#1    该函数返回常数,返回当前交易帐户ID(该函数返回字符串类型数值)
#2    账户类型,0 盈透 1 CTP 2 金仕达期货 3FIX接口 4恒生期货 5子账户 6其他柜台 255 无效账户
#3    现金余额
#5    浮动盈亏
#6    当前交易帐户中的动态权益/资产值
#19    当前可用资金
#20    当前流动资产
#26    上次结算准备金/期初余额
#27    结算准备金/期初余额
#28    占用保证金/证券市值
#29    可取资金
#30    平仓盈亏数额/回报卖出金额/融券盈亏
#31    手续费
#32    入金金额/利息积数/融资市值
#33    出金金额/当前余额
#34    上次信用额度
#35    上次质压
#36    质压金额
#37    信用额度
#38    冻结保证金/禁取资产
#39    冻结手续费/回报买入金额/融资盈亏
#40    保底资金
#41    多头保证金率(期货专有)
#42    空头保证金率(期货专有)
#43    返回交易网关名称,该函数返回字符串常数
#44    融券市值
#45    融券费用
#46    融券利息
#47    融资余额
#48    融券余额
#49    可用保证金
#50    已用融资额
#51    已用融券额
#52    融资负债
#53    返回当前交易账户是否处于有效状态。建议对账户持仓或资金进行读取时首先调用该函数对账户有效性进行判断,以免出现误操作。(对IB外盘无效,仅限国内)
 
# 本Python代码主要用于策略交易
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
#from PythonApi import *
 
#  参数定义区,这里定义的参数可以直接在context对象中获取。--(选择实现)
#def parameter():
#    input_par("myvalues1",5,1,20,1)
#    input_par("myvalues2",10,1,20,1)
 
 
#  在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。--(必须实现)
#def init(context):
    # 在context中保存全局变量
    #context.s1 = "SZ000001"   #平安银行股票
    
    # print("策略启动") #调试打印输出
    
 
# before_trading此函数会在每天基准合约的策略交易开始前被调用,当天只会被调用一次。--(选择实现)
#def before_trading(context):
#    pass
 
 
# 你选择的品种的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新。--(必须实现)
#def handle_bar(context):
    # 开始编写你的主要的算法逻辑。
    
    #使用buy_open、sell_close等方法下单
    #下单示例:
    #buy_open(context.s1, "Market", volume = 100)    #  市价开多
    #buy_open(context.s1, "Limit", 25.45, 100)       #  限价开多
#    pass
    
    
# after_trading函数会在每天交易结束后被调用,当天只会被调用一次。 --(选择实现)
#def after_trading(context):
#    pass
    
    
# order_status当委托下单,成交,撤单等与下单有关的动作时,该方法就会被调用。---(选择实现)
#def order_status(context,order):
#    pass
 
# order_action当查询交易接口信息时返回的通知---(选择实现)
#def order_action(context,type, account, datas)
#       pass
 
# exit函数会在测评结束或者停止策略运行时会被调用。---(选择实现)
#def exit(context):
#    pass
 

{别忘了将本网告诉您身边的朋友,向朋友传达有用资料,也是一种人情,你朋友会感谢你的。}

 

 

有思路,想编写各种指标公式,交易模型,选股公式,还原公式的朋友

可联系技术人员 QQ: 262069696  点击在线交流或微信:cxhjy888 进行 有偿收费 编写!(注:由于人数限制,QQ或微信请选择方便的一个联系我们就行,加好友时请简单备注下您的需求,否则无法通过。谢谢您!)

怎么收费,代编流程等详情请点击查阅!

(注:由于人数限制,QQ或微信请选择方便的一个联系我们就行,加好友时请简单备注下您的需求,否则无法通过。谢谢您!)

 


【字体: 】【打印文章】【查看评论

相关文章

    没有相关内容