FAQ > 金融建模 > 第三方交互 > Python

Q:pyTSL接口中如何并发执行多个天软任务    

  • A:每个天软账号都有多个并发数权限(可执行个数,一般是5个),在构建天软任务时,可以充分使用这些并发数来提高效率。
     比如在需要天软完成多个独立运算或取数时,可以把该类任务分成多个,根据自己并发数的使用情况合理安排多个线程同时领取执行这些任务,可以提高交互效率。
     pyTSL接口中提供Batch类用于并发执行多个天软任务,使用时实例化该对象接口即可。
    使用说明:FAQ:天软pyTSL接口

    特别说明:
    1.可用key方法设置每次任务的关键字信息,查看执行进度及区分不同的任务,key关键字只能设置为字符串
    2.在使用并发时可以执行独立的任务,即可以同时执行多个不同的任务
    3.每次执行天软任务时可以指定pyTSL.Client 实例,可指定不同的账号及不同的服务器同时执行天软任务
    4.Batch类的第一个构造参数是指天软账号的并发数;
    5.在使用该并发时如果发生连接中断,原来提交的任务会被服务器取消,
    客户机这边会不断尝试重连,如果连上会重新提交那些任务。

    使用实例
    key方法的使用:在执行天软任务时指定关键字key即可在结果中调用
    python代码:
    import pyTSL
    #user为天软账号,password 为账号密码
    c = pyTSL.Client("user", "password", "tsl.tinysoft.com.cn", 443)
    c.login()
    test = '''
      function get_value(stock);
      begin
        return stockname(stock);
      end;
      '''
    stocks = ['SH600000','SH600004','SH600006','SH600007']
    batch=pyTSL.Batch(4)#设置4个并发数,用户可根据账号并发资源合理控制
    for s in stocks:
      print("key:",s)
      t=batch.call(c, "get_value", s, code=test,key=s)

    for r in iter(batch):
      print(r.key(),r.value())
    #返回结果:


    同时执行不同的任务:
    python代码:
    import pyTSL
    #user为天软账号,password 为账号密码
    c = pyTSL.Client("user", "password", "tsl.tinysoft.com.cn", 443)
    c.login()
    stocks = ['SH600000','SH600004','SH600006','SH600007']
    batch=pyTSL.Batch(4)#设置4个并发数,用户可根据账号并发资源合理控制
    for s in stocks:
      print("key:",s)
      if s == "SH600000" :
        batch.exec(c,"return '%s';"%s,key=s)
      else:
        batch.exec(c,"return stockname('%s');"%s,key=s)

    for r in iter(batch):
      print(r.key(),r.value())

    #返回结果:


    指定多个服务器执行天软任务:
    python代码:
    import pyTSL
    #user为天软账号,password 为账号密码
    c = pyTSL.Client("user", "password", "tsl.tinysoft.com.cn", 443)
    c.login()
    d = pyTSL.Client("user", "password", "wh.tinysoft.com.cn", 443)
    d.login()
    servers = ['tsl.tinysoft.com.cn','wh.tinysoft.com.cn']
    batch=pyTSL.Batch(4)#设置4个并发数,用户可根据账号并发资源合理控制
    for s in servers:
      print("key:",s)
      if s=="tsl.tinysoft.com.cn":
        batch.exec(c,"return TSAppserver();",service=c.server_list()[2],key=s)
      else :
        batch.exec(d,"return TSAppserver();",service=d.server_list()[2],key=s)

    for r in iter(batch):
      print(r.key(),r.value())

    #返回结果:


    导出数据使用实例:
    FAQ:Q:python如何把天软数据分批导入到本地

    使用多线程取指定日代码列表大小单流入流出数据(按分钟线汇总)
    取大小单流入流出数据参考:FAQ:Q:如何统计区间内每日大小单流入流出数据
    python实现代码:
    import sys
    import pandas as pd
    import pyTSL

    #user 为天软账号, password 为账号密码
    c = pyTSL.Client("username", "password", "tsl.tinysoft.com.cn", 443)
    lg=c.login()
    if lg != 1:
      print("登陆天软服务器失败:",c.last_error())
      sys.exit()
    else:
      print("登陆天软服务器成功")
    Indexid="SH000016"
    Endt=20240827
    r = c.exec("return getbkbydate('{0}',{1}T);".format(Indexid,Endt)) #获取指定日上证50的证券列表
    if r.error() !=0:
      print(r.message())
    else:
      bk=r.value()
      print("证券样本长度:",len(bk))

    buy_and_sell_data ='''
    Function Stock_BuyAndSellminuteTracking(stockid,Ibegt,Iendt);
    Begin
    {**
    %% @explain(说明)大单跟踪,返回证券或累计证券列表区间每日分钟线流入流出的大小单成交金额(万)数据
    包括:小单:单笔交易明细成交金额<4万元
     中单:单笔交易明细成交金额4-20万元
     大单:单笔交易明细成交金额20-100万元
     小单:单笔交易明细成交金额大于100万元
    %% @param(stiockid)(VarChar/array) 股票代码
    %% @param(begt)(DateT) 开始日
    %% @param(endt)(DateT) 截止日
    %% @return(array) 区间每日分钟线流入流出大小单数据
    **}
    //将整型日期转成天软日期
    begt:=inttodate(Ibegt);
    endt:=inttodate(Iendt);
    ov:=BackupSystemParameters2();

    setsysparam(pn_stock(),stockid);
    setsysparam(pn_date(),endt);
    v1:=StrToTime(StockAuctionTime(3,0)); //上午连续竞价开始
    v2:=StockAuctionTime(2,0)?StrToTime(StockAuctionTime(2,0)):0; //夜盘连续竞价开始
    compB:=function(y,mm,d,h,m,s,v1,v2);
    begin
    t:=EncodeTime(h,m,s,0);
    if t>8/24 and t<=v1 then
    begin
    if t=v1 then m+=1;
    else frac(v1*24)*60? m:=frac(v1*24)*60+1:(h++,m:=1);
    end
    else if v2 and t>20/24 and t<=v2 then
    begin
    if t=v2 then m+=1;
    else frac(v2*24)*60? m:=frac(v2*24)*60+1:(h++,m:=1);
    end
    else if s>0 then m++;

    if h>=15 and m>=0 and t<18/24 then m:=0;
    if m=60 then (h++,m:=0);
    return EncodedateTime(y,mm,d,h,m,0,0);
    end

    tradData:=select ['date'],
     compB.do(YearOf(["date"]),monthOf(["date"]),dayOf(["date"]),HourOf(['date']),MinuteOf(['date']),SecondOf(['date']),v1,v2) as "daymin",
     ['amount']/10000. as '成交金额(万)',
     ['zmm']
    from tradetable datekey begt to endt+18/24 of stockid where ['amount']>0 end;

    trad3:=select *,['成交金额(万)']/2 as "成交金额(万)" from tradData where ["zmm"]=3 end;
    len:=length(trad3);
    for i:=0 to len-1 do
    begin
    trad3[i]:=trad3[i,:];
    trad3[len+i]:=trad3[i,:];
    trad3[i,"zmm"]:=1;
    trad3[len+i,"zmm"]:=2;
    end
    tradData:=select * from tradData where ["zmm"] in array(1,2) end union2 trad3 ;

    if not istable(tradData) then return array();
    tradData[:,array('小单','中单','大单','超大单')]:=0;
    compA:=function(v);
    begin
    case v of
    0 to 4:return '小单';
    4 to 20:return '中单';
    20 to 100:return '大单';
    else return '超大单';
    end;
    end;
    update tradData set [compA.do(['成交金额(万)'])]=['成交金额(万)'] end;
    tradd:=select stockid as "stockid",datetimetostr(["daymin"]) as "date",
     sumof(["超大单"],["zmm"]=1) as "流入额(超大单)",
     sumof(["超大单"],["zmm"]=2) as "流出额(超大单)",
     sumof(["大单"],["zmm"]=1) as "流入额(大 单)",
     sumof(["大单"],["zmm"]=2) as "流出额(大 单)",
     sumof(["中单"],["zmm"]=1) as "流入额(中 单)",
     sumof(["中单"],["zmm"]=2) as "流出额(中 单)",
     sumof(["小单"],["zmm"]=1) as "流入额(小 单)",
     sumof(["小单"],["zmm"]=2) as "流出额(小 单)"
    from tradData group by ["daymin"] order by ["daymin"] end;
    return tradd;
    End;
    '''
    #设置并发数-不重连方式
    batch = pyTSL.Batch(4)#账号一般并发数是5个,用户可根据情况调整
    #逐个代码提交并发任务
    for s in bk:
      task =batch.call(c,"Stock_BuyAndSellminuteTracking",s,Endt,Endt,key="{}-{}".format(s,Endt),code=buy_and_sell_data)

      if task[0]==0:
        print(task[1])

    #将结果合并到DataFrame中
    df=pd.DataFrame()
    for r in iter(batch):#对结果进行处理
      df=pd.concat([df,r.dataframe()]) #合并所有任务的结果集

    print(df)

    c.logout() #断开登陆

    #打印结果: