class Item(object):
"""单笔交易对象,存储购买日期和数量 可能是买入也可能是卖出"""
def __init__(self, time, num):
if type(time) is int or type(time) is str:
self.time = datetime.datetime.strptime(str(time),'%Y%m%d')
else:
self.time = time
if type(num) is str:
self.num = int(num)
else:
self.num = num
class Position(object):
"""头寸对象,存储某人员对于某股票的全部头寸 以队列模式先进先出"""
def __init__(self, stock_name, person_name):
self.items = []
self.stock_name = stock_name
self.person_name = person_name
def is_empty(self):
return self.items == []
def buy(self, item):
"""有买入则在items列表里追加此次交易记录"""
self.items.append(item)
def sell(self, item, limit):
"""根据卖出的交易记录更新本头寸 返回可能存在的相关交易信息(以元组的列表返回)"""
related = []
# 首次记录先是卖的,则pass
if len(self.items) == 0 :
return related
else:
# 不断根据卖出数量抵消买入记录,时间最久远的先被抵消,完全抵消后离开队列,卖出数量抵完为止
while item.num > 0:
# 判断此次抵消的买入记录是否和卖出记录的日期差≤limit天
if (item.time.date() - self.items[0].time.date()).days <= limit:
# 发现相关交易,将相关信息打包为元组,放入列表related
info = (self.person_name, self.stock_name, self.items[0].time,
self.items[0].num,
item.time,
min(item.num,self.items[0].num),
(item.time.date() - self.items[0].time.date()).days)
related.append(info)
# 判断最远的一次买入是否能完全抵消剩余卖出数量(临界值稍微注意,和不能一样也需要删除队列头)
if item.num >= self.items[0].num:
# 不能,则先用最远的买入抵消部分卖出,剩余的卖出数量继续被后面的买入抵消
item.num -= self.items[0].num
# 最远的买入记录离开队列,循环继续
del (self.items[0])
if len(self.items) == 0: # 如果卖的比买的多,直接跳出循环
return related
else:
# 能,则最远的买入记录完全消化剩余卖出数量,并留有余量,下一次循环会停止
self.items[0].num -= item.num
item.num = 0
return related
def FIFO(df,col_people,col_stock,col_time,col_num,col_type,limit=1e4):
df = df.sort_values(by=col_time)
# dic 以人员,股票为索引存储所有头寸的字典
dic = {}
relate = []
for row in df.iterrows():
name = row[1][col_people]
date = row[1][col_time]
stock = row[1][col_stock]
num = row[1][col_num]
type = row[1][col_type]
index = name + ','+stock
if index not in dic:
dic[index] = Position(person_name=name, stock_name=stock)
if type == '买入':
dic[index].buy(Item(date, num))
else:
#卖出交易返回信息
relate += (dic[index].sell(Item(date,num),limit))
print(name,date,stock,type)
result = pd.DataFrame(relate)
result.columns = ['PERSON','INSTRUMENT_CODE','BUY_TIME','BUY_VOLUME_CUMSUM','SELL_TIME','SELL_VOLUME','INTERVAL_DAYS']
return result
先进先出匹配交易
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 先进先出 - 队列效果(后面的数据把前面的数据往前顶) 先进先出: unshift + pop 组合 先进后出 -...
- 今日金句:商业的本质是交易,更先进的商业,就是更高效率的交易。 日新团队名称由来“日日新、苟日新、又日新”(出自:...
- 从定义来说, 栈限定仅在表尾进行插入或删除操作的线性表。也就是说它有两个操作,且操作数[https://www.b...