金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 2647|回复: 6

金字塔VBA常用对象使用范例

[复制链接]

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2023-6-2 10:44 | 显示全部楼层 |阅读模式
本帖最后由 资深技术02 于 2023-6-2 11:28 编辑

金字塔vba编写策略经常使用的对象,在编程帮助中有很多介绍,但是例子相对较少,本人经过2年来对金字塔vba策略的编写,积累了大量的例子,从今天开始我将不定期整理出来供大家借鉴参考,本楼将是一个目录,供快速浏览。

特别常用的对象:


Application对象



Order对象



Document对象



ReportData对象



MarketData对象



Menu对象

金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 10:48 | 显示全部楼层
本帖最后由 资深技术02 于 2023-9-21 15:45 编辑

一、Application对象
1、基本介绍
UserName:返回金字塔用户账号,不是你的交易账号。例如:abc=Application.UserName,就可以把当前登录的用户账号赋给abc变量,使用下面的程序可以显示登录账号的信息
[Visual Basic] 复制代码
iVer=Application.UserType
               if iVer<2 then
                      Application.MsgOut "你的金字塔版本不支持本程序,请升级账户"
                      exit sub
              end if
        End Sub
EnginCode:返回当前用户计算机的机器识别码(只读)
此属性的应用场景是限定特定的用户才能使用本程序,因为金字塔软件在每一台机上的识别码都是不相同的,你就可以判断客户的本属性是否与设定值相同,不相同就不让他运行。
[Visual Basic] 复制代码
       Sub Application_VbaStart()[/align][align=left]               dim sEnginCode[/align][align=left]               dim sTestCode[/align][align=left]               sTestCode="35A7707C1617CBE0"       '本行字符串改为你设定的识别码[/align][align=left]               sEnginCode=Application.EnginCode[/align][align=left]               if  strcomp(sEnginCode,sTestCode,vbtextCompare)<>0 then[/align][align=left]                   Application.MsgOut "你的不是授权用户,不能使用本程序"[/align][align=left]                   exit sub[/align][align=left]               end if[/align][align=left]        End Sub[/align][align=left]   '如果没有打开ABC的框架,就打开     [/align][align=left]   ifApplication.isActivateFrame("ABC")=0 then[/align][align=left]Callapplication.ActivateFrame("ABC")[/align][align=left]   end if

ActivateFrameWithCode方法:
这个方法是对ActivateFrame方法的扩充,可以激活框架的同时指定品种和周期,如: Call Application.ActivateFrameWithCode("ABC","IF05","ZJ",0)将激活框架ABC,并在框架中打开IF05合约的1分钟分析图。
Cyc 参数为 -1 时,打开分时走势界面。
[Visual Basic] 复制代码
Sub Application_VBAStart()
    CallApplication.SetTimer(0,2*1000)      '设置一个0号计时器,间隔2秒执行一次
    CallApplication.Settimer(9,5*1000)      '设置一个9号计时器,间隔5秒执行一次
End Sub


'下面的过程是计时器循环体,我让计时器显示每次触发的时间,你看看是不是间隔设定的秒数就触发。
[Visual Basic] 复制代码
Sub Application_Timer(ID)
    If ID=0 then
        Application.msgout Cdate(time) &",0号计时器触发了"
    end if
    If ID=9 then
        Application.msgout Cdate(time) &",9号计时器触发了"
    end if
End Sub


Application的事件
        Start 应用程序启动后发生。
                写法:
                Sub Application_Start()            '下面的事件都是加上 Application_ 不再赘述
                       '你的代码段
                End Sub
        Close 应用程序关闭时发生。
        Timer 当达到SetTimer方法所设定的定时值后发生。其参数为定时器的标识符。(前面有例子)
        VBAStart  VBA宏启动运行后发生。(前面有例子)
        VBAEnd    VBA宏停止运行后发生

特别需要注意的地方:
    1、计时器一旦设置,如果不显式销毁,下次启动vba时依然会生效的。
