Skip to content

Commit

Permalink
remove data oracle and other changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mamahfouz committed Jun 19, 2019
1 parent ffd4f3d commit 7079c23
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 3,914 deletions.
30 changes: 14 additions & 16 deletions agent/ExchangeAgent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
from util.OrderBook import OrderBook
from util.util import log_print

import sys

import jsons as js
import numpy as np
import pandas as pd
Expand Down Expand Up @@ -68,17 +66,25 @@ def kernelInitializing (self, kernel):

# Obtain opening prices (in integer cents). These are not noisy right now.
for symbol in self.order_books:
self.order_books[symbol].last_trade = self.oracle.getDailyOpenPrice(symbol, self.mkt_open)
log_print ("Opening price for {} is {}", symbol, self.order_books[symbol].last_trade)
try:
self.order_books[symbol].last_trade = self.oracle.getDailyOpenPrice(symbol, self.mkt_open)
log_print ("Opening price for {} is {}", symbol, self.order_books[symbol].last_trade)
except AttributeError as e:
log_print(str(e))


# The exchange agent overrides this to additionally log the full depth of its
# order books for the entire day.
def kernelTerminating (self):
super().kernelTerminating()

# Skip order book dump if requested.
if self.book_freq is None: return
if self.book_freq is None:
for symbol in self.order_books:
book = self.order_books[symbol]
dfLog = pd.DataFrame([book.mid_dict, book.bid_levels_price_dict, book.bid_levels_size_dict,
book.ask_levels_price_dict, book.ask_levels_size_dict]).T
dfLog.columns = ['mid_price', 'bid_level_prices', 'bid_level_sizes', 'ask_level_prices', 'ask_level_sizes']
self.writeLog(dfLog, filename='orderbook_{}'.format(symbol))

# Iterate over the order books controlled by this exchange.
for symbol in self.order_books:
Expand Down Expand Up @@ -137,7 +143,7 @@ def kernelTerminating (self):
# to the exchange agent log.
self.writeLog(df, filename='orderbook_{}'.format(symbol))

print ("Order book archival complete.")
print ("Order book archival complete.")


def receiveMessage (self, currentTime, msg):
Expand Down Expand Up @@ -271,15 +277,7 @@ def receiveMessage (self, currentTime, msg):
log_print ("Modification request discarded. Unknown symbol: {}".format(order.symbol))
else:
self.order_books[order.symbol].modifyOrder(deepcopy(order), deepcopy(new_order))
elif msg.body['msg'] == 'REPLICATE_ORDERBOOK_SNAPSHOT':
timestamp = msg.body['timestamp']
symbol = msg.body['symbol']
log_print ("{} received REPLICATE_ORDERBOOK_SNAPSHOT for t= {}".format(self.name, timestamp))
if symbol not in self.order_books:
log_print ("Orderbook replication request discarded. Unknown symbol: {}".format(symbol))
else:
self.order_books[symbol].replicateOrderbookSnapshot()



def sendMessage (self, recipientID, msg):
# The ExchangeAgent automatically applies appropriate parallel processing pipeline delay
Expand Down
11 changes: 8 additions & 3 deletions agent/ExperimentalAgent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
class ExperimentalAgent(TradingAgent):

def __init__(self, id, name, symbol,
startingCash, execution_timestamp, quantity, is_buy_order, limit_price,
random_state = None):
super().__init__(id, name, startingCash, random_state)
starting_cash, execution_timestamp, quantity, is_buy_order, limit_price,
log_orders = False, random_state = None):
super().__init__(id, name, starting_cash, random_state)
self.symbol = symbol
self.execution_timestamp = execution_timestamp
self.quantity = quantity
self.is_buy_order = is_buy_order
self.limit_price = limit_price
self.log_orders = log_orders

def kernelStarting(self, startTime):
super().kernelStarting(startTime)
Expand All @@ -24,6 +25,10 @@ def wakeup(self, currentTime):
elif (currentTime > self.mkt_open) and (currentTime < self.mkt_close):
if currentTime == self.execution_timestamp:
self.placeLimitOrder(self.symbol, self.quantity, self.is_buy_order, self.limit_price, dollar=False)
if self.log_orders: self.logEvent('LIMIT_ORDER', {'agent_id': self.id, 'dollar': False, 'fill_price': None,
'is_buy_order': self.is_buy_order, 'limit_price': self.limit_price,
'order_id': 1, 'quantity': self.quantity, 'symbol': self.symbol,
'time_placed': str(currentTime)})

