def make_trades(stock, signal, tdate, tpositive, tnegative, begin=0, taxrate=125, trade_strategy=buy_first, extra_func=default_extra): ''' stock为stock ssingal为买卖信号,对于次日买卖的信号,输入前需要将signal roll(1) tpositive,tnegative为信号值为正和负时的选择价格 taxrate为税率,默认为千分之八 begin为起始交易日 trade_strategy为交易方式,先买后卖,先卖后买,还是均可 以买入开始计算 ''' assert len(tpositive) == len(tnegative) == len(signal) #print signal,'=signal' sis = signal.nonzero()[0] #非0信号的index slen = len(sis) if slen == 0: return [] tbegin = tdate.searchsorted(begin) ibegin = sis.searchsorted(tbegin) #tbegin在非0索引中的插入位置 #print tbegin,ibegin if ibegin >= slen: #空信号 return [] should_skip = trade_strategy(signal[sis[ibegin]]) ibegin += should_skip if ibegin >= slen: #仍然是空信号 return [] #print signal[tbegin:].tolist(),sis,ibegin,tbegin tbegin = sis[ibegin] trades = [] #print sis #print tnegative for i in xrange(ibegin, slen): ci = sis[i] cs = signal[ci] #通常是1/-1,只有正/负有意义,数值本身无意义 price = tpositive[ci] if cs > 0 else tnegative[ci] #print ci,cs,price,tdate[ci],tnegative[ci] ctrade = Trade( stock.code, int(tdate[ci]), int(price), int(cs) * VOLUME_BASE, taxrate ) #int强制转换,避免把numpy.int32传入trade.因为ndarray索引得到的值是numpy.intxx的,而非普通int ctrade.stock = stock ctrade.idate = ci trades.append(extra_func(ctrade, stock, ci)) #if sum(signal[tbegin:]) != 0: #最后一个未平仓,不计算。 这一点已经在match_trades中保证 #print sum(signal[tbegin:]),signal[tbegin:].tolist() # trades.pop() #print trades[-1].tdate,trades[-1].tvolume,trades[-1].tprice return trades
def organize_trades(self, named_trades): trades = PositionManager.organize_trades(self, named_trades) #for trade in trades: # print trade if len(trades) == 0: return trades new_trades = [] ti = 0 tcur = trades[ti] dlen = len(trades[0].stock.transaction[CLOSE]) holding = {} for i in xrange(dlen): for hold in holding.values(): #i=0是没有持仓,所以不需要判断i>1 tlimit = (hold[0].transaction[CLOSE][i - 1] + hold[0].transaction[HIGH][i - 1]) / 2 base = hold[-1] #print tlimit,hold[1]+hold[2] if (tlimit > hold[1] + hold[2] and tlimit < base.tprice + hold[2] * 5): #当不超过3ATR时,添加一个trade #print base.tstock,self.dates[i],tlimit,hold[1],hold[2],base.tprice tvolume = base.tvolume / 2 or 1 trade = Trade(base.tstock, int(self.dates[i]), int(hold[0].transaction[OPEN][i]), tvolume, base.taxrate) trade.stock = base.stock trade.atr = int(base.stock.atr2[i]) trade.type = 'append' new_trades.append(trade) holding[hold[0]][1] = hold[1] + hold[2] #更改起始价格 while tcur.idate == i: if tcur.tvolume > 0: holding[tcur.stock] = [ tcur.stock, tcur.tprice, int(tcur.stock.atr2[i]), tcur ] elif tcur.tvolume < 0 and tcur.stock in holding: #print 'del:',tcur.tdate del holding[tcur.stock] ti += 1 if ti >= len(trades): break tcur = trades[ti] if ti >= len(trades): break trades[0:0] = new_trades #插入到前面,以便如果B/S同时出现,B排序在前面 trades.sort(cmp=lambda x, y: x.tdate - y.tdate) #for trade in trades:print trade return trades
def make_trades(stock,signal,tdate,tpositive,tnegative ,begin=0,taxrate=125,trade_strategy=buy_first,extra_func=default_extra): ''' stock为stock ssingal为买卖信号,对于次日买卖的信号,输入前需要将signal roll(1) tpositive,tnegative为信号值为正和负时的选择价格 taxrate为税率,默认为千分之八 begin为起始交易日 trade_strategy为交易方式,先买后卖,先卖后买,还是均可 以买入开始计算 ''' assert len(tpositive) == len(tnegative) == len(signal) #print signal,'=signal' sis = signal.nonzero()[0] #非0信号的index slen = len(sis) if slen == 0: return [] tbegin = tdate.searchsorted(begin) ibegin = sis.searchsorted(tbegin) #tbegin在非0索引中的插入位置 #print tbegin,ibegin if ibegin >= slen: #空信号 return [] should_skip = trade_strategy(signal[sis[ibegin]]) ibegin += should_skip if ibegin >= slen: #仍然是空信号 return [] #print signal[tbegin:].tolist(),sis,ibegin,tbegin tbegin = sis[ibegin] trades = [] #print sis #print tnegative for i in xrange(ibegin,slen): ci = sis[i] cs = signal[ci] #通常是1/-1,只有正/负有意义,数值本身无意义 price = tpositive[ci] if cs>0 else tnegative[ci] #print ci,cs,price,tdate[ci],tnegative[ci] ctrade = Trade(stock.code,int(tdate[ci]),int(price),int(cs)*VOLUME_BASE,taxrate) #int强制转换,避免把numpy.int32传入trade.因为ndarray索引得到的值是numpy.intxx的,而非普通int ctrade.stock = stock ctrade.idate = ci trades.append(extra_func(ctrade,stock,ci)) #if sum(signal[tbegin:]) != 0: #最后一个未平仓,不计算。 这一点已经在match_trades中保证 #print sum(signal[tbegin:]),signal[tbegin:].tolist() # trades.pop() #print trades[-1].tdate,trades[-1].tvolume,trades[-1].tprice return trades
def organize_trades(self,named_trades): trades = PositionManager.organize_trades(self,named_trades) #for trade in trades: # print trade if len(trades) == 0: return trades new_trades = [] ti = 0 tcur = trades[ti] dlen = len(trades[0].stock.transaction[CLOSE]) holding = {} for i in xrange(dlen): for hold in holding.values(): #i=0是没有持仓,所以不需要判断i>1 tlimit = (hold[0].transaction[CLOSE][i-1] + hold[0].transaction[HIGH][i-1])/2 base = hold[-1] #print tlimit,hold[1]+hold[2] if(tlimit > hold[1] + hold[2] and tlimit < base.tprice + hold[2]*5):#当不超过3ATR时,添加一个trade #print base.tstock,self.dates[i],tlimit,hold[1],hold[2],base.tprice tvolume = base.tvolume/2 or 1 trade = Trade(base.tstock,int(self.dates[i]),int(hold[0].transaction[OPEN][i]),tvolume,base.taxrate) trade.stock = base.stock trade.atr = int(base.stock.atr2[i]) trade.type = 'append' new_trades.append(trade) holding[hold[0]][1] = hold[1] + hold[2] #更改起始价格 while tcur.idate == i: if tcur.tvolume>0: holding[tcur.stock] = [tcur.stock,tcur.tprice,int(tcur.stock.atr2[i]),tcur] elif tcur.tvolume<0 and tcur.stock in holding: #print 'del:',tcur.tdate del holding[tcur.stock] ti += 1 if ti >= len(trades): break tcur = trades[ti] if ti>=len(trades): break trades[0:0]= new_trades #插入到前面,以便如果B/S同时出现,B排序在前面 trades.sort(cmp=lambda x,y:x.tdate-y.tdate) #for trade in trades:print trade return trades