所以,你要记住在Application_VBAEnd事件中使用Killtimer来销毁计时器。

     2、Application_VBAStart只能有一个,你不要在多个模块中拥有多个vbastart事件,那样系统就会出错的。


金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 11:10 | 显示全部楼层
本帖最后由 资深技术02 于 2023-9-21 15:54 编辑

二、Order对象
    1、基本介绍:Order对象是你在金字塔软件下使用VBA下单和查询订单的对象,其重要程度不言而喻了吧。
    2、主要属性:(本帖以CTP平台为主要平台,以下讲到的都是CTP平台使用的)
    (1)Holding2:得到当前指定帐户的国内期货持仓品种数量
    (2)OrderNum2:得到所有国内期货当前有效的未成交合约品种数量
    (3)OrderQueue:顺序执行下单成交,即按委托顺序成交报单,可以用于平仓反手,套利等委托动作
    3、有用的方法:
     Account:得到当前默认帐户信息
      Account2:得到指定的国内期货帐户信息
      Buy:开多操作
      Sell:平多操作
      BuyShort:开空操作
      SellShort:平空操作
      CancelOrder:执行撤单操作
      HoldingInfo2:取指定索引的指定CTP帐户的合约持仓信息
      HoldingInfoByCode2:取指定CTP品种的持仓合约信息
      OrderInfoByCode:取指定品种的未成交IB合约信息
      OrderInfo2:取指定索引的未成交CTP合约信息
      OrderInfoByCode2:取指定品种的未成交CTP合约信息
      Contract:取指定品种的合约信息
      ChargeByNum:计算指定品种的本次交易手续费用
      IsAccount:判断指定帐号是否是当前已登录有效帐号,例如 Order.IsAccount("351579"),如果该账户已登录则返回1,否则返回0
    4、事件
     OrderStatusEx2:当委托订单出现变化时发生该扩展事件,比如撤单、成交等
应用场景及代码片段:
1、获取指定者账户的所有持仓合约,保存到一个字符串中。
此例需要解决的问题:首先要获取账户的总持仓数,需要用到Holding2属性,然后要逐一循环取出每一个持仓合约的持仓量,需要用到HoldingInfo2方法。
[Visual Basic] 复制代码
function GetHoldStr(sAccount)
dim i
dim BuyHold
dim BuyCost
dim SellHold
dim SellCost
dim CurCode
dim CurMarket

  On Error resume Next
  HoldStr=""
HoldingCount=Order.Holding2(sAccount)
  If HoldingCount>0 then
   For i=0 to HoldingCount-1
    CallOrder.HoldingInfo2(i,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,Code,Market,sAccount)
    CurCode=Code
    CurMarket=Market
    BuyHold=BuyHolding
    SellHold=SellHolding
    HoldStr=HoldStr & CurCode
    if BuyHold>0 then
      HoldStr=HoldStr & ":+" &BuyHold
    end if
    if SellHold>0 then
      HoldStr=HoldStr & ":-" &SellHold
    end if
    HoldStr=HoldStr & ","
   Next
   HoldStr=Left(HoldStr,len(HoldStr)-1)
  End If
  GetHoldStr=HoldStr
End function

本代码使用函数方式,传递一个账户号码,就可以获取该账户的持仓信息,调用方法是:hold=GetHoldStr("88888888")。
2、获取指定合约的信息,包括合约最小跳动单位,合约保证金比例、合约乘数。
[Visual Basic] 复制代码
private iMultipliter,iMinTick,iShortPercent,iLongPercent
SubGetContractHold(sCode,sMarket)  '获取合约的信息
     'Application.MsgOut sCode & "," &sMarket
     on error resume next
     CallOrder.Contract(sCode,sMarket,Multipliter,MinTick,ShortPercent,LongPercent)
     iMultipliter=Multipliter
     'application.MsgOut iMultipliter
     iMinTick=MinTick
     iShortPercent=ShortPercent
     iLongPercent=LongPercent
