In [3]:
import numpy as np
from collections import namedtuple
In [4]:
'''
struct to storage order price and volume to trade
Usage:
a = Order(price=1, volume=1)
'''
Order = namedtuple('order', 'id price volume')
In [5]:
class dynamic_order:
'''
extension of Order, used in making deals
'''
def __init__(self, order):
assert isinstance(order, Order)
self.id = order.id
self.price = order.price
self.volume = order.volume
@property
def show(self):
print('id : %d' % self.id)
print('price : %d' % self.price)
print('volume : %d' % self.volume)
In [75]:
class Trader:
'''
A primary class to define an investor
'''
def __init__(self, id):
self.id = id
self.cash = 0 # 现金
self.cash_history = []
self.asset = 0 # 总资产
self.asset_history = []
self.stock = 0 # 持股
self.stock_history = []
self.trade_history = [] # 交易记录
self.price = 0
self.order = Order(id=self.id,
price=0,
volume=0)
def gen_order(self):
self.order = Order(id=self.id,
price=np.random.randint(-10, 10),
volume=np.random.randint(1, 5))
def update(self, price, vol):
vol *= np.sign(self.order.price)
price = abs(price)
self.cash -= price * vol
self.cash_history.append(self.cash)
self.stock += vol
self.stock_history.append(self.stock)
self.trade_history.append((price, vol))
self.price = price
self.asset = self.cash + self.stock * self.price
self.asset_history.append(self.asset)
@property
def show(self):
print('id : %d, cash : %d, stock : %d, stock_price : %d, asset : %d' %
(self.id, self.cash, self.stock, self.price, self.asset))
# print('asset : %d' % self.asset)
# print('stock : %d' % self.stock)
In [92]:
def make_deals(orders):
buy_list = [dynamic_order(order) for order in orders if order.price>0]
sell_list = [dynamic_order(order) for order in orders if order.price<0]
buy_list = sorted(buy_list, key=lambda x:(-x.price, x.id))
sell_list = sorted(sell_list, key=lambda x:(abs(x.price), x.id))
deal_result = np.zeros(len(orders), int)
price = 0
if len(buy_list)==0 or len(sell_list)==0:
return price, deal_result
while sell_list[0].price+buy_list[0].price>=0:
if sell_list[0].volume>=buy_list[0].volume:
sell_list[0].volume -= buy_list[0].volume
deal_result[buy_list[0].id] += buy_list[0].volume
deal_result[sell_list[0].id] += buy_list[0].volume
if sell_list[0].volume==buy_list[0].volume:
price = (buy_list[0].price + abs(sell_list[0].price)) / 2
else:
price = abs(sell_list[0].price)
_ = buy_list.pop(0)
else:
buy_list[0].volume -= sell_list[0].volume
deal_result[buy_list[0].id] += sell_list[0].volume
deal_result[sell_list[0].id] += sell_list[0].volume
price = buy_list[0].price
_ = sell_list.pop(0)
price = abs(price)
if len(buy_list)==0 or len(sell_list)==0:
break
return price, deal_result
In [93]:
investors = [Trader(i) for i in range(200)]
In [94]:
start = time.time()
for step in range(3000):
orders = []
for investor in investors:
investor.gen_order()
orders.append(investor.order)
price, deal_result = make_deals(orders)
for i,investor in enumerate(investors):
investor.update(price=price, vol=deal_result[i])
print('用时:', time.time()-start)
In [91]:
len(orders)
Out[91]:
In [79]:
for investor in investors:
investor.show
In [80]:
import time
a = time.time()
In [82]:
b = time.time()-a
print(b)