def receiveMessage(self, currentTime, msg):
super().receiveMessage(currentTime, msg)
Expand Down
80 changes: 29 additions & 51 deletions agent/MarketReplayAgent.py
Original file line number Diff line number Diff line change
@@ -1,86 +1,73 @@
import pandas as pd

from agent.TradingAgent import TradingAgent
from util.util import log_print
from util.order.LimitOrder import LimitOrder
from message.Message import Message
from util.util import log_print


class MarketReplayAgent(TradingAgent):


def __init__(self, id, name, symbol, date, startingCash, log_orders = False, random_state = None):
super().__init__(id, name, startingCash, random_state)
def __init__(self, id, name, type, symbol, date, starting_cash, log_orders = False, random_state = None):
super().__init__(id, name, type, starting_cash=starting_cash, log_orders=log_orders, random_state = random_state)
self.symbol = symbol
self.date = date
self.log_orders = log_orders
self.log_orders = log_orders
self.state = 'AWAITING_WAKEUP'


def kernelStarting(self, startTime):
super().kernelStarting(startTime)
self.oracle = self.kernel.oracle

def kernelStopping (self):
super().kernelStopping()

def wakeup (self, currentTime):
super().wakeup(currentTime)
self.last_trade[self.symbol] = self.oracle.getDailyOpenPrice(self.symbol, self.mkt_open)
if not self.mkt_open or not self.mkt_close:
return
order = self.oracle.trades_df.loc[self.oracle.trades_df.timestamp == currentTime]
wake_up_time = self.oracle.trades_df.loc[self.oracle.trades_df.timestamp > currentTime].iloc[0].timestamp
if currentTime == self.oracle.orderbook_df.iloc[0].name:
self.placeMktOpenOrders(order, t=currentTime)
elif (currentTime > self.mkt_open) and (currentTime < self.mkt_close):
try:
self.placeOrder(currentTime, order)
except Exception as e:
log_print(e)
self.setWakeup(wake_up_time)
self.state = 'INACTIVE'
try:
super().wakeup(currentTime)
self.last_trade[self.symbol] = self.oracle.getDailyOpenPrice(self.symbol, self.mkt_open)
if not self.mkt_open or not self.mkt_close:
return
order = self.oracle.trades_df.loc[self.oracle.trades_df.timestamp == currentTime]
wake_up_time = self.oracle.trades_df.loc[self.oracle.trades_df.timestamp > currentTime].iloc[0].timestamp
if (currentTime > self.mkt_open) and (currentTime < self.mkt_close):
self.state = 'ACTIVE'
try:
self.placeOrder(currentTime, order)
except Exception as e:
log_print(e)
self.setWakeup(wake_up_time)
except Exception as e:
log_print(str(e))


def receiveMessage (self, currentTime, msg):
super().receiveMessage(currentTime, msg)


def placeMktOpenOrders(self, snapshot_order, t=0):
orders_snapshot = self.oracle.orderbook_df.loc[self.oracle.orderbook_df.index == t].T
for i in range(0, len(orders_snapshot) - 1, 4):
ask_price = orders_snapshot.iloc[i][0]
ask_vol = orders_snapshot.iloc[i + 1][0]
bid_price = orders_snapshot.iloc[i + 2][0]
bid_vol = orders_snapshot.iloc[i + 3][0]

if snapshot_order.direction.item() == 'BUY' and bid_price == snapshot_order.price.item():
bid_vol -= snapshot_order.vol.item()
elif snapshot_order.direction.item() == 'SELL' and ask_price == snapshot_order.price.item():
ask_vol -= snapshot_order.vol.item()

self.placeLimitOrder(self.symbol, bid_vol, True, float(bid_price), dollar=False)
self.placeLimitOrder(self.symbol, ask_vol, False, float(ask_price), dollar=False)
self.placeOrder(snapshot_order.timestamp.item(), snapshot_order)


def placeOrder(self, currentTime, order):
if len(order) == 1:
type = order.type.item()
id = order.order_id.item()
direction = order.direction.item()
price = order.price.item()
vol = order.vol.item()