End Sub

本例使用变量来存储合约信息的4个值,所以,变量定义置于过程顶端,调用本过程之后,变量就存储了该合约的对应值,其他过程就可以直接使用了。
3、获取未成交的订单信息
[Visual Basic] 复制代码
FunctionGetPendingOrder(sCode,sMarket)  '获取未成交单
dim Orderid   '订单ID
dim Filled   '提交手数
dim Remaining  '剩余手数
dim Action   '买卖
dim OrderType  '订单类型
dim LmtPrice  '委托价
dim Account   '账户
dim Kaiping   '开平
GetPendingOrder=0
PendingCount=Order.OrderNum2
For i=0 to PendingCount-1
      CallOrder.OrderInfo2(i,OrderID,ConSign,Filled,Remaining,Action,OrderType,LmtPrice,Account,Kaiping,Code,Market)
      if Code=sCode then
          GetPendingOrder=OrderID
      end if
Next
end function

本函数返回指定合约的未成交单的订单号,调用方法:OrdID=GetPendingOrder("IF05","ZJ"),然后根据这个返回的OrdID,你可以进行其他的操作,比如,如果是要下单,先看有没有未成交的委托单,如果有就不下单,或者取消该委托单然后再下单等。

4、取消所有委托单
[Visual Basic] 复制代码
dim Orderid '订单ID
dim Filled '提交手数
dim Remaining '剩余手数
dim Action '买卖
dim OrderType '订单类型
dim LmtPrice '委托价
dim Account '账户
dim Kaiping '开平
PendingCount=Order.OrderNum2
For i=0 to PendingCount-1
CallOrder.OrderInfo2(i,OrderID,ConSign,Filled,Remaining,Action,OrderType,LmtPrice,Account,Kaiping,Code,Market)
CancelOrder OrderID
Next
End Sub


这个过程,遍历每一个委托单,逐一进行撤销操作。如果你要撤销指定OrderID的委托单,只需对此过程稍作修改就可以实现了。
5、获取指定品种的持仓量、持仓均价
[Visual Basic] 复制代码
private AccountID,iBuyHold,iSellHold,BuyPrice,SellPrice
SubGetHoldByCode(sAccount,sCode,sMarket)
     dim i,k
     dim BuyHolding
    dim BuyCost
    dim BuyTodayHolding
    dim SellHolding
    dim SellCost
    dim SellTodayHolding
    dim PNL
    dim UseMargin
    dim Code
    dim Market

     On Error resume Next
     AccountStatus=Order.Account2(2,sAccount)
     'application.MsgOut sCode & "," &sMarket & "," & sAccount & ",NextCode:" &NextCode & ",账户状态:" & AccountStatus
      if AccountStatus=255 OrAccountStatus="" then
          exit sub
      end if
      CallOrder.HoldingInfoByCode2(sCode,sMarket,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,sAccount)
     iBuyHold=BuyHolding
     iSellHold=SellHolding
     BuyPrice=BuyCost
     SellPrice=SellCost  
End Sub

这个过程也是将返回的值保存到外部变量,供其他过程使用。所以过程前的定义变量必不可少。
使用方式:GetHoldByCode"8888888","IF05","ZJ"     '传入交易账户、合约代码、市场代码
6、下单指令封装成过程:

    Order对象的下单指令buy,sell,buyshort,sellshort,每次要使用都得看参数怎么用的,是不是很不方便呢?我把他们写成4个过程了,看看是不是很好?
    参数说明:
    nPrice传入的价格,传入0就是市价委托,否则就是限价委托,sCode合约代码,sMarket市场代阿玛,iOrdID委托量,sAccount交易的账户
