返回列表 发布新帖

分享一个内部python回测期货的示例

2060 2
发表于 2023-12-15 16:27:36 | 显示全部楼层 阅读模式
  1. # coding:gbk



  2. class _a():
  3.     pass

  4. A = _a()

  5. def init(C):
  6.     # print("2122231232132324")
  7.     A.symbol = "c2401.DF" # 填一个具体合约,跑不起来大概率就是你没有下载本地数据
  8.     A.period = "1m"
  9.     C.accID = "123123"
  10.     return
  11.    

  12. def handlebar(C):
  13.     # print(C.barpos)
  14.     backTestTime = timetag_to_datetime(C.get_bar_timetag(C.barpos),"%Y%m%d%H%M%S")
  15.     print(backTestTime)
  16.     kline = C.get_market_data_ex(['open', 'high','low','close'],[A.symbol],period = A.period, end_time = backTestTime)[A.symbol]
  17.     # print(123)
  18.     # print(kline)
  19.     ma5 = kline["close"].rolling(5).mean()
  20.     ma10 = kline["close"].rolling(10).mean()
  21.     holding = get_Future_holdings(C.accID)
  22.     lots = holding.get(A.symbol,{}).get("净持仓",0)
  23.     print(f"已走完K线 --- ma5:{ma5.iloc[-2]}  ma10:{ma10.iloc[-2]}" )
  24.     print(f"最新K线 --- ma5:{ma5.iloc[-1]}  ma10:{ma10.iloc[-1]}" )
  25.     # print(ma5.iloc[-2] > ma10.iloc[-2] )
  26.     if ma5.iloc[-2] > ma10.iloc[-2] and ma5.iloc[-3] < ma10.iloc[-3]:
  27.         print(f"ma5上穿ma10")
  28.         if lots < 0:
  29.             my_passorder(C,A.symbol, "buy_close", abs(lots))
  30.         
  31.         my_passorder(C,A.symbol, "buy_open",1)
  32.     elif ma5.iloc[-2] < ma10.iloc[-2] and ma5.iloc[-3] > ma10.iloc[-3]:
  33.         print(f"ma5下穿ma10")
  34.         if lots > 0:
  35.             my_passorder(C,A.symbol, "sell_close", lots)
  36.         
  37.         my_passorder(C,A.symbol, "sell_open",1)
  38.         
  39.     # .get market data ex(['open', 'high','low','close'],['510300.SH']
  40.     return


  41. def my_passorder(C,Futuer:str,opentype:str,lots:int,price = None,m_strRemark = '系统备注'):
  42.     '''
  43.    
  44.     Args:
  45.         C: ContextInfo \n
  46.         Futuer: 期货代码 \n

  47.         opentype:
  48.                 'buy_open' 开多\n
  49.                 'sell_open' 开空\n
  50.                 'sell_close' 平多\n
  51.                 'buy_close' 平空\n
  52.         lots: 手
  53.         price: 下单价格,不指定时默认按市价下单
  54.         m_strRemark = '系统备注' 用于自定义寻找orderID
  55.     '''
  56.     Futuer_ExchangeID = Futuer.split(".")[1]
  57.     opentype = opentype #买卖方向
  58.     op =1101  #手数
  59.     # 期货区分开平
  60.     if opentype == "buy_open":
  61.         opType = 0
  62.     elif opentype == "sell_open":
  63.         opType = 3
  64.     elif opentype == "sell_close":
  65.         opType = 7
  66.     elif opentype == "buy_close":
  67.         opType = 9

  68.     volumex = lots
  69.     price = 0 if not price else price # price参数必须存在
  70.     if Futuer_ExchangeID == "SF":
  71.         prType = 14 if not price else 11 # 对于上期所,若不指定价格,则默认按对手价下单
  72.     elif Futuer_ExchangeID == "DF" or Futuer_ExchangeID == "ZF":
  73.         prType = 12 if not price else 11 # 对于大商所和郑商所,若不指定价格,则默认按涨跌停价下单
  74.     else:
  75.         prType = 14 if not price else 11 # 对于其他所,若不指定价格,则默认按对手价下单

  76.     print(f'{Futuer} 新委托信息 方向{opentype} 价格{price} 量{volumex}')
  77.     #print(f"opType:{opType} , op:{op} , C.accID{C.accID} , stock{stock} , prType{prType} , price{price} , volumex{volumex}")
  78.     passorder(opType, op, C.accID,Futuer, prType, price, volumex,'交易注释',1,'{}'.format(m_strRemark), C)
  79.     print(f'委托发送完成')






  80. def get_Future_holdings(accid,symbol = None):
  81.     '''
  82.     针对期货返回持仓的奇葩结构做处理
  83.     Arg:
  84.         accondid:账户id
  85.         symbol: 品种,不填默认返会全部持仓
  86.             
  87.     return:
  88.         {股票名:{'手数':int,"持仓成本":float,'浮动盈亏':float,"可用余额":int}}
  89.     '''
  90.     datatype = "FUTURE"
  91.    
  92.     PositionInfo_dict = {}
  93.    
  94.     Long_dict={}
  95.    
  96.     Short_dict={}
  97.    
  98.     resultlist = get_trade_detail_data(accid,datatype,'POSITION')
  99.    
  100.     for obj in resultlist:
  101.         #防除零
  102.         if obj.m_nVolume == 0:
  103.             continue
  104.         if obj.m_nDirection == 48:
  105.             if not Long_dict.get(obj.m_strInstrumentID+"."+obj.m_strExchangeID):
  106.                 Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID] = {
  107.                 "多头数量":obj.m_nVolume,
  108.                 "多头成本":obj.m_dOpenPrice,
  109.                
  110.                 "浮动盈亏":obj.m_dFloatProfit,
  111.                 "保证金占用":obj.m_dMargin
  112.                 }
  113.             else:
  114.                     
  115.                     Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["多头数量"] += obj.m_nVolume
  116.                     # 算浮动盈亏
  117.                     Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["浮动盈亏"] += obj.m_dFloatProfit
  118.                     # 算保证金占用
  119.                     Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["保证金占用"] += obj.m_dMargin
  120.                     # 算多头成本
  121.                     Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["多头成本"] = (
  122.                         Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["多头成本"] * \
  123.                         (Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["多头数量"] - obj.m_nVolume) + \
  124.                         (obj.m_dOpenPrice * obj.m_nVolume)
  125.                     )/Long_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["多头数量"]
  126.                     
  127.         elif obj.m_nDirection == 49:
  128.             if not Short_dict.get(obj.m_strInstrumentID+"."+obj.m_strExchangeID):
  129.                 Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID] = {
  130.                 "空头数量":obj.m_nVolume  ,
  131.                 "空头成本":obj.m_dOpenPrice ,
  132.                 "浮动盈亏":obj.m_dFloatProfit,
  133.                 "保证金占用":obj.m_dMargin
  134.                 }
  135.             else:
  136.                 Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["空头数量"] += obj.m_nVolume
  137.                 # 算浮动盈亏
  138.                 Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["浮动盈亏"] += obj.m_dFloatProfit
  139.                 # 算保证金占用
  140.                 Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["保证金占用"] += obj.m_dMargin
  141.                 # 计算空头成本
  142.                 Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["空头成本"] = (
  143.                     Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["空头成本"] * \
  144.                     (Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["空头数量"] - obj.m_nVolume) + \
  145.                     (obj.m_dOpenPrice * obj.m_nVolume)
  146.                 )/Short_dict[obj.m_strInstrumentID+"."+obj.m_strExchangeID]["空头数量"]
  147.         
  148.    
  149.     for _symbol in set(list(Long_dict.keys()) + list(Short_dict.keys())):
  150.         
  151.         PositionInfo_dict[_symbol] = {
  152.         "多头数量":Long_dict[_symbol]["多头数量"] if Long_dict.get(_symbol) else 0 ,
  153.         
  154.         "空头数量":Short_dict[_symbol]["空头数量"] if Short_dict.get(_symbol) else 0 ,
  155.         
  156.         "多头成本":Long_dict[_symbol]["多头成本"] if Long_dict.get(_symbol) else None ,
  157.         
  158.         "空头成本":Short_dict[_symbol]["空头成本"] if Short_dict.get(_symbol) else None,
  159.         
  160.         "净持仓" : Long_dict.get(_symbol,{}).get("多头数量",0) -  Short_dict.get(_symbol,{}).get("空头数量",0),
  161.         
  162.         "浮动盈亏": Long_dict.get(_symbol,{}).get("浮动盈亏",0) +  Short_dict.get(_symbol,{}).get("浮动盈亏",0),
  163.         
  164.         "保证金占用": Long_dict.get(_symbol,{}).get("保证金占用",0) +  Short_dict.get(_symbol,{}).get("保证金占用",0)
  165.         }
  166.         
  167.     if symbol:
  168.         return PositionInfo_dict[symbol]
  169.     else :
  170.         return PositionInfo_dict








复制代码


评论2

rzp
发表于 2023-12-22 12:00:35 | 显示全部楼层
太好了
一鋮
发表于 2025-1-15 21:41:09 | 显示全部楼层
以后有用

回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2025 迅投QMT社区 版权所有 All Rights Reserved. 京ICP备2025122616号-3
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表