@@ -28,8 +28,10 @@ def __init__(self, blotters, dcontexts, strpcon, i):
2828 for key , value in dcontexts .iteritems ():
2929 self ._dcontexts [key ] = value
3030
31- def name (self , j ):
32- return self ._blts [j ].name
31+ def name (self , j = None ):
32+ if j != None :
33+ return self ._blts [j ].name
34+ return self ._blts [0 ].name
3335
3436 def transactions (self , j = None ):
3537 """ 第j个策略的所有成交明细, 默认返回组合的成交明细。
@@ -147,6 +149,7 @@ def technicals(self, j=None, strpcon=None):
147149 return rst
148150
149151 def data (self , strpcon = None ):
152+ ## @TODO execute_unit._parse_pcontracts()
150153 """ 周期合约数据, 只有向量运行才有意义。
151154
152155 Args:
@@ -155,10 +158,10 @@ def data(self, strpcon=None):
155158 Returns:
156159 pd.DataFrame. 数据
157160 """
158- pcon = self . _main_pcontract
159- if strpcon :
160- pcon = PContract . from_string ( strpcon )
161- return self ._dcontexts [pcon ].raw_data
161+ if not strpcon :
162+ strpcon = self . _main_pcontract
163+ strpcon = strpcon . upper ()
164+ return self ._dcontexts [strpcon ].raw_data
162165
163166 def _update_positions (self , current_positions , deal_positions , trans ):
164167 """ 根据交易明细计算开平仓对。 """
@@ -270,6 +273,7 @@ def __init__(self, name, events_pool, settings={ }):
270273 def all_holdings (self ):
271274 """ 账号历史情况,最后一根k线处平所有仓位。"""
272275 if self .positions :
276+ #assert False
273277 self ._force_close ()
274278 return self ._all_holdings
275279
@@ -302,8 +306,9 @@ def update_datetime(self, dt):
302306 pos .today = 0
303307 self ._datetime = dt
304308
305- def update_status (self , dt , at_baropen = True ):
309+ def update_status (self , dt , at_baropen , append ):
306310 """ 更新历史持仓,当前权益。"""
311+ ## @TODO open_orders 和 postion_margin分开,valid_order调用前再统计?
307312 # 更新资金历史。
308313 dh = { }
309314 dh ['datetime' ] = dt
@@ -329,6 +334,11 @@ def update_status(self, dt, at_baropen=True):
329334 # 当前权益 = 初始资金 + 累积平仓盈亏 + 当前持仓盈亏 - 历史佣金总额
330335 dh ['equity' ] = self ._capital + self .holding ['history_profit' ] + pos_profit - \
331336 self .holding ['commission' ]
337+ ## @TODO
338+ # 对于股票,Bar的开盘和收盘点资金验证是一致的。
339+ # 如果期货不一致,成交撮合时候也无法确定确切的时间点,
340+ # ,就无法确定精确的可用资金,可能因此导致cash<0, 就得加
341+ # 强平功能,使交易继续下去。
332342 dh ['cash' ] = dh ['equity' ] - margin - order_margin
333343 if dh ['cash' ] < 0 :
334344 for key in self .positions .iterkeys ():
@@ -338,24 +348,33 @@ def update_status(self, dt, at_baropen=True):
338348 self .holding ['cash' ] = dh ['cash' ]
339349 self .holding ['equity' ] = dh ['equity' ]
340350 self .holding ['position_profit' ] = pos_profit
341- if at_baropen :
351+ if append :
342352 self ._all_holdings .append (dh )
343353 else :
344354 self ._all_holdings [- 1 ] = dh
345355
346356 def update_signal (self , event ):
347- """ 处理策略函数产生的下单事件。 """
357+ """ 处理策略函数产生的下单事件。
358+
359+ 可能产生一系列order事件,在bar的开盘时间交易。
360+ """
348361 assert event .type == Event .SIGNAL
349362 new_orders = []
350363 for order in event .orders :
351- if self ._valid_order (order ):
364+ errmsg = self ._valid_order (order )
365+ if errmsg == '' :
352366 order .datetime = self ._datetime
353- self .api .order (copy .deepcopy (order ))
354367 new_orders .append (order )
368+ if order .side == TradeSide .KAI :
369+ self .holding ['cash' ] -= order .order_margin (self ._bars [order .contract ].open )
355370 else :
371+ logger .warn (errmsg )
372+ #print len(event.orders), len(new_orders)
356373 continue
357374 self .open_orders .update (new_orders ) # 改变对象的值,不改变对象地址。
358375 self ._all_orders .extend (new_orders )
376+ for order in new_orders :
377+ self .api .order (copy .deepcopy (order ))
359378 for order in new_orders :
360379 if order .side == TradeSide .PING :
361380 pos = self .positions [PositionKey (order .contract , order .direction )]
@@ -412,6 +431,7 @@ def _update_holding(self, trans):
412431 flag = 1 if trans .direction == Direction .LONG else - 1
413432 profit = (trans .price - self .positions [poskey ].cost ) * trans .quantity * \
414433 flag * trans .volume_multiple
434+ #print profit, trans.price, trans.quantity
415435 #if self.name == 'A1': # 平仓调试
416436 #print "***********"
417437 #print self._datetime, profit
@@ -421,28 +441,27 @@ def _update_holding(self, trans):
421441 def _valid_order (self , order ):
422442 """ 判断订单是否合法。 """
423443 if order .quantity <= 0 :
424- raise TradingError ( err = "交易数量不能小于0" )
444+ return "交易数量要大于0"
425445 # 撤单
426446 if order .side == TradeSide .CANCEL :
427447 if order not in self .open_orders :
428- raise TradingError ( err = '撤销失败: 不存在该订单!' )
448+ return '撤销失败: 不存在该订单!'
429449 if order .side == TradeSide .PING :
430450 try :
431451 poskey = PositionKey (order .contract , order .direction )
432452 pos = self .positions [poskey ]
433453 if pos .closable < order .quantity :
434- raise TradingError ( err = '可平仓位不足' )
454+ return '可平仓位不足'
435455 except KeyError :
436456 # 没有持有该合约
437457 #logger.warn("不存在合约[%s]" % order.contract)
438- raise TradingError ( err = "不存在合约[%s]" % order .contract )
458+ return "不存在合约[%s]" % order .contract
439459 elif order .side == TradeSide .KAI :
440- new_price = self ._bars [order .contract ].close
460+ new_price = self ._bars [order .contract ].open
441461 if self .holding ['cash' ] < order .order_margin (new_price ):
442- raise TradingError (err = '没有足够的资金开仓' )
443- else :
444- self .holding ['cash' ] -= order .order_margin (new_price )
445- return True
462+ #print self.holding['cash'], new_price * order.quantity
463+ return '没有足够的资金开仓'
464+ return ''
446465
447466 def _force_close (self ):
448467 """ 在回测的最后一根k线以close价格强平持仓位。 """
@@ -463,7 +482,7 @@ def _force_close(self):
463482 self ._update_holding (trans )
464483 self ._update_positions (trans )
465484 if force_trans :
466- self .update_status (trans .datetime , False )
485+ self .update_status (trans .datetime , False , False )
467486 self .positions = { }
468487 return
469488
0 commit comments