这下,你再也不用多次翻看帮助了,只要记住这4个过程的名字就行了。
[Visual Basic] 复制代码
'开多单
Sub KaiDuoDan(nPrice,sCode,sMarket,iOrdVol,sAccount)  '开多单,nPrice=0时为市价,否则就是传递过来的价
'application.MsgOut "iOrdVol:" & iOrdVol &"," & sCode & "," & sMarket & ","& sAccount & "," & nPrice
If iOrdVol>0 then
  If nPrice=0 then
   'application.MsgOut "sCode,sMarket,AccountID:"& sCode & "," & sMarket & "," & AccountID
   CallOrder.Buy(1,iOrdVol,0,0,sCode,sMarket,sAccount,0)     '市价开多单
  Else
   CallOrder.Buy(0,iOrdVol,nPrice,0,sCode,sMarket,sAccount,0)   '限价开多单
  End If
End If
End Sub
'开空单
Sub KaiKongDan(nPrice,sCode,sMarket,iOrdVol,sAccount)  '开空单,nPrice=0时为市价,否则就是传递过来的价
'application.MsgOut "iOrdVol:" & iOrdVol &"," & sCode & "," & sMarket & ","& sAccount & "," & nPrice
If iOrdVol>0 then
  If nPrice=0 then
   Call Order.BuyShort(1,iOrdVol,0,0,sCode,sMarket,sAccount,0)    '市价开空单
  Else
   CallOrder.BuyShort(0,iOrdVol,nPrice,0,sCode,sMarket,sAccount,0)   '限价开空单
  End If
End If
End Sub
'平多单
Sub PingDuoDan(nPrice,sCode,sMarket,iOrdVol,sAccount)  '平多单,nPrice=0时为市价,否则就是传递过来的价
If iOrdVol>0 then
  If nPrice=0 then
   CallOrder.Sell(1,iOrdVol,0,0,sCode,sMarket,sAccount,0)    '市价平多单
  Else
   CallOrder.Sell(0,iOrdVol,nPrice,0,sCode,sMarket,sAccount,0)   '限价平多单
  End If
End If
End Sub
'平空单
Sub PingKongDan(nPrice,sCode,sMarket,iOrdVol,sAccount)  '平空单,nPrice=0时为市价,否则就是传递过来的价
If iOrdVol>0 then
  If nPrice=0 then
   CallOrder.SellShort(1,iOrdVol,0,0,sCode,sMarket,sAccount,0)    '市价平空单
  Else
   CallOrder.SellShort(0,iOrdVol,nPrice,0,sCode,sMarket,sAccount,0)   '限价平空单
  End If
End If
End Sub


7、计算订单手续费
    手续费的计算可以使用ChargeByNum(Code,Market, lmtPrice, Volume, Type)方法
    如计算股指期货IF05的交易手续费,可以这么做: sxf=ChargeByNum("IF05","ZJ",2650,2,0)
    参数说明:Code合约代码、Market市场代码、lmtPrice委托价、Volume委托量、Type买卖方向

    使用此方法计算的手续费取决于你是否正确设置了合约信息中的保证金比例、手续费标准,如果设置不对,计算就不对了。
8、根据合约代码获取持仓量、持仓均价并存入全局变量中共后台策略调用
[Visual Basic] 复制代码
'传入交易账户号、合约代码、市场代码 如:GetHoldByCode"88888888","IF05","ZJ"
SubGetHoldByCode(sAccount,sCode,sMarket)   
  dimi
  dim BuyHolding
dim BuyCost
dim BuyTodayHolding
dim SellHolding
dim SellCost
dim SellTodayHolding
dim PNL
dim UseMargin
dim Code
dim Market

  On Error resume Next
  AccountStatus=Order.Account2(2,sAccount)    '检测账户是否登陆,如果没有登陆就退出
  'application.MsgOut sCode & "," & sMarket &"," & sAccount & ",NextCode:" & NextCode &",账户状态:"& AccountStatus
    if AccountStatus=255 Or AccountStatus="" then
     exit sub
    end if
    CallOrder.HoldingInfoByCode2(sCode,sMarket,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,sAccount)