existing_order = self.orders.get(id)

if type == 'NEW':
self.placeLimitOrder(self.symbol, vol, direction == 'BUY', float(price), dollar=False, order_id=id)
elif type in ['CANCELLATION', 'PARTIAL_CANCELLATION']:
existing_order = self.orders.get(id)
if existing_order:
if type == 'CANCELLATION':
self.cancelOrder(existing_order)
elif type == 'PARTIAL_CANCELLATION':
new_order = LimitOrder(self.id, currentTime, self.symbol, vol, direction == 'BUY', float(price),
dollar=False, order_id=id)
self.modifyOrder(existing_order, new_order)
else:
self.replicateOrderbookSnapshot(currentTime)
elif type in ['EXECUTE_VISIBLE', 'EXECUTE_HIDDEN']:
existing_order = self.orders.get(id)
if existing_order:
if existing_order.quantity == vol:
self.cancelOrder(existing_order)
Expand All @@ -90,23 +77,14 @@ def placeOrder(self, currentTime, order):
self.cancelOrder(existing_order)
else:
executed_order = LimitOrder(self.id, currentTime, self.symbol, new_vol, direction == 'BUY', float(price),
dollar=False, order_id=id)
dollar=False, order_id=id)
self.modifyOrder(existing_order, executed_order)
self.orders.get(id).quantity = new_vol
else:
self.replicateOrderbookSnapshot(currentTime)
else:
orders = self.oracle.trades_df.loc[self.oracle.trades_df.timestamp == currentTime]
for index, order in orders.iterrows():
self.placeOrder(currentTime, order = pd.DataFrame(order).T)


def replicateOrderbookSnapshot(self, currentTime):
log_print("Received notification of orderbook snapshot replication at: {}".format(currentTime))
self.sendMessage(self.exchangeID, Message({"msg": "REPLICATE_ORDERBOOK_SNAPSHOT", "sender": self.id,
"symbol": self.symbol, "timestamp": str(currentTime)}))
if self.log_orders: self.logEvent('REPLICATE_ORDERBOOK_SNAPSHOT', currentTime)


def getWakeFrequency(self):
return self.oracle.trades_df.iloc[0].timestamp - self.mkt_open
43 changes: 43 additions & 0 deletions agent/RandomAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from agent.TradingAgent import TradingAgent
import numpy as np
import pandas as pd


class RandomAgent(TradingAgent):


def __init__(self, id, name, symbol, startingCash,
buy_price_range = [90, 105], sell_price_range = [95, 110], quantity_range = [50, 500],
random_state = None):
super().__init__(id, name, startingCash, random_state)
self.symbol = symbol
self.buy_price_range = buy_price_range
self.sell_price_range = sell_price_range
self.quantity_range = quantity_range


def kernelStarting(self, startTime):
super().kernelStarting(startTime)


def wakeup(self, currentTime):
super().wakeup(currentTime)
self.last_trade[self.symbol] = 0
if not self.mkt_open or not self.mkt_close:
return
elif (currentTime > self.mkt_open) and (currentTime < self.mkt_close):
direction = np.random.randint(0, 2)
price = np.random.randint(self.buy_price_range[0], self.buy_price_range[1]) \
if direction == 1 else np.random.randint(self.sell_price_range[0], self.sell_price_range[1])
quantity = np.random.randint(self.quantity_range[0], self.quantity_range[1])
self.placeLimitOrder(self.symbol, quantity, direction, price, dollar=False)
delta_time = self.random_state.exponential(scale=1.0 / 0.005)
self.setWakeup(currentTime + pd.Timedelta('{}ms'.format(int(round(delta_time)))))


def receiveMessage(self, currentTime, msg):
super().receiveMessage(currentTime, msg)


def getWakeFrequency(self):
return pd.Timedelta('1ms')
68 changes: 33 additions & 35 deletions config/marketreplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from agent.MarketReplayAgent import MarketReplayAgent
from agent.ExchangeAgent import ExchangeAgent
from agent.ExperimentalAgent import ExperimentalAgent
from util.oracle.OrderBookOracle import OrderBookOracle

from util import util
from util.oracle.RandomOrderBookOracle import RandomOrderBookOracle
from util.order import LimitOrder

