欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。


金字塔客服中心 - 专业程序化交易软件提供商金字塔软件高级功能研发区 → 发布一个Python网格交易策略

   

欢迎使用金字塔普通技术服务论坛,您可以在相关区域发表技术支持贴。
我司技术服务人员将优先处理 VIP客服论坛 服务贴,普通区问题处理速度慢,请耐心等待。谢谢您对我们的支持与理解。    


  共有14442人关注过本帖树形打印复制链接

主题:发布一个Python网格交易策略

帅哥哟,离线,有人找我吗?
guotx2010
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:蜘蛛侠 帖子:1366 积分:5210 威望:0 精华:7 注册:2010/12/11 18:00:33
发布一个Python网格交易策略  发帖心情 Post By:2018/12/21 8:33:46 [只看该作者]

老听说金字塔支持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)    #终止计时器


 回到顶部
帅哥哟,离线,有人找我吗?
yukizzc
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:21598 积分:0 威望:0 精华:1 注册:2010/7/31 16:35:30
  发帖心情 Post By:2018/12/21 8:49:16 [只看该作者]

1、你不使用金字塔的绿色版,自己本地装python的环境,然后安装这些库是可以使用的。

2、GUI界面这块目前可能的确不行


 回到顶部
帅哥哟,离线,有人找我吗?
guotx2010
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:蜘蛛侠 帖子:1366 积分:5210 威望:0 精华:7 注册:2010/12/11 18:00:33
  发帖心情 Post By:2018/12/21 8:56:43 [只看该作者]

那我得安装一个python试试了,至于gui,可以结合vba做窗体来弥补。

 回到顶部
帅哥哟,离线,有人找我吗?
马良
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:1516 积分:229 威望:0 精华:0 注册:2012/3/30 12:40:56
  发帖心情 Post By:2018/12/21 10:03:18 [只看该作者]

1,后面会增加ini文件的直接操作函数 2,python对ui的操作肯定不如vba的,python的优点在于策略研发而不是二次开发

 回到顶部
帅哥哟,离线,有人找我吗?
guotx2010
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:蜘蛛侠 帖子:1366 积分:5210 威望:0 精华:7 注册:2010/12/11 18:00:33
  发帖心情 Post By:2018/12/23 16:31:49 [只看该作者]

周末用vba做界面,将需要交互的ini文件读写,做成窗体,提供盘中修改的功能,python实时读取ini文件进行交易,形成vba和python的互补,挺不错。


 回到顶部
帅哥哟,离线,有人找我吗?
F10
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:38 积分:0 威望:0 精华:0 注册:2018/12/19 10:08:58
  发帖心情 Post By:2019/2/19 10:26:50 [只看该作者]

context.s1 = "ZQZC05"   #动力煤

这样可以吗?
context.s1 = "ZC05"   #动力煤

 回到顶部
帅哥哟,离线,有人找我吗?
投资老友-WAN
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游侠 帖子:217 积分:390 威望:0 精华:0 注册:2012/11/3 10:14:55
  发帖心情 Post By:2019/2/20 14:43:47 [只看该作者]

楼主,谢谢你的分享,看你的代码很有意思,你没有用handle Bar的方式来触发运行策略,而是建立时钟settimer(GridTrade,2000)  来跑你的网格交易子程序Grid Trade

 回到顶部
帅哥哟,离线,有人找我吗?
F10
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:新手上路 帖子:38 积分:0 威望:0 精华:0 注册:2018/12/19 10:08:58
  发帖心情 Post By:2019/2/21 14:01:03 [只看该作者]

执行Python脚本时遇到错误。

 类型: SystemError 
 描述: PyEval_EvalFrameEx returned a result with an error set


不知道是哪里错了?

 回到顶部
帅哥哟,离线,有人找我吗?
无为剑
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:2437 积分:0 威望:0 精华:0 注册:2016/3/5 22:53:41
  发帖心情 Post By:2019/2/21 15:47:08 [只看该作者]

这个策略不能进行程序化回测,只能用在盘中实时交易

 回到顶部
帅哥哟,离线,有人找我吗?
投资老友-WAN
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:论坛游侠 帖子:217 积分:390 威望:0 精华:0 注册:2012/11/3 10:14:55
  发帖心情 Post By:2019/2/22 9:31:38 [只看该作者]

不能回测的原因可能就是这个策略不是用handle bar触发运算循环,是用类似VB的定时器触发。Python模块的回测是以Handle Bar为循环的。

 回到顶部
总数 14 1 2 下一页