iBuyHold=BuyHolding
iSellHold=SellHolding
DuoPrice=BuyCost
KongPrice=SellCost  
Call Document.SetExtData("多开仓价",DuoPrice)
Call Document.SetExtData("空开仓价",KongPrice)
Call Document.SetExtData("多持仓",iBuyHold)
Call Document.SetExtData("空持仓",iSellHold)
EndSub


图表或后台策略中调用全局变量的方法:
aa:=extgbdata('多开仓价');
bb:=extgbdata('空开仓价');
cc:=extgbdata('多持仓);
dd:=extgbdata('空持仓);

9、OrderStatusEx2事件

    Order对象的OrderStatusEx和OrderStatusEx2的区别是,后者返回了交易账户。我个人更喜欢使用后者,可以精确指定对那个帐户的交易情况进行处理。

    从帮助文字可以看出,这个事件监控订单的变化情况,从下单、撤单、成交等都可以实时回传给你的,通过这个事件,你可以做很多事件的。
    (1)做一个账户跟踪程序,跟踪另一个账户的交易,就要用到这个事件,具体思路是有成交时,判断是哪一个账户成交,如果是你要监控的账户,就同步在另一个账户开同向的仓位。
    这个实例等我闲下来整理一下代码,可以奉献给大家,敬请期待。
    (2)可以做一个将成交记录实时写到Excel的程序,这样你就可以清楚地看到你当前的交易,盈亏计算也可以在excel中完成。
    这个实例,我已经公布在论坛了,有兴趣的可以看看:http://www.weistock.com/bbs/dispbbs.asp?boardid=5&Id=10234
    (3)用在套利策略中,可以用来处理单腿交易等。
    (4)其他需要监控账户变动情况,如:下单后多长时间不成交撤单,你需要记录下单的时间,然后比较最新时间与该时间的间隔来确定是否需要撤单。

    需要说明一下金字塔返回的订单状态:
    1)Submitted:是已经提交订单。
    2)Filled:是已经成交的订单。
    3)Tradeing:是成交回报,可能filled状态的单成交时分多次成交,那么这个状态的单就会有多个。
    4)Cancelled:是已经取消的单

    下面是一个将成交情况存入全局变量的实例

[Visual Basic] 复制代码
Sub ORDER_OrderStatusEx2(OrderID,Status, Filled, Remaining, Price, Code, Market, OrderType, Aspect,Kaiping,Account, AccountType)
'账户类型 0 IB 1 CTP 2 金仕达
    Dim sStatus       '成交状态
If AccountType=0 then
  sAccType="0.IB"
ElseIf AccountType=1 then
  sAccType="1.CTP"
ElseIf AccountType=2 then
  sAccType="2.金士达"
End if
  
If AccountType=0 then
  sStatus="FILLED"
ElseIf AccountType=1 then
  sStatus="TRADEING"
ElseIf AccountType=2 then
  sStatus="FILLED"
End if

If UCase(Status)="FILLED" then  '只跟踪成交的单
  if Aspect=0 and Kaiping=0 then '买入
   CallDocument.SetExtString("Order-Buy-time",time)     '成交时间
   CallDocument.SetExtData("Order-B-Price",Price)   '成交价格
   CallDocument.SetExtData("Order-B-Vol",Filled)   '成交手数
   Call Document.SetExtData("Order-B-OrderID",OrderID)  '成交单号
  end if
  if Aspect=1 and Kaiping=0 then '卖出
   Call Document.SetExtString("Order-S-time",time)     '成交时间
   CallDocument.SetExtData("Order-S-Price",Price)   '成交价格
   CallDocument.SetExtData("Order-S-Vol",Filled)   '成交手数
   CallDocument.SetExtData("Order-S-OrderID",OrderID)  '成交单号
  end if
  if Aspect=1 and Kaiping>0 then '卖平
   CallDocument.SetExtString("Order-Sp-time",time)     '成交时间
   CallDocument.SetExtData("Order-Sp-Price",Price)  '成交价格
   Call Document.SetExtData("Order-Sp-Vol",Filled)   '成交手数
   CallDocument.SetExtData("Order-Sp-OrderID",OrderID) '成交单号
  end if
  if Aspect=0 and Kaiping>0 then '买平
   CallDocument.SetExtString("Order-Bp-time",time)    '成交时间
   CallDocument.SetExtData("Order-Bp-Price",Price) '成交价格
   CallDocument.SetExtData("Order-Bp-Vol",Filled)  '成交手数
  end if