import datetime as dt
Expand Down Expand Up @@ -61,7 +61,7 @@
print("Symbols traded: {}".format(symbols))

# 2) Historical Date to simulate
date = '2012-06-21'
date = '2019-06-19'
date_pd = pd.to_datetime(date)
print("Historical Simulation Date: {}".format(date))

Expand All @@ -70,19 +70,19 @@
# 3) ExchangeAgent Config
num_exchanges = 1
mkt_open = date_pd + pd.to_timedelta('09:30:00')
mkt_close = date_pd + pd.to_timedelta('09:30:05')
mkt_close = date_pd + pd.to_timedelta('09:35:00')
print("ExchangeAgent num_exchanges: {}".format(num_exchanges))
print("ExchangeAgent mkt_open: {}".format(mkt_open))
print("ExchangeAgent mkt_close: {}".format(mkt_close))

ea = ExchangeAgent(id = 0,
name = 'Exchange_Agent',
type = 'ExchangeAgent',
mkt_open = mkt_open,
mkt_close = mkt_close,
symbols = symbols,
log_orders=log_orders,
book_freq = '1s',
ea = ExchangeAgent(id = 0,
name = 'Exchange_Agent',
type = 'ExchangeAgent',
mkt_open = mkt_open,
mkt_close = mkt_close,
symbols = symbols,
log_orders = log_orders,
book_freq = None,
pipeline_delay = 0,
computation_delay = 0,
stream_history = 10,
Expand All @@ -91,48 +91,46 @@
agents.extend([ea])

# 4) MarketReplayAgent Config
num_mr_agents = 1
cash_mr_agents = 10000000

mr_agents = [MarketReplayAgent(id = 1,
name = "Market_Replay_Agent",
symbol = symbols[0],
date = date,
startingCash = cash_mr_agents,
random_state = random_state)]
agents.extend(mr_agents)
market_replay_agents = [MarketReplayAgent(id = 1,
name = "Market_Replay_Agent",
type = 'MarketReplayAgent',
symbol = symbols[0],
log_orders = log_orders,
date = date,
starting_cash = 0,
random_state = random_state)]
agents.extend(market_replay_agents)

# 5) ExperimentalAgent Config
num_exp_agents = 1
cash_exp_agents = 10000000

exp_agents = [ExperimentalAgent(id = 2,
experimental_agents = [ExperimentalAgent(id = 2,
name = "Experimental_Agent",
symbol = symbols[0],
startingCash = cash_exp_agents,
execution_timestamp = pd.Timestamp("2012-06-21 09:30:02"),
starting_cash = 10000000,
log_orders = log_orders,
execution_timestamp = pd.Timestamp("2019-06-19 09:32:00"),
quantity = 1000,
is_buy_order = True,
limit_price = 500,
random_state = random_state)]
agents.extend(exp_agents)
agents.extend(experimental_agents)
#######################################################################################################################

# 6) Kernel Parameters
kernel = Kernel("Market Replay Kernel", random_state = random_state)

kernelStartTime = date_pd + pd.to_timedelta('09:30:00')
kernelStopTime = date_pd + pd.to_timedelta('09:30:05')
kernelStopTime = date_pd + pd.to_timedelta('09:35:00')
defaultComputationDelay = 0
latency = np.zeros((3, 3))
noise = [ 0.0 ]

# 7) Data Oracle
oracle = OrderBookOracle(symbol='AAPL',
date='2012-06-21',
orderbook_file_path='C:/_code/py/air/abides_open_source/abides/data/lob_data/AAPL_2012-06-21_34200000_57600000_orderbook_10.csv',
message_file_path='C:/_code/py/air/abides_open_source/abides/data/lob_data/AAPL_2012-06-21_34200000_57600000_message_10.csv',
num_price_levels=10)
oracle = RandomOrderBookOracle(symbol = 'AAPL',
market_open_ts = mkt_open,
market_close_ts = mkt_close,
buy_price_range = [90, 105],
sell_price_range = [95, 110],
quantity_range = [50, 500],
seed=seed)

kernel.runner(agents = agents, startTime = kernelStartTime,
stopTime = kernelStopTime, agentLatency = latency,
Expand Down
Loading

0 comments on commit 7079c23

Please sign in to comment.