End if
End Sub


把这段代码复制到你的金字塔vba模块中,试着下几个单,然后可以看看全局变量中是否有下单时间、成交价格、成交手数、成交单号这些变量。


金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 11:11 | 显示全部楼层
本帖最后由 资深技术02 于 2023-9-21 15:55 编辑

三、Document对象
    使用这个对象可以很方便地读写配置文件(ini文件)、读写全局变量、写日志文件等。

    我最喜欢使用全局变量了,先说说全局变量怎么使用吧,全局变量类似于单值数据库,以键值对形式形式存放数值,存放的数据主要是数值或字符串,对于这个两种类型的数据分别使用不同方法来读写。
    对于数值性的数据使用SetExtData来赋值,使用GetExtData来读取。
    看下面的代码段:
[Visual Basic] 复制代码
    Sub WriteAndReadGlobal()
          '将数值型数据写入全局变量
          CallDocument.SetExtData("变量1",1000)
          '从全局变量读取出来存入到临时变量
          Var1=Document.GetExtData("变量1")
         application.msgout "Var1:" & Var1
    End Sub
    对于字符性的数据使用SetExtString来赋值,使用GetExtString来读取。
    看下面的代码段:
[Visual Basic] 复制代码
    Sub WriteAndReadGlobal1()
        '将数值型数据写入全局变量
        CallDocument.SetExtString("变量1","测试字符")
        '从全局变量读取出来存入到临时变量
       Var1=Document.GetExtString("变量1")
        application.msgout"Var1:" & Var1
    End Sub


    如果要将当前时间存储到全局变量,可以这么写: CallDocument.SetExtString("当前时间",Cdate(time))

    清除全局变量的方法:ClearExtData,使用这个方法可以一次全部清除所有的全局变量。
    Call Document.ClearExtData()
    这个方法是很彻底,可是有一个问题,就是如果我不想全部清除,而是想清除某一个全局变量,就没有办法了。我曾向金字塔论坛提出过此问题,到现在这个版本还是没有增加单个清除的方法。
    一个复杂的策略可能会使用大量的全局变量,这些全局变量可能是动态生成的名字,具有某一特征,比如,记录订单情况的全局变量使用字符"Order"加该订单的OrderID,这里的OrderID就是动态的,设置时可以这样在Order_OrderStatusEx事件中设置:
Call Document.SetExtData("Order-" & OrderID &"-Vol",Filled),可是要清除这个全局变量,仅仅根据名称,你是不能完成的,因为清除一般是在收盘时,可是,当时那个OrderID,系统已经无法知道了,所以,希望金字塔再扩充此部分功能时,不仅要增加清除单个全局变量,还要增加清除具有某一特征的多个全局变量,如Order开头的全局变量。
    另外、全局变量多了,要想知道到底有多少个全局变量,无法知道,要是有一个属性来记录全局变量的个数,然后有一个方法来遍历每一个全局变量就完美了。




    上面的遗憾,在2.93版已经不再有了,因为已经增加了相应的处理方法了:
1、增加了ExtDataNum和ExtDataStringNum两个属性,分别返回数值型和字符性全局变量个数,就可以遍历了。
2、增加了GetExtDataByIndex和GetExtStringByIndex取得指定位置的全局变量的值和键。
3、增加了RemoveExtData和RemoveExtString两个方法,来删除数值型和字符型全局变量。
对ini文件,我们都不会陌生,用它来记录你的策略中需要长期保存的参数是它的最佳使用场景,比如,记录交易账号、交易的合约代码、止盈、止损标准等。

1、GetPrivateProfileString:使用这个方法来读取ini文件中的字符值
2、WritePrivateProfileString:使用这个方法来写入字符值到ini文件

[Visual Basic] 复制代码
priavate AccountID
private DiCangVol,BuCangVol,JiaCangVol,ZhiYingStd,ZhiSunStd
Sub GetIni()
     AccountID=document.GetPrivateProfileString("Gen","AccountID", "", "C:\SystemSet.ini")
    DiCangVol=cdbl(document.GetPrivateProfileString("Gen","DiCangVol",1, "C:\SystemSet.ini"))    '底仓手数
    BuCangVol=cdbl(document.GetPrivateProfileString("Gen", "BuCangVol",1,"C:\SystemSet.ini"))   '补仓手数
    JiaCangVol=cdbl(document.GetPrivateProfileString("Gen","JiaCangVol",8, "C:\SystemSet.ini"))   '加仓手数
    ZhiYingStd=cdbl(document.GetPrivateProfileString("Gen","ZhiSunStd",8, "C:\SystemSet.ini"))   '止盈标准
     ZhiSunStd=cdbl(document.GetPrivateProfileString("Gen","ZhiSunStd",8, "C:\SystemSet.ini"))    '止损标准
     ifAccountID="" then
          msgbox"SystemSet.ini文件中没有设置AccountID(交易账号),请修改C:\SystemSet.ini"
          Document.WritePrivateProfileString "Gen","AccountID","88888888","C:\SystemSet.INI"   '交易账户
         Document.WritePrivateProfileString"Gen","Market","ZJ","C:\SystemSet.INI"   '市场代码
         Document.WritePrivateProfileString"Gen","WriteSql","1","C:\SystemSet.INI"   '是否写到Sql Server
     end if
End Sub





金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 11:13 | 显示全部楼层
本帖最后由 资深技术02 于 2023-6-2 11:18 编辑

四、ReportData对象:

    此对象是返回行情数据,之前讲到的MarketData对象的两种获取最新行情数据的方法,getReportData方法、RegReportNotify订阅行情并使用MarketData_ReportNotify事件获取最新行情都是返回这个对象。
还有Grid对象的GetReportData方法也是返回本对象。

    本对象的常用属性可以看看编程帮助的说明,本帖只讲一些用的最多的属性。
   LastOpen         昨开价
   LastHigh          昨高价
   LastLow           昨低价
   Open              取开盘价
   High               取最高价
   Low                取最低价
   NewPrice          取最新价
   Volume             取成交量(手)
   Amount            取成交额(元)
   BuyPrice1         取买1价格
    BuyVolume1      取买1量
   SellPrice1         取卖1价
    SellVolume1      取卖1量

下面的例子返回IF07最新价、买1、卖1价
Sub TestReportData()
    setreport1=marketdata.getreportdata("IF07","ZJ")
    application.msgout Cdate(time) &",IF07最新价:" &report1.NewPrice & ",买1价:"&report1.buyprice1&",卖1价:"&report1.sellprice1
End

这个对象相对简单,关键是理清楚与grid、marketdata对象的关系,此对象就是一个数据的载体,这样说也许你会理解的快些。


金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 11:14 | 显示全部楼层
本帖最后由 资深技术02 于 2023-9-21 15:50 编辑

五、MarketData对象 获取行情数据,这个你一定得用。

    1、GetReportData:获取指定品种的行情数据。
比如要获取股指6月份合约的最新价,代码如下:
[Visual Basic] 复制代码
   sub GetNewPrice()
          Set Report1=MarketData.GetReportData("IF06","ZJ")
          NewPrice=Report1.NewPrice
          Application.Msgout Cdate(time) & ",IF06最新价:" &NewPrice
   End Sub



这个事件返回的数据为一个ReportData对象,你如果需要返回买1价、卖1价、合约代码、市场代码等其他信息,只要看ReportData对象的属性有哪些就可以直接调用了。

    如果要每隔一段时间读取一次价格,比如每隔1秒读取一次价格,用于决定是否符合开平仓条件,那么就得使用定时器了,定时器的使用方法,本帖子的第一个对象讲得很清楚,可以参考。   

2、ReportNotify事件
使用ReportNotity来监控价格变化比上面的定时读取价格的方法好的地方是价格的每一次跳动都逃不过这个事件的监控,而使用定时器,则会漏掉一些价格,不如:股指每一秒钟有2笔成交回报,用上面的方法就会漏掉一次价格变化,当然如果你把定时器设置成500毫秒一次也可以获取每一次的价格变化,但是这样对系统资源的消耗会很大的,而是用这个事件相对占用较少系统资源。
如果你是做套利的,那么对价格变动更加敏感,使用这个事件是最好的选择。
这个事件的使用,需要首先注册你要监控的品种,使用RegReportNotify方法,代码如下:
   sub RegIF()            '还是监控IF06合约的价格变化
           Call MarketData.RegReportNotify("IF06","ZJ")
           '要监控多个品种,继续写代码就行了,如:
           CallMarketData.RegReportNotify("RB10","SQ")    '监控上期的螺纹钢10月份合约
   end sub
把这个过程用到VBAStart事件中,就会在启动VBA时自动注册对IF06合约的监控

到这里为止,你只做了一半事情,很多人就是在这之后不知道怎么获取行情数据了。别担心,继续看下去你就明白了。

注册了合约之后,需要通过另一个事件来获取行情数据,那就是ReportNotify事件,这个事件会返回一个ReportData对象,这个更上面的一样。
[Visual Basic] 复制代码
   Sub MarketData_ReportNotify(ReportData)
           '有人在这里还是用1的方法设置一个report1变量,然后取report1的返回值,这是多余的,ReportData本身就是返回的数据,直接取reportData的值就行了。
           NewPrice=ReportData.NewPrice
           stkLable=ReportData.Label
           Application.Msgout Cdate(time) & ",Code:" & stkLabel &",NewPrice:" & NewPrice
    EndSub

   当你监控了某一个品种之后,应该在Application_VBAEnd事件或Application_Close事件中进行注销,不然这个合约在你启动VBA时依然有效,除非你退出金字塔,重新进入就没有了。
   注销的方法是:使用unRegReportNotify方法。
   Sub UnRegIF()
          CallMarketData_UnRegReportNotify("IF06","ZJ")
   End Sub
   可以把这个过程用到Application_VBAEnd中,就会很好的在你不用的时候注销监控的品种了。


   以上代码都是我在本贴子中现场写的,没有经过测试,主要是启发你的思路,如果测试有错误,可以跟帖指出。

金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

3

主题

2万

帖子

2万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
 楼主| 发表于 2023-6-2 11:28 | 显示全部楼层
本帖最后由 资深技术02 于 2023-9-21 15:55 编辑

六、Menu对象:

    这个对象相对简单些,是用于生成菜单的。
    帮助文件有介绍,但是没有例子,本帖主要是列举一个例子,帮助朋友们快速掌握此对象的使用方法。

''''''''''菜单操作
[Visual Basic] 复制代码
[/align]Sub MENU_Show()
 Menu.AddMenu 0, 0, "菜单项一"
 Menu.AddMenu 1, 1, "菜单项二"
 Menu.AddMenu 2, 2, "菜单项三"
 Menu.AddMenu 3, 3, "菜单项四"
 Menu.AddMenu 4, 4, "菜单项"
End Sub
 
Sub MENU_Command(Cmd)
 Select Case Cmd
 Case 0
  Sub01
 Case 1 
  Sub02[/align][align=left] Case 2
  Sub03
 Case 3
  Sub04
 Case 4
  Sub05
 End Select
End Sub[/align][align=left][align=left]


上述代码放在一个模块中,启动VBA,就会在工具->扩展 下生成一个你自己的菜单。


金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2024-9-17 14:37 , Processed in 0.113490 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表