Here I will build the environment where my agent will be trained. As it is a pretty complicated task, I created this notebook just to explore some options. Test an automated strategy is something pretty difficult, to tell the truth. There are some issues that I could talk about: historical prices are just one path from a stochastic process, the presence of the strategy on the market could change it etc.
However, would be interesting if the solution explored in my capstone could capture some aspect of the real structure of the markets. So, I will build an environment that will use historical data, but I will build it in a "agent-based model" fashion. Probably I will not do that to this project, but this structure can be useful for some future projects that I intend to do after completing this one.
I will use TAQ data from Bloomberg; It consists of 'level I' data from the PETR4 Brazilian Stock. I will explain about all these terms and data in my "official" project; here I just intend to share my experiments in a less formal way. Level I data is the information of the first queue of order book (bid and ask), and trades that have been made (TAQ is an acronym for Trade and Quote). It alone is not enough to create an order book, but I will try to do that. If I complete this task, I could exclude the historical data and include some random agents to build a Monte Carlo of the order book, for example. I will try to build it upon the codes for the SmartCab project. Instead of the gridlike world, my world will be discrete, but an order book.
So, let's start looking at the data that I have available. It is data from the last 19 days from PETR4 stock from Brazilian BMFBovespa. I choose this share because it is on of the most active stocks in our market, but still the data produced is manageable (60 to 90 thousands of rows by day).
import zipfile
s_fname = "data/petr4_0725_0818.zip"
archive = zipfile.ZipFile(s_fname, 'r')
def foo():
f_total = 0.
f_tot_rows = 0.
for i, x in enumerate(archive.infolist()):
f_total += x.file_size/ 1024.**2
for num_rows, row in enumerate(archive.open(x)):
f_tot_rows += 1
print "{}:\t{:,.0f} rows\t{:0.2f} MB".format(x.filename, num_rows + 1, x.file_size/ 1024.**2)
print '=' * 42
print "TOTAL\t\t{} files\t{:0.2f} MB".format(i+1,f_total)
print "\t\t{:0,.0f} rows".format(f_tot_rows)
%time foo()
20160725.csv: 117,170 rows 4.66 MB 20160726.csv: 105,898 rows 4.20 MB 20160727.csv: 131,058 rows 5.22 MB 20160728.csv: 117,286 rows 4.65 MB 20160729.csv: 145,368 rows 5.79 MB 20160801.csv: 114,815 rows 4.57 MB 20160802.csv: 113,642 rows 4.51 MB 20160803.csv: 142,283 rows 5.69 MB 20160804.csv: 144,832 rows 5.78 MB 20160805.csv: 117,901 rows 4.70 MB 20160808.csv: 93,502 rows 3.70 MB 20160809.csv: 86,078 rows 3.41 MB 20160810.csv: 112,320 rows 4.46 MB 20160811.csv: 153,925 rows 6.16 MB 20160812.csv: 154,212 rows 6.17 MB 20160815.csv: 114,955 rows 4.57 MB 20160816.csv: 111,913 rows 4.45 MB 20160817.csv: 122,047 rows 4.86 MB 20160818.csv: 90,024 rows 3.56 MB ========================================== TOTAL 19 files 91.09 MB 2,289,229 rows Wall time: 4.54 s
Ok, all files together have 91 MB. It is not too much actually. Maybe I could try to get more data later. Well, let's read one of them.
import pandas as pd
df = pd.read_csv(archive.open(x), index_col=0, parse_dates=['Date'])
df.head()
Date | Type | Price | Size | |
---|---|---|---|---|
0 | 2016-08-18 10:09:09 | TRADE | 12.80 | 1000 |
1 | 2016-08-18 10:09:09 | BID | 12.80 | 15900 |
2 | 2016-08-18 10:09:09 | ASK | 12.81 | 2900 |
3 | 2016-08-18 10:09:09 | ASK | 12.81 | 7900 |
4 | 2016-08-18 10:09:09 | BID | 12.80 | 20900 |
print "{:%m/%d/%Y}".format(df.Date[0])
print df.groupby('Type').count()['Date']
08/18/2016 Type ASK 32843 BID 32116 TRADE 25064 Name: Date, dtype: int64
As it is a "Trade And quotes" file, I was already expecting that there was the same number os Bid and Ask rows in the file. Well... it wasn't a problem to read this file. Well, I will read this file row by row now and include the prices in a binomial tree (the structure I intend to use to keep the order book). Let's see how long it takes.
from bintrees import FastRBTree
def foo():
for idx, row in df.iterrows():
pass
print "time to iterate the rows:"
%time foo()
time to iterate the rows: CPU times: user 9.15 s, sys: 114 ms, total: 9.27 s Wall time: 9.22 s
def foo():
bid_tree = FastRBTree()
ask_tree = FastRBTree()
for idx, row in df.iterrows():
if row.Type == 'BID':
bid_tree.insert(row['Price'], row['Size'])
elif row.Type == 'ASK':
ask_tree.insert(row['Price'], row['Size'])
print "time to insert everything in binary trees:"
%time foo()
time to insert everything in binary trees: CPU times: user 15.6 s, sys: 317 ms, total: 15.9 s Wall time: 15.8 s
It is not excelent, but it is ok for now. I will see how bad it will be when I include all the logic needed. Now, let's visualize the prices on that day
df_aux = df[df.Type == 'TRADE'].Price
df_aux.index = df[df.Type == 'TRADE'].Date
ax = df_aux.plot()
ax.set_title("Price fluctuation of PETR4\n");
Know what, let's visualize the prices of all days. I will plot the cumulated returns of this series
import pandas as pd
df_all = None
for i, x in enumerate(archive.infolist()):
df = pd.read_csv(archive.open(x), index_col=0, parse_dates=['Date'])
ts_date = df.Date[0].date()
df.Date = ["{:%H:%M:%S}".format(x) for x in df.Date]
df = df[df.Type == "TRADE"]
df = pd.DataFrame(df.groupby('Date').last()['Price'])
if i == 0:
df_all = df.copy()
df_all.columns = [ts_date]
else:
df_aux = df.copy()
df_aux.columns = [ts_date]
df_all = df_all.join(df_aux)
df_all.index = pd.to_datetime(df_all.index)
df_all = df_all.fillna(method='ffill')
df_all = df_all.dropna()
import numpy as np
df_logrtn = np.log(df_all/df_all.shift())
df_logrtn = df_logrtn[[(x.hour*60 + x.minute) < (16*60 + 55) for x in df_logrtn.index]]
ax = df_logrtn.cumsum().plot(legend=False)
ax.set_title('Cumulative Log-Returns of PETR4 in 19 different days\n', fontsize=16)
ax.set_ylabel('Return');
Interesting, isn't it?! It looks like the output of a Monte Carlo simulation. Well, the simulator that I will build should produce exactly this output.
There is a problem using this data to do a simulation: the order of events. As there is just the first line of the order book, when happened a trade that filled more than an price level at once, I won't have the order in the second price level in my structure to be filled. So, I need to create it beforehand. To do so, I need to preprocess the dataset, so I can include this event. What I will do is sum up the trades that happend in sequence and include a new rows between the sequences to preper the dataset.
import qtrader.preprocess as preprocess
s_fname = "data/petr4_0725_0818.zip"
preprocess.make_zip_file(s_fname)
run in 46.55 seconds
Now, let's check if I keep the same traded quantity in all files
import zipfile
import pandas as pd
s_fname = "data/petr4_0725_0818.zip"
archive = zipfile.ZipFile(s_fname, 'r')
f_total = 0.
i_same = 0
i_different = 0
for i, x in enumerate(archive.infolist()):
s_fname = 'data/petr4_0725_0818_2/' + x.filename
df = pd.read_csv(archive.open(x), index_col=0, parse_dates=['Date'])
df2 = pd.read_csv(s_fname, index_col=0, parse_dates=['Date'])
f_all = (df.ix[df.Type=='TRADE', 'Price'] * df.ix[df.Type=='TRADE', 'Size']).sum()
f_all2 = (df2.ix[df2.Type=='TRADE', 'Price'] * df2.ix[df2.Type=='TRADE', 'Size']).sum()
if f_all == f_all2:
i_same += 1
else:
i_different += 1
print "{} files has the same number of trades".format(i_same)
print "{} files has DIFFERENT number of trades".format(i_different)
19 files has the same number of trades 0 files has DIFFERENT number of trades
Nice. I am going to use this files in the next steps.
I imagine a structure where my environment is an order book that operates in discrete time steps. At each time step, it allows randomly the agents (at each step) to take new actions. Then, the Environment updates the order book according to these messages.
At the beginning of each time step, all agent see the same state of the order book. Some of them will try to execute orders at the same price, for example, and the environment will accept just this kind of message while there are orders to be filled at that particular price. After that, It should distribute all the new states to the agents.
It also should keep the prices organized and, inside each price, should follow the orders arranged by "arrival time". Always that an agent grow his quantity of an existing order, it should be moved to the end of the queue on that price. The message that the agent should send to the environment should be something like that
{'instrumento_symbol': 'PETR4',
'agent_id': 10,
'order_entry_step': 15,
'order_status': 'New'
'last_order_id': 11,
'order_id': 11,
'order_side': 'BID',
'agressor_indicator': 'Neutral',
'order_price': 12.11,
'total_qty_order': 100,
'traded_qty_order': 0}
The limit order book will be ordered first by price and then by arrival. So, my first class should be the order itself. The second class should be the price level (that is a group of orders). The third one, the side of the book (a collection of Price Levels). Finally, the order book (the bid and ask side). So, now I need to create all the structure that handle these interations. If should receive an order and answer to the environment if it was acepted , the new ID, and, if there was a trade, the informations about the trade so the environment can update the state of the agents. I need a list of prices and another of orders. Oh... and a list of agents that have a list of their current orders on the market, but it is something handle by the environment. So, let's do that. First, let's implement the order structure.
# example of message
d_msg = {'instrumento_symbol': 'PETR4',
'agent_id': 10,
'order_entry_step': 15,
'order_status': 'New',
'last_order_id': 0,
'order_id': 0,
'order_side': 'BID',
'order_price': 12.11,
'total_qty_order': 100,
'traded_qty_order': 0}
class Order(object):
'''
A representation of a single Order
'''
def __init__(self, d_msg):
'''
Instantiate a Order object. Save all parameter as attributes
:param d_msg: dictionary.
'''
# keep data extract from file
self.d_msg = d_msg.copy()
self.d_msg['org_total_qty_order'] = self.d_msg['total_qty_order']
f_q1 = self.d_msg['total_qty_order']
f_q2 = self.d_msg['traded_qty_order']
self.d_msg['total_qty_order'] = f_q1 - f_q2
self.order_id = d_msg['order_id']
self.last_order_id = d_msg['last_order_id']
self.name = "{:07d}".format(d_msg['order_id'])
self.main_id = self.order_id
def __str__(self):
'''
Return the name of the Order
'''
return self.name
def __repr__(self):
'''
Return the name of the Order
'''
return self.name
def __eq__(self, other):
'''
Return if a Order has equal order_id from the other
:param other: Order object. Order to be compared
'''
return self.order_id == other.order_id
def __ne__(self, other):
'''
Return if a Order has different order_id from the other
:param other: Order object. Order to be compared
'''
return not self.__eq__(other)
def __hash__(self):
'''
Allow the Order object be used as a key in a hash table. It is used by
dictionaries
'''
return self.order_id.__hash__()
def __getitem__(self, s_key):
'''
Allow direct access to the inner dictionary of the object
:param i_index: integer. index of the l_legs attribute list
'''
return self.d_msg[s_key]
my_order = Order(d_msg)
print "My id is {} and the price is {:0.2f}".format(my_order['order_id'], my_order['order_price'])
print "The string representation of the order is {}".format(my_order)
My id is 0 and the price is 12.11 The string representation of the order is 0000000
If the ID is zero, I will consider as the new order. Well... now I need to organize orders at the same price by arrival time and update its IDs. Also, if an existing order increases the quantity, should have been marked with a new ID. If the quantity decreases, it should keep the same place on the queue. So, the price level need to know what is the last general ID used by the Order Book:
from bintrees import FastRBTree
class PriceLevel(object):
'''
A representation of a Price level in the book
'''
def __init__(self, f_price):
'''
A representation of a PriceLevel object
'''
self.f_price = f_price
self.i_qty = 0
self.order_tree = FastRBTree()
def add(self, order_aux):
'''
Insert the information in the tree using the info in order_aux. Return
is should delete the Price level or not
:param order_aux: Order Object. The Order message to be updated
'''
# check if the order_aux price is the same of the self
if order_aux['order_price'] != self.f_price:
raise DifferentPriceException
elif order_aux['order_status'] == 'limit':
self.order_tree.insert(order_aux.main_id, order_aux)
self.i_qty += int(order_aux['total_qty_order'])
# check if there is no object in the updated tree (should be deleted)
return self.order_tree.count == 0
def delete(self, i_last_id, i_old_qty):
'''
Delete the information in the tree using the info in order_aux. Return
is should delete the Price level or not
:param i_last_id: Integer. The previous secondary order id
:param i_old_qty: Integer. The previous order qty
'''
# check if the order_aux price is the same of the self
try:
self.order_tree.remove(i_last_id)
self.i_qty -= i_old_qty
except KeyError:
raise DifferentPriceException
# check if there is no object in the updated tree (should be deleted)
return self.order_tree.count == 0
def __str__(self):
'''
Return the name of the PriceLevel
'''
return '{:,.0f}'.format(self.i_qty)
def __repr__(self):
'''
Return the name of the PriceLevel
'''
return '{:,.0f}'.format(self.i_qty)
def __eq__(self, other):
'''
Return if a PriceLevel has equal price from the other
:param other: PriceLevel object. PriceLevel to be compared
'''
# just to make sure that there is no floating point discrepance
f_aux = other
if not isinstance(other, float):
f_aux = other.f_price
return abs(self.f_price - f_aux) < 1e-4
def __gt__(self, other):
'''
Return if a PriceLevel has a gerater price from the other.
Bintrees uses that to compare nodes
:param other: PriceLevel object. PriceLevel to be compared
'''
# just to make sure that there is no floating point discrepance
f_aux = other
if not isinstance(other, float):
f_aux = other.f_price
return (f_aux - self.f_price) > 1e-4
def __lt__(self, other):
'''
Return if a Order has smaller order_id from the other. Bintrees uses
that to compare nodes
:param other: Order object. Order to be compared
'''
f_aux = other
if not isinstance(other, float):
f_aux = other.f_price
return (f_aux - self.f_price) < -1e-4
def __ne__(self, other):
'''
Return if a Order has different order_id from the other
:param other: Order object. Order to be compared
'''
return not self.__eq__(other)
my_order = Order(d_msg)
# create different orders at the same price
d_msg1 = d_msg.copy()
d_msg1['order_id'] = 1
order1 = Order(d_msg1)
d_msg2 = d_msg.copy()
d_msg2['order_id'] = 2
order2 = Order(d_msg2)
d_msg3 = d_msg.copy()
d_msg3['order_id'] = 3
order3 = Order(d_msg3)
my_price = PriceLevel(d_msg['order_price'])
my_price.add(order1)
my_price.add(order2)
my_price.add(order3)
False
print "There is {} shares at {:.2f}".format(my_price, my_price.f_price)
print 'the orders in the book are: {}'.format(dict(my_price.order_tree))
There is 300 shares at 12.11 the orders in the book are: {1: 0000001, 2: 0000002, 3: 0000003}
Ok. Now, let's delete two of them
my_price.delete(1, 100)
my_price.delete(2, 100)
print "There is {} shares at {:.2f}".format(my_price, my_price.f_price)
print 'the orders in the book are: {}'.format(dict(my_price.order_tree))
There is 100 shares at 12.11 the orders in the book are: {3: 0000003}
I will let to the Environment handle the IDs, so the order book just need to keep the data ordered. Now, I am going to implement the Book side (a collection of Price levels) and the Limit Order Book (a collection of BookSide). You can see the final implementation on the file book.py
.
import qtrader.book as book; reload(book);
my_book = book.LimitOrderBook('PETR4')
d_msg0 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 0,
'order_price': 12.12,
'order_side': 'ASK',
'order_status': 'New',
'total_qty_order': 400,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg1 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 1,
'order_price': 12.11,
'order_side': 'BID',
'order_status': 'New',
'total_qty_order': 100,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg2 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 2,
'order_price': 12.11,
'order_side': 'BID',
'order_status': 'New',
'total_qty_order': 100,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg3 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 3,
'order_price': 12.10,
'order_side': 'BID',
'order_status': 'New',
'total_qty_order': 200,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg4 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 4,
'order_price': 12.10,
'order_side': 'BID',
'order_status': 'New',
'total_qty_order': 100,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg5 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 3,
'order_price': 12.10,
'order_side': 'BID',
'order_status': 'Replaced',
'total_qty_order': 100,
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
d_msg6 = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'last_order_id': 0,
'order_entry_step': 15,
'order_id': 1,
'order_price': 12.11,
'order_side': 'BID',
'order_status': 'Filled',
'total_qty_order': 100,
'traded_qty_order': 0,
'agressor_indicator': 'Passive'}
# include several orders
my_book.update(d_msg0)
my_book.update(d_msg1)
my_book.update(d_msg2)
my_book.update(d_msg3)
my_book.update(d_msg4)
my_book.get_n_top_prices(5)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 200 | 12.11 | 12.12 | 400 |
1 | 300 | 12.10 | NaN | NaN |
# test cancelation
my_book.update(d_msg5)
my_book.get_n_top_prices(5)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 200 | 12.11 | 12.12 | 400 |
1 | 200 | 12.10 | NaN | NaN |
# checking if the order of Ids are OK
x = my_book.book_bid.price_tree.get(12.10)
x.order_tree
FastRBTree({3: 0000003, 4: 0000004})
# test a trade
my_book.update(d_msg6)
my_book.get_n_top_prices(5)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 100 | 12.11 | 12.12 | 400 |
1 | 200 | 12.10 | NaN | NaN |
my_book.get_basic_stats()
{'n_order_ask': 1, 'n_order_bid': 3, 'n_price_ask': 1, 'n_price_bid': 2}
Ok, everything looks right. Let's play with some real data now.
I want to build a structure that I could simulate with any kind of data: real data, "semi-real" data and artificial data. Using artificial data, I could allow the agent change the environment. The other two option, I would just replay the market. The first one, I would need "level II" data, that is not easily acquired, and it is harder to handle. The second one, I would use just "level I" data, which some vendors provide, like Bloomberg. However, there are just the grouped data of the best- bid and offer.
For now, what I need is a framework to interact with the book and a planner (maybe). This planner won't do anything if we are using the artificial market, just return the actions of each agent. If it is historical data, It should take the data and translate to the Environment as actions of each agent. So, my environment could update the order book using just the messages dicionaries and update each agent if that message was acepted or not. I guess that the role of the Environment should be update each agent with informations that them could use to build their states and rewards. The planner should handle the "macro-behaviour" of each agent (like, know something about the true price, etc).
So, let's come back to the data that was explored at the begining of this notebook. the first thing that I should do is to do a basic reshape on the data to make it work with my book.
import zipfile
s_fname = "data/petr4_0725_0818.zip"
archive = zipfile.ZipFile(s_fname, 'r')
f_total = 0.
for i, x in enumerate(archive.infolist()):
f_total += x.file_size/ 1024.**2
for num_rows, row in enumerate(archive.open(x)):
pass
import pandas as pd
df = pd.read_csv(archive.open(x), index_col=0, parse_dates=['Date'])
df.head(5)
Date | Type | Price | Size | |
---|---|---|---|---|
0 | 2016-08-18 10:09:09 | TRADE | 12.80 | 1000 |
1 | 2016-08-18 10:09:09 | BID | 12.80 | 15900 |
2 | 2016-08-18 10:09:09 | ASK | 12.81 | 2900 |
3 | 2016-08-18 10:09:09 | ASK | 12.81 | 7900 |
4 | 2016-08-18 10:09:09 | BID | 12.80 | 20900 |
Something that I need to take into account is that the book didn't start before the first BID or ASK, that both are related to the aggregated best bid and ask, and TRADE can be an aggression on either side. As I want to make a book with multiple queues, I will keep the orders on the book and just modify it when the price returns to that level. So, before decrease the BID or increase the ASK, I should check if I have an order for that price and modify it before cancel the better price. Also, I know that the TRADE flag can be a cross order, something that I don't want to account for. I also want to keep track of the changes on the best queue of the order book and the trades separated.
def translate_row(idx, row, i_order_id):
'''
'''
if row.Type != 'TRADE' and row['Size'] > 100:
d_rtn = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'new_order_id': i_order_id + 1,
'order_entry_step': idx,
'order_id': i_order_id + 1,
'order_price': row['Price'],
'order_side': row.Type,
'order_status': 'New',
'total_qty_order': row['Size'],
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
return i_order_id + 1, d_rtn
# test the structure
import qtrader.book as book; reload(book);
my_book = book.LimitOrderBook('PETR4')
for idx, row in df.iterrows():
i_id = my_book.i_last_order_id
t_rtn = translate_row(idx, row, i_id)
if t_rtn:
my_book.i_last_order_id = t_rtn[0]
my_book.update(t_rtn[1])
if idx == 1000:
break
my_book.get_n_top_prices(5)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 1,200 | 12.88 | 12.80 | 2,000 |
1 | 2,625,400 | 12.87 | 12.81 | 144,800 |
2 | 1,712,600 | 12.86 | 12.82 | 281,100 |
3 | 1,957,300 | 12.85 | 12.83 | 1,169,900 |
4 | 94,600 | 12.84 | 12.84 | 396,200 |
my_book.get_basic_stats()
{'n_order_ask': 295, 'n_order_bid': 290, 'n_price_ask': 10, 'n_price_bid': 10}
Well... I would say that I need to handle better this orders. I need to cancel them to the bid and don't cross each other. So... Also, note the quantity on each price. It is not feasable. I need that the function knows the book. Let's see.
def translate_row(idx, row, my_book):
'''
'''
l_msg = []
if row.Type != 'TRADE' and row['Size'] % 100 == 0:
# recover the best price
f_best_price = my_book.get_best_price(row.Type)
i_order_id = my_book.i_last_order_id + 1
# check if there is orders in the row price
obj_ordtree = my_book.get_orders_by_price(row.Type, row['Price'])
if obj_ordtree:
# cant present more than 2 orders (mine and market)
assert len(obj_ordtree) <= 2, 'More than two offers'
# get the first order
obj_order = obj_ordtree.nsmallest(1)[0][1]
# check if should cancel the best price
b_cancel = False
if row.Type == 'BID' and row['Price'] < f_best_price:
# check if the price in the row in smaller
obj_ordtree2 = my_book.get_orders_by_price(row.Type)
best_order = obj_ordtree2.nsmallest(1)[0][1]
d_rtn = best_order.d_msg
d_rtn['order_status'] = 'Canceled'
l_msg.append(d_rtn.copy())
elif row.Type == 'ASK' and row['Price'] > f_best_price:
obj_ordtree2 = my_book.get_orders_by_price(row.Type)
best_order = obj_ordtree2.nsmallest(1)[0][1]
d_rtn = best_order.d_msg
d_rtn['order_status'] = 'Canceled'
l_msg.append(d_rtn.copy())
# replace the current order
i_old_id = obj_order.main_id
i_new_id = obj_order.main_id
if row['Size'] > obj_order['total_qty_order']:
i_new_id = my_book.i_last_order_id + 1
d_rtn = obj_order.d_msg
d_rtn['order_status'] = 'Canceled'
l_msg.append(d_rtn.copy())
# Replace the order
d_rtn = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'order_id': i_old_id,
'order_entry_step': idx,
'new_order_id': i_new_id,
'order_price': row['Price'],
'order_side': row.Type,
'order_status': 'Replaced',
'total_qty_order': row['Size'],
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
l_msg.append(d_rtn.copy())
else:
# if the price is not still in the book, include a new order
d_rtn = {'agent_id': 10,
'instrumento_symbol': 'PETR4',
'order_id': my_book.i_last_order_id + 1,
'order_entry_step': idx,
'new_order_id': my_book.i_last_order_id + 1,
'order_price': row['Price'],
'order_side': row.Type,
'order_status': 'New',
'total_qty_order': row['Size'],
'traded_qty_order': 0,
'agressor_indicator': 'Neutral'}
l_msg.append(d_rtn)
return l_msg
# test the structure
import qtrader.book as book; reload(book);
import pprint
import time
f_start = time.time()
my_book = book.LimitOrderBook('PETR4')
self = my_book
for idx, row in df.iterrows():
l_msg = translate_row(idx, row, my_book)
if l_msg:
for msg in l_msg:
my_book.update(msg)
# if idx == 10000:
# break
"It took {:0.2f} seconds to process {:0,.0f} rows".format(time.time() - f_start, idx + 1)
'It took 27.90 seconds to process 90,023 rows'
my_book.get_basic_stats()
{'n_order_ask': 8, 'n_order_bid': 18, 'n_price_ask': 8, 'n_price_bid': 18}
my_book.get_n_top_prices(100)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 50,600 | 12.95 | 12.96 | 130,000 |
1 | 159,200 | 12.94 | 12.97 | 62,400 |
2 | 8,700 | 12.93 | 12.98 | 34,600 |
3 | 74,000 | 12.92 | 12.99 | 28,100 |
4 | 9,700 | 12.91 | 13.00 | 65,900 |
5 | 13,900 | 12.90 | 13.01 | 31,900 |
6 | 45,400 | 12.89 | 13.02 | 10,300 |
7 | 69,900 | 12.88 | 13.03 | 119,300 |
8 | 123,000 | 12.87 | NaN | NaN |
9 | 21,900 | 12.86 | NaN | NaN |
10 | 33,000 | 12.85 | NaN | NaN |
11 | 161,100 | 12.84 | NaN | NaN |
12 | 53,800 | 12.83 | NaN | NaN |
13 | 58,400 | 12.82 | NaN | NaN |
14 | 12,700 | 12.81 | NaN | NaN |
15 | 40,200 | 12.80 | NaN | NaN |
16 | 44,900 | 12.79 | NaN | NaN |
17 | 64,500 | 12.78 | NaN | NaN |
It is looking right, but I still need to treat Trades. Let's do it. As I know that some trades are cross orders (it is not passing through the book), I will pre-process the data to exclude them, so my simulator will just handle data that relevant.
df.head()
Date | Type | Price | Size | |
---|---|---|---|---|
0 | 2016-08-18 10:09:09 | TRADE | 12.80 | 1000 |
1 | 2016-08-18 10:09:09 | BID | 12.80 | 15900 |
2 | 2016-08-18 10:09:09 | ASK | 12.81 | 2900 |
3 | 2016-08-18 10:09:09 | ASK | 12.81 | 7900 |
4 | 2016-08-18 10:09:09 | BID | 12.80 | 20900 |
def foo():
best_bid = None
best_ask = None
i_num_cross = 0
l_cross = []
for idx, row in df.iterrows():
if row.Size % 100 == 0:
if row.Type == 'BID':
best_bid = row.copy()
elif row.Type == 'ASK':
best_ask = row.copy()
else:
if not isinstance(best_bid, type(None)):
if row.Price == best_bid.Price:
if row.Size > best_bid.Size:
# print 'cross-bid', idx
i_num_cross += 1
l_cross.append(idx)
if not isinstance(best_ask, type(None)):
if row.Price == best_ask.Price:
if row.Size > best_ask.Size:
# print 'cross-ask', idx
i_num_cross += 1
l_cross.append(idx)
print "number of cross-orders: {:.0f}".format(i_num_cross)
return l_cross
%time l_cross = foo()
number of cross-orders: 26 CPU times: user 21.5 s, sys: 706 ms, total: 22.2 s Wall time: 21.7 s
I guess that I will not need to treat that. Just need to ignores trades that there are not enough in the book to filled them. Let´s first start by building an object to read the data files so I don't need to load all the data to a dataframe before translating the rows to the order book.
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.book as book; reload(book);
import time
s_fname = "data/petr4_0725_0818.zip"
my_test = matching_engine.BloombergMatching(None, "PETR4", 200, s_fname)
f_start = time.time()
for i in xrange(my_test.max_nfiles):
for d_data in my_test:
pass
print "Time to iterate the files: {:0.2f}".format(time.time() - f_start)
Time to iterate the files: 32.37
Hm... I was reading all the files in 6 seconds before.... It looks bad, isn't it? Let's translate the messages and update the books using the last function implemented and process the trades.
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.book as book; reload(book);
import time
s_fname = "data/petr4_0725_0818_2.zip"
my_test = matching_engine.BloombergMatching(None, "PETR4", 200, s_fname)
f_start = time.time()
for i in xrange(my_test.max_nfiles):
quit = False
while True:
try:
l_msg = my_test.next()
except StopIteration:
quit = True
finally:
if quit:
break
# break
print "Time to iterate the files: {:0.2f}".format(time.time() - f_start)
Time to iterate the files: 249.52
... Yeh... There is some changes to do before conclude it. I need to make the translator handle multiple orders. It is handling multiple messages just in Trades, not when there are limit orders. I am not sure if I will use multiple agents by price, but I need to handle more than one agent anyway because the agent that I intend to create. But know what, before implement it, I guess that it is better to introduce the last peace of this study: the environment
my_test.my_book.get_n_top_prices(5)
qBid | Bid | Ask | qAsk | |
---|---|---|---|---|
0 | 2,000 | 12.01 | 12.03 | 36,000 |
1 | 800 | 12.00 | 12.04 | 71,600 |
2 | 37,900 | 11.99 | 12.05 | 20,400 |
3 | 97,000 | 11.98 | 12.06 | 23,100 |
4 | 45,100 | 11.97 | 12.07 | 27,900 |
My environment should know what is the best bid and best price at each iteration, and keep a list of the trades that have happened. Each agent could have multiple orders at each time. However, I will allow the most of them to handle a single order at each time to simplify my problem. Each agent should receive some variables that it could use to compose its inner-state at each time step. Also, should be given the reward if it is the case. As I probably should test what kind of reward it receives, maybe the environment should pass just a dictionary of variables, and the agent decides what it will use as state and what it will use as the reward... and what it will not use at all.
As I stated before, my order matching still has a important limitation. It assumes that all price levels have just a single order, and it will not be the case, as my agent will interact with the environment. I could even include more orders at each price level... but I guess that I will keep it "simple" (it is not simple, already).
Something that I will have to take care is that, as I dealing with historical data (and I wnat to keep it in that way), I will need to make my translator to modify the order book to acomodate the order of my agent. My agent will always use the minimum quantity possible, so I need to discount it when my agent include an order in any price (and decrease it when the agent cancel that order). I also will have an agent that will have all order of the market (and that will perform the trades). So, let's start by just instantiating an environment and set the initial agents to a simulation
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import pprint
e = environment.Environment()
a = e.create_agent(environment.Agent)
e.set_primary_agent(a)
pprint.pprint(dict(e.agent_states))
{11: {'Ask': 0.0, 'Bid': 0.0, 'Position': 0, 'qAsk': 0, 'qBid': 0}, 10: {'Ask': 0.0, 'Bid': 0.0, 'Position': 0, 'qAsk': 0, 'qBid': 0}}
Ok, now let's try to simulate the order book, as before
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import pprint
import time
s_fname = "data/petr4_0725_0818_2.zip"
my_env = environment.Environment()
f_start = time.time()
for i in xrange(my_env.order_matching.max_nfiles):
quit = False
my_env.reset()
while True:
try:
l_msg = my_env.step()
except StopIteration:
quit = True
finally:
if quit:
break
print "Time to iterate the files: {:0.2f}".format(time.time() - f_start)
More than 5 minutes to read all files. Well, if you think, there are more than 2 million rows in total. It implies that there are more than 2 million times that my agent will receive something from the environment. So, maybe it is not so bad. Maybe I should even restrict the number of steps inside a particular file, so I could use the remain data to perform a back test. By the way, it is not a problem that I intend to address here. For now, my goal is just building the world where I can include agents to interact. It is already pretty complicated so far. Let's keep moving. Now, I will make the agent to sense the world and receive a reward by their actions. One of the measued that I want to include is the order flow imbalance that I will explain better in the main notebook. For now, the form of the measure is:
$$e_n = \mathbb{1}_{P_{n}^{B} \geq P_{n-1}^{B}} q^{B}_{n} - \mathbb{1}_{P_{n}^{B} \leq P_{n-1}^{B}} q^{B}_{n-1} + \mathbb{1}_{P_{n}^{A} \leq P_{n-1}^{A}} q^{A}_{n} + \mathbb{1}_{P_{n}^{A} \geq P_{n-1}^{A}} q^{A}_{n-1}$$Where $A$ in related to the ask side, $B$ to the Bid side, $n$ to the current observation and $n-1$ to the last one. $\mathbb{1}$ is an Indicator function and $P$ is the price and $q$, the quantity. I will also hold the value of this variables in chunck of 10 seconds. So, let's see
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import pprint
import time
s_fname = "data/petr4_0725_0818_2.zip"
my_env = environment.Environment()
f_start = time.time()
for i in xrange(my_env.order_matching.max_nfiles):
quit = False
my_env.reset()
while True:
try:
# if my_env.order_matching.idx == 6:
# if my_env.order_matching.i_nrow == 107410:
# raise NotImplementedError
if my_env.order_matching.i_nrow > 9:
break
l_msg = my_env.step()
except StopIteration:
quit = True
finally:
if quit:
break
break
print "Time to iterate the files: {:0.2f}".format(time.time() - f_start)
Environment.reset(): Trial set up to use 20160725.csv file ZombieAgent.update(): position = 0, inputs = {'qAsk': 0, 'spread': 0, 'qAggr': 0, 'qTraded': 0, 'midPrice': 0.0, 'deltaMid': 0.0, 'qOfi': 0, 'qBid': 0}, action = BEST_BID, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 51800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56900, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56900, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 57000, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 57000, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 1400.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 6400.0, 'qBid': 11100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 6400.0, 'qBid': 11100}, action = BEST_BID, reward = 0.0 ZombieAgent.update(): position = -1000.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = SELL, reward = 0.0 ZombieAgent.update(): position = 0.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = BUY, reward = 0.0 ZombieAgent.update(): position = 0.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = BEST_OFFER, reward = 0.0 Time to iterate the files: 0.01
Now, I need to calculate the reward. Both the inputs from environment and the reward is something that I will need to explore in the main notebook. For now, the reward will be just the PnL from the last step to this step. Porblably I will penalize the agent to keep orders in the order book later. Just to make it "pays the risk". For now, let's see:
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import pprint
import time
s_fname = "data/petr4_0725_0818_2.zip"
my_env = environment.Environment()
f_start = time.time()
for i in xrange(my_env.order_matching.max_nfiles):
quit = False
my_env.reset()
while True:
try:
# if my_env.order_matching.idx == 6:
# if my_env.order_matching.i_nrow == 107410:
# raise NotImplementedError
if my_env.order_matching.i_nrow > 9:
break
l_msg = my_env.step()
except StopIteration:
quit = True
finally:
if quit:
break
break
print "Time to iterate the files: {:0.2f}".format(time.time() - f_start)
Environment.reset(): Trial set up to use 20160725.csv file ZombieAgent.update(): position = 0, inputs = {'qAsk': 0, 'spread': 0, 'qAggr': 0, 'qTraded': 0, 'midPrice': 0.0, 'deltaMid': 0.0, 'qOfi': 0, 'qBid': 0}, action = BEST_BID, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 51800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56800, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56900, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 56900, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 57000, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 57000, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 0.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 1400.0, 'qBid': 6100}, action = BEST_OFFER, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 6400.0, 'qBid': 11100}, action = None, reward = 0.0 ZombieAgent.update(): position = 0, inputs = {'qAsk': 55600, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 6400.0, 'qBid': 11100}, action = BEST_BID, reward = 0.0 ZombieAgent.update(): position = -1000.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = SELL, reward = -4.19 ZombieAgent.update(): position = 0.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = BUY, reward = -4.19 ZombieAgent.update(): position = 0.0, inputs = {'qAsk': 54600, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': 11.98, 'deltaMid': 0.0, 'qOfi': 7400.0, 'qBid': 11100}, action = BEST_OFFER, reward = 0.0 Time to iterate the files: 0.01
It is pretty bad. It between 8 to 12 minutes to run, depending on the machine used. Well, I will try to optimize it later. Now, it is time to make the part that I was avoiding at all costs =). I need to allow a random agent interact with this world and receives whatever need to receive. I will need to improve my translator for doing that (at this point, my agent can not change too much what have happened). Also, I will not print out the updates in Zombie agent, but just in my learning agent, that will happen to be updated just once per second (from the simulation, not from real time). First, let's allow the environment to deal with multiple orders by price and trades when the prices cross each other.
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import qtrader.agent as agent; reload(agent);
import qtrader.simulator as simulator; reload(simulator);
e = environment.Environment()
a = e.create_agent(agent.BasicAgent)
e.set_primary_agent(a)
sim = simulator.Simulator(e)
%time sim.run(n_trials=20)
Simulator.run(): Trial 1 Environment.reset(): Trial set up to use 20160725.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 2 Environment.reset(): Trial set up to use 20160726.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 3 Environment.reset(): Trial set up to use 20160727.csv file id: 118756, date: 2016-07-27 16:18:07 qBid Bid Ask qAsk 0 100 11.65 11.65 9,000 1 77,200 11.64 11.66 78,300 2 8,000 11.63 11.67 29,500 3 72,300 11.62 11.68 38,700 4 79,300 11.61 11.69 94,100 corrected qBid Bid Ask qAsk 0 77,200 11.64 11.65 8,900 1 8,000 11.63 11.66 78,300 2 72,300 11.62 11.67 29,500 3 79,300 11.61 11.68 38,700 4 90,600 11.60 11.69 94,100 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 4 Environment.reset(): Trial set up to use 20160728.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 5 Environment.reset(): Trial set up to use 20160729.csv file id: 108555, date: 2016-07-29 14:58:07 qBid Bid Ask qAsk 0 200 11.92 11.92 22,500 1 11,700 11.91 11.93 107,900 2 83,000 11.90 11.94 103,600 3 51,200 11.89 11.95 100,700 4 81,100 11.88 NaN NaN corrected qBid Bid Ask qAsk 0 11,700 11.91 11.92 22,300 1 83,000 11.90 11.93 107,900 2 51,200 11.89 11.94 103,600 3 81,100 11.88 11.95 100,700 4 54,100 11.87 NaN NaN Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 6 Environment.reset(): Trial set up to use 20160801.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 7 Environment.reset(): Trial set up to use 20160802.csv file id: 112762, date: 2016-08-02 16:34:54 qBid Bid Ask qAsk 0 6,600 11.33 11.33 2,600 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 4,000 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112763, date: 2016-08-02 16:35:02 qBid Bid Ask qAsk 0 4,000 11.33 11.33 2,700 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 1,300 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112764, date: 2016-08-02 16:35:04 qBid Bid Ask qAsk 0 1,300 11.33 11.33 4,700 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 18,700 11.32 11.33 3,400 1 13,700 11.31 11.34 27,900 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 id: 112765, date: 2016-08-02 16:35:08 qBid Bid Ask qAsk 0 8,600 11.33 11.33 3,400 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 5,200 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112781, date: 2016-08-02 16:35:44 qBid Bid Ask qAsk 0 13,400 11.33 11.33 5,900 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 7,500 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112803, date: 2016-08-02 16:36:09 qBid Bid Ask qAsk 0 7,500 11.33 11.33 7,100 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 400 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112805, date: 2016-08-02 16:36:13 qBid Bid Ask qAsk 0 19,900 11.33 11.33 8,100 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 11,800 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112806, date: 2016-08-02 16:36:14 qBid Bid Ask qAsk 0 11,800 11.33 11.33 8,300 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 3,500 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112807, date: 2016-08-02 16:36:15 qBid Bid Ask qAsk 0 3,500 11.33 11.32 600 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 2,900 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112808, date: 2016-08-02 16:36:25 qBid Bid Ask qAsk 0 300 11.40 11.34 27,900 1 2,900 11.33 11.35 45,600 2 18,700 11.32 11.36 61,800 3 13,700 11.31 11.37 59,800 4 100 11.30 11.38 20,000 corrected qBid Bid Ask qAsk 0 2,900 11.33 11.34 27,600 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112811, date: 2016-08-02 16:37:18 qBid Bid Ask qAsk 0 2,900 11.33 11.30 1,700 1 18,700 11.32 11.34 27,600 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 1,200 11.33 11.34 27,600 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112813, date: 2016-08-02 16:37:56 qBid Bid Ask qAsk 0 1,200 11.33 11.30 2,000 1 18,700 11.32 11.34 27,600 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 18,700 11.32 11.30 800 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 id: 112813, date: 2016-08-02 16:37:56 qBid Bid Ask qAsk 0 18,700 11.32 11.30 800 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 corrected qBid Bid Ask qAsk 0 17,900 11.32 11.34 27,600 1 13,700 11.31 11.35 45,600 2 100 11.30 11.36 61,800 3 53,900 11.29 11.37 59,800 4 7,100 11.28 11.38 20,000 id: 112930, date: 2016-08-02 17:10:08 qBid Bid Ask qAsk 0 17,900 11.32 11.00 200 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 8 Environment.reset(): Trial set up to use 20160803.csv file corrected Empty DataFrame Columns: [qBid, Bid, Ask, qAsk] Index: [] Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 9 Environment.reset(): Trial set up to use 20160804.csv file id: 107887, date: 2016-08-04 15:08:10 qBid Bid Ask qAsk 0 49,600 12.09 12.09 100 1 100 12.08 12.10 311,700 2 42,800 12.07 12.11 99,700 3 100 12.06 12.12 279,000 4 24,900 12.05 NaN NaN corrected qBid Bid Ask qAsk 0 49,500 12.09 12.10 311,700 1 100 12.08 12.11 99,700 2 42,800 12.07 12.12 279,000 3 100 12.06 NaN NaN 4 24,900 12.05 NaN NaN id: 114962, date: 2016-08-04 15:28:04 qBid Bid Ask qAsk 0 100 12.05 12.05 5,400 1 139,900 12.04 12.06 15,400 2 47,600 12.03 12.07 57,900 3 16,500 12.02 12.08 24,500 4 100 12.01 12.09 38,000 corrected qBid Bid Ask qAsk 0 139,900 12.04 12.05 5,300 1 47,600 12.03 12.06 15,400 2 16,500 12.02 12.07 57,900 3 100 12.01 12.08 24,500 4 20,900 12.00 12.09 38,000 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 10 Environment.reset(): Trial set up to use 20160805.csv file id: 61813, date: 2016-08-05 13:37:24 qBid Bid Ask qAsk 0 100 11.80 11.79 8,100 1 12,400 11.78 11.80 25,900 corrected qBid Bid Ask qAsk 0 12,400 11.78 11.79 8,000 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 11 Environment.reset(): Trial set up to use 20160808.csv file id: 57769, date: 2016-08-08 13:24:23 qBid Bid Ask qAsk 0 800 11.91 11.91 100 1 63,300 11.90 11.92 24,600 2 23,000 11.89 11.93 12,700 3 79,900 11.88 11.94 67,000 4 11,600 11.87 11.95 13,900 corrected qBid Bid Ask qAsk 0 700 11.91 11.92 24,600 1 63,300 11.90 11.93 12,700 2 23,000 11.89 11.94 67,000 3 79,900 11.88 11.95 13,900 4 11,600 11.87 11.96 64,800 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 12 Environment.reset(): Trial set up to use 20160809.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 13 Environment.reset(): Trial set up to use 20160810.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 14 Environment.reset(): Trial set up to use 20160811.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 15 Environment.reset(): Trial set up to use 20160812.csv file id: 1244, date: 2016-08-12 10:07:42 qBid Bid Ask qAsk 0 3,700 12.20 12.20 100 1 20,800 12.19 12.21 13,800 2 25,200 12.18 NaN NaN 3 17,000 12.17 NaN NaN 4 21,400 12.16 NaN NaN corrected qBid Bid Ask qAsk 0 3,600 12.20 12.21 13,800 1 20,800 12.19 NaN NaN 2 25,200 12.18 NaN NaN 3 17,000 12.17 NaN NaN 4 21,400 12.16 NaN NaN id: 20005, date: 2016-08-12 10:32:36 qBid Bid Ask qAsk 0 6,700 12.31 12.30 200 1 89,100 12.30 12.32 45,900 2 6,700 12.29 NaN NaN 3 14,700 12.28 NaN NaN 4 75,300 12.27 NaN NaN corrected qBid Bid Ask qAsk 0 6,500 12.31 12.32 45,900 1 89,100 12.30 NaN NaN 2 6,700 12.29 NaN NaN 3 14,700 12.28 NaN NaN 4 75,300 12.27 NaN NaN id: 111297, date: 2016-08-12 14:46:20 qBid Bid Ask qAsk 0 100 12.15 12.15 20,000 1 55,300 12.13 12.16 69,600 2 23,200 12.12 12.17 60,800 3 8,000 12.11 12.18 30,300 4 10,100 12.10 12.19 128,600 corrected qBid Bid Ask qAsk 0 55,300 12.13 12.15 19,900 1 23,200 12.12 12.16 69,600 2 8,000 12.11 12.17 60,800 3 10,100 12.10 12.18 30,300 4 34,000 12.09 12.19 128,600 Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 16 Environment.reset(): Trial set up to use 20160815.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 17 Environment.reset(): Trial set up to use 20160816.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 18 Environment.reset(): Trial set up to use 20160817.csv file Environment.step(): Market closed at 16:30:00! Trial aborted. Simulator.run(): Trial 19 Environment.reset(): Trial set up to use 20160818.csv file id: 86051, date: 2016-08-18 16:21:40 qBid Bid Ask qAsk 0 100 13.02 13.02 43,700 1 63,000 13.01 13.03 151,900 2 8,400 13.00 NaN NaN 3 118,800 12.99 NaN NaN 4 58,100 12.98 NaN NaN corrected qBid Bid Ask qAsk 0 63,000 13.01 13.02 43,600 1 8,400 13.00 13.03 151,900 2 118,800 12.99 NaN NaN 3 58,100 12.98 NaN NaN 4 53,100 12.97 NaN NaN CPU times: user 4min 12s, sys: 1.28 s, total: 4min 13s Wall time: 4min 13s
Ok, now, let's implement my basic agent that will take actions randomly. I will let it insert limit order with 10 cents of spread between the bid price the the agent order I alow it to update its state just once a hour.
import qtrader.book as book; reload(book);
import qtrader.matching_engine as matching_engine; reload(matching_engine);
import qtrader.environment as environment; reload(environment);
import qtrader.agent as agent; reload(agent);
import qtrader.simulator as simulator; reload(simulator);
import qtrader.translators as translators; reload(translators);
e = environment.Environment()
a = e.create_agent(agent.BasicAgent, f_min_time=3600.)
e.set_primary_agent(a)
sim = simulator.Simulator(e)
%time sim.run(n_trials=30)
Simulator.run(): Trial 1 Environment.reset(): Trial set up to use 20160725.csv file BasicAgent.update(): position = 100.0, inputs = {'qAsk': 7000, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.14', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 30400}, action = TAKE, price_action = ['12.14'], reward = -0.42, time = 2016-07-25 10:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 12800, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.07', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 17600}, action = TAKE, price_action = ['12.07'], reward = -7.42, time = 2016-07-25 11:10:00 BasicAgent.update(): position = 300.0, inputs = {'qAsk': 58900, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.00', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 26200}, action = TAKE, price_action = ['12.00'], reward = -14.42, time = 2016-07-25 12:10:00 BasicAgent.update(): position = 300.0, inputs = {'qAsk': 104200, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.04', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 20600}, action = None, price_action = [], reward = 0, time = 2016-07-25 13:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 90900, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.02', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 5100}, action = HIT, price_action = ['12.02'], reward = 5.58, time = 2016-07-25 14:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 32100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.10', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 44500}, action = None, price_action = [], reward = 0, time = 2016-07-25 15:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 13200, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.07', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 42400}, action = None, price_action = [], reward = 0, time = 2016-07-25 16:10:00 Environment.step(): Market closed at 16:30:00! MidPrice = 12.03. Trial aborted. Simulator.run(): Trial 2 Environment.reset(): Trial set up to use 20160726.csv file BasicAgent.update(): position = -100.0, inputs = {'qAsk': 600, 'spread': 1, 'qAggr': 25600.0, 'qTraded': 83800.0, 'midPrice': '11.92', 'deltaMid': '-0.010', 'qOfi': 121700.0, 'qBid': 95400}, action = HIT, price_action = ['11.92'], reward = -0.42, time = 2016-07-26 10:10:03 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 15800, 'spread': 1, 'qAggr': -6500.0, 'qTraded': 6500.0, 'midPrice': '11.98', 'deltaMid': '0.000', 'qOfi': 1900.0, 'qBid': 7100}, action = TAKE, price_action = ['11.98'], reward = -6.42, time = 2016-07-26 11:10:03 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 49200, 'spread': 2, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.94', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 23600}, action = BEST_BOTH, price_action = ['11.83', '12.05'], reward = 0.0, time = 2016-07-26 12:10:03 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 317500, 'spread': 2, 'qAggr': 17200.0, 'qTraded': 46200.0, 'midPrice': '12.04', 'deltaMid': '0.005', 'qOfi': 17500.0, 'qBid': 67800}, action = SELL, price_action = ['12.05'], reward = 0.58, time = 2016-07-26 12:41:26 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 19000, 'spread': 1, 'qAggr': 10800.0, 'qTraded': 10800.0, 'midPrice': '12.06', 'deltaMid': '0.000', 'qOfi': -9400.0, 'qBid': 10000}, action = HIT, price_action = ['12.05'], reward = -3.42, time = 2016-07-26 13:41:27 BasicAgent.update(): position = -300.0, inputs = {'qAsk': 12100, 'spread': 1, 'qAggr': 1100.0, 'qTraded': 1100.0, 'midPrice': '11.98', 'deltaMid': '0.000', 'qOfi': 12200.0, 'qBid': 133300}, action = HIT, price_action = ['11.98'], reward = 15.58, time = 2016-07-26 14:41:29 BasicAgent.update(): position = -300.0, inputs = {'qAsk': 30300, 'spread': 1, 'qAggr': -500.0, 'qTraded': 900.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': -6600.0, 'qBid': 111300}, action = BEST_BOTH, price_action = ['11.83', '11.85', '12.06'], reward = 6.0, time = 2016-07-26 15:41:29 BasicAgent.update(): position = -300.0, inputs = {'qAsk': 158200, 'spread': 1, 'qAggr': -2100.0, 'qTraded': 2900.0, 'midPrice': '11.93', 'deltaMid': '0.000', 'qOfi': -3100.0, 'qBid': 15400}, action = BEST_BID, price_action = ['12.06', '11.85', '11.83'], reward = 9.0, time = 2016-07-26 16:41:29 Environment.step(): Market closed at 16:30:00! MidPrice = 11.94. Trial aborted. Simulator.run(): Trial 3 Environment.reset(): Trial set up to use 20160727.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 5500, 'spread': 1, 'qAggr': 0, 'qTraded': 0, 'midPrice': '11.98', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 11700}, action = BEST_BID, price_action = ['11.88'], reward = 0.0, time = 2016-07-27 10:10:20 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 25000, 'spread': 1, 'qAggr': -100.0, 'qTraded': 100.0, 'midPrice': '11.93', 'deltaMid': '0.000', 'qOfi': 1200.0, 'qBid': 13700}, action = TAKE, price_action = ['11.94'], reward = -1.42, time = 2016-07-27 11:10:22 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 21200, 'spread': 2, 'qAggr': -230800.0, 'qTraded': 230800.0, 'midPrice': '11.89', 'deltaMid': '-0.015', 'qOfi': -40400.0, 'qBid': 93900}, action = BUY, price_action = ['11.88'], reward = -3.42, time = 2016-07-27 11:20:26 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 27700, 'spread': 1, 'qAggr': 9400.0, 'qTraded': 10600.0, 'midPrice': '11.70', 'deltaMid': '0.000', 'qOfi': 10600.0, 'qBid': 53900}, action = BEST_BID, price_action = ['11.59'], reward = -38.0, time = 2016-07-27 12:20:27 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 22600, 'spread': 1, 'qAggr': -1200.0, 'qTraded': 1400.0, 'midPrice': '11.68', 'deltaMid': '0.000', 'qOfi': 4000.0, 'qBid': 54900}, action = None, price_action = ['11.59'], reward = -4.0, time = 2016-07-27 13:20:27 BasicAgent.update(): position = 300.0, inputs = {'qAsk': 30500, 'spread': 1, 'qAggr': 600.0, 'qTraded': 1800.0, 'midPrice': '11.58', 'deltaMid': '0.000', 'qOfi': 2500.0, 'qBid': 95200}, action = TAKE, price_action = ['11.59'], reward = -21.41, time = 2016-07-27 14:20:27 BasicAgent.update(): position = 400.0, inputs = {'qAsk': 73300, 'spread': 1, 'qAggr': 2500.0, 'qTraded': 2700.0, 'midPrice': '11.62', 'deltaMid': '0.000', 'qOfi': -4800.0, 'qBid': 8300}, action = TAKE, price_action = ['11.63'], reward = 10.59, time = 2016-07-27 15:20:27 id: 118756, date: 2016-07-27 16:18:07 qBid Bid Ask qAsk 0 100 11.65 11.65 9,000 1 77,200 11.64 11.66 78,300 2 8,000 11.63 11.67 29,500 3 72,300 11.62 11.68 38,700 4 79,300 11.61 11.69 94,100 corrected qBid Bid Ask qAsk 0 77,200 11.64 11.65 8,900 1 8,000 11.63 11.66 78,300 2 72,300 11.62 11.67 29,500 3 79,300 11.61 11.68 38,700 4 90,600 11.60 11.69 94,100 BasicAgent.update(): position = 400.0, inputs = {'qAsk': 112800, 'spread': 1, 'qAggr': 8700.0, 'qTraded': 12100.0, 'midPrice': '11.64', 'deltaMid': '0.000', 'qOfi': -125400.0, 'qBid': 83200}, action = None, price_action = [], reward = 0, time = 2016-07-27 16:20:27 Environment.step(): Market closed at 16:30:00! MidPrice = 11.53. Trial aborted. Simulator.run(): Trial 4 Environment.reset(): Trial set up to use 20160728.csv file BasicAgent.update(): position = 100.0, inputs = {'qAsk': 1600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.34', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 72800}, action = TAKE, price_action = ['11.35'], reward = -1.4, time = 2016-07-28 10:10:00 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 4100, 'spread': 1, 'qAggr': 3700.0, 'qTraded': 5900.0, 'midPrice': '11.26', 'deltaMid': '0.010', 'qOfi': 42400.0, 'qBid': 17900}, action = HIT, price_action = ['11.26'], reward = -8.39, time = 2016-07-28 11:10:01 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 6700, 'spread': 1, 'qAggr': -100.0, 'qTraded': 1300.0, 'midPrice': '11.26', 'deltaMid': '0.000', 'qOfi': 1900.0, 'qBid': 21300}, action = TAKE, price_action = ['11.27'], reward = -1.39, time = 2016-07-28 12:10:05 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 5400, 'spread': 1, 'qAggr': 3200.0, 'qTraded': 5000.0, 'midPrice': '11.26', 'deltaMid': '0.000', 'qOfi': -400.0, 'qBid': 35500}, action = None, price_action = [], reward = 0, time = 2016-07-28 13:10:06 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 78200, 'spread': 1, 'qAggr': 4400.0, 'qTraded': 5400.0, 'midPrice': '11.39', 'deltaMid': '0.000', 'qOfi': -700.0, 'qBid': 60300}, action = HIT, price_action = ['11.38'], reward = 11.6, time = 2016-07-28 14:10:06 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 5000, 'spread': 1, 'qAggr': 46000.0, 'qTraded': 75600.0, 'midPrice': '11.52', 'deltaMid': '0.020', 'qOfi': 121400.0, 'qBid': 19900}, action = BEST_BID, price_action = ['11.42'], reward = 0.0, time = 2016-07-28 15:10:06 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 6900, 'spread': 2, 'qAggr': -3900.0, 'qTraded': 3900.0, 'midPrice': '11.43', 'deltaMid': '-0.005', 'qOfi': -10400.0, 'qBid': 58300}, action = BUY, price_action = ['11.42'], reward = 0.6, time = 2016-07-28 15:31:02 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 29500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.40', 'deltaMid': '0.000', 'qOfi': 3300.0, 'qBid': 15500}, action = BEST_BID, price_action = ['11.30'], reward = -3.0, time = 2016-07-28 16:31:04 Environment.step(): Market closed at 16:30:00! MidPrice = 11.43. Trial aborted. Simulator.run(): Trial 5 Environment.reset(): Trial set up to use 20160729.csv file BasicAgent.update(): position = -100.0, inputs = {'qAsk': 28000, 'spread': 1, 'qAggr': -300.0, 'qTraded': 300.0, 'midPrice': '11.76', 'deltaMid': '11.765', 'qOfi': 130100.0, 'qBid': 135100}, action = HIT, price_action = ['11.76'], reward = -0.41, time = 2016-07-29 10:10:11 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 23500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.70', 'deltaMid': '0.000', 'qOfi': -400.0, 'qBid': 7400}, action = None, price_action = [], reward = 0, time = 2016-07-29 11:10:11 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 7000, 'spread': 1, 'qAggr': 600.0, 'qTraded': 600.0, 'midPrice': '11.76', 'deltaMid': '0.000', 'qOfi': 11000.0, 'qBid': 18300}, action = TAKE, price_action = ['11.76'], reward = -0.41, time = 2016-07-29 12:10:11 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 136800, 'spread': 2, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.81', 'deltaMid': '0.000', 'qOfi': 26100.0, 'qBid': 50400}, action = BEST_BID, price_action = ['11.70'], reward = 0.0, time = 2016-07-29 13:10:12 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 93200, 'spread': 1, 'qAggr': 2000.0, 'qTraded': 2400.0, 'midPrice': '11.80', 'deltaMid': '0.000', 'qOfi': 1200.0, 'qBid': 49800}, action = HIT, price_action = ['11.79'], reward = -1.41, time = 2016-07-29 14:10:12 id: 108555, date: 2016-07-29 14:58:07 qBid Bid Ask qAsk 0 200 11.92 11.92 22,500 1 11,700 11.91 11.93 107,900 2 83,000 11.90 11.94 103,600 3 51,200 11.89 11.95 100,700 4 81,100 11.88 NaN NaN corrected qBid Bid Ask qAsk 0 11,700 11.91 11.92 22,300 1 83,000 11.90 11.93 107,900 2 51,200 11.89 11.94 103,600 3 81,100 11.88 11.95 100,700 4 54,100 11.87 NaN NaN BasicAgent.update(): position = 0.0, inputs = {'qAsk': 11200, 'spread': 1, 'qAggr': 800.0, 'qTraded': 6200.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': -2700.0, 'qBid': 8600}, action = TAKE, price_action = ['11.96'], reward = -16.42, time = 2016-07-29 15:10:12 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 6600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.92', 'deltaMid': '0.000', 'qOfi': 400.0, 'qBid': 14100}, action = BEST_BOTH, price_action = ['11.70', '11.81', '12.02'], reward = 0.0, time = 2016-07-29 16:10:12 Environment.step(): Market closed at 16:30:00! MidPrice = 11.92. Trial aborted. Simulator.run(): Trial 6 Environment.reset(): Trial set up to use 20160801.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 4300, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.90', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 52400}, action = BEST_BOTH, price_action = ['11.79', '12.00'], reward = 0.0, time = 2016-08-01 10:10:00 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 7400, 'spread': 1, 'qAggr': -89600.0, 'qTraded': 89600.0, 'midPrice': '11.80', 'deltaMid': '-0.010', 'qOfi': -131700.0, 'qBid': 17000}, action = BUY, price_action = ['11.79'], reward = 0.59, time = 2016-08-01 10:31:15 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 23900, 'spread': 1, 'qAggr': -46900.0, 'qTraded': 51700.0, 'midPrice': '11.64', 'deltaMid': '-0.010', 'qOfi': -73500.0, 'qBid': 31800}, action = HIT, price_action = ['11.63'], reward = -17.41, time = 2016-08-01 11:31:15 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 16400, 'spread': 1, 'qAggr': -100.0, 'qTraded': 100.0, 'midPrice': '11.57', 'deltaMid': '0.000', 'qOfi': -15400.0, 'qBid': 5000}, action = None, price_action = ['12.00'], reward = 0.0, time = 2016-08-01 12:31:16 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 16400, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.50', 'deltaMid': '0.000', 'qOfi': -7000.0, 'qBid': 105400}, action = BEST_BID, price_action = ['11.39'], reward = 0.0, time = 2016-08-01 13:31:16 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 11600, 'spread': 1, 'qAggr': -4900.0, 'qTraded': 4900.0, 'midPrice': '11.52', 'deltaMid': '0.000', 'qOfi': -2400.0, 'qBid': 17600}, action = BEST_BOTH, price_action = ['11.39', '11.41', '11.62'], reward = 0.0, time = 2016-08-01 14:31:17 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 14400, 'spread': 1, 'qAggr': -700.0, 'qTraded': 700.0, 'midPrice': '11.48', 'deltaMid': '0.000', 'qOfi': 5700.0, 'qBid': 129300}, action = HIT, price_action = ['11.47'], reward = -1.4, time = 2016-08-01 15:31:17 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 23500, 'spread': 1, 'qAggr': -23900.0, 'qTraded': 26100.0, 'midPrice': '11.42', 'deltaMid': '-0.010', 'qOfi': 25200.0, 'qBid': 74600}, action = BUY, price_action = ['11.41'], reward = 6.6, time = 2016-08-01 15:52:58 Environment.step(): Market closed at 16:30:00! MidPrice = 11.24. Trial aborted. Simulator.run(): Trial 7 Environment.reset(): Trial set up to use 20160802.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 16100, 'spread': 2, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.34', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 12900}, action = BEST_BID, price_action = ['11.23'], reward = 0.0, time = 2016-08-02 10:10:00 BasicAgent.update(): position = 0, inputs = {'qAsk': 7600, 'spread': 1, 'qAggr': -6400.0, 'qTraded': 8800.0, 'midPrice': '11.36', 'deltaMid': '0.000', 'qOfi': 48600.0, 'qBid': 11100}, action = None, price_action = [], reward = 0, time = 2016-08-02 11:10:01 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 10900, 'spread': 1, 'qAggr': -800.0, 'qTraded': 33000.0, 'midPrice': '11.24', 'deltaMid': '-0.010', 'qOfi': 10400.0, 'qBid': 27700}, action = BUY, price_action = ['11.23'], reward = 0.61, time = 2016-08-02 11:52:08 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 21500, 'spread': 2, 'qAggr': -80600.0, 'qTraded': 80600.0, 'midPrice': '11.24', 'deltaMid': '-0.015', 'qOfi': -84400.0, 'qBid': 55800}, action = BEST_BID, price_action = ['11.13'], reward = 0.0, time = 2016-08-02 12:52:08 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 7400, 'spread': 1, 'qAggr': -3500.0, 'qTraded': 6500.0, 'midPrice': '11.24', 'deltaMid': '0.000', 'qOfi': -30800.0, 'qBid': 6800}, action = BEST_BID, price_action = ['11.13', '11.13'], reward = 0.0, time = 2016-08-02 13:52:11 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 14500, 'spread': 2, 'qAggr': -24400.0, 'qTraded': 29800.0, 'midPrice': '11.14', 'deltaMid': '-0.005', 'qOfi': -72700.0, 'qBid': 14100}, action = BUY, price_action = ['11.13'], reward = -9.39, time = 2016-08-02 14:10:38 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 6600, 'spread': 1, 'qAggr': 1400.0, 'qTraded': 10200.0, 'midPrice': '11.23', 'deltaMid': '0.000', 'qOfi': -10300.0, 'qBid': 53100}, action = None, price_action = [], reward = 0, time = 2016-08-02 15:10:38 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 7700, 'spread': 1, 'qAggr': -15000.0, 'qTraded': 16600.0, 'midPrice': '11.36', 'deltaMid': '-0.010', 'qOfi': -36700.0, 'qBid': 13700}, action = None, price_action = [], reward = 0, time = 2016-08-02 16:10:39 id: 112762, date: 2016-08-02 16:34:54 qBid Bid Ask qAsk 0 6,600 11.33 11.33 2,600 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 4,000 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112763, date: 2016-08-02 16:35:02 qBid Bid Ask qAsk 0 4,000 11.33 11.33 2,700 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 1,300 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112764, date: 2016-08-02 16:35:04 qBid Bid Ask qAsk 0 1,300 11.33 11.33 4,700 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 18,700 11.32 11.33 3,400 1 13,700 11.31 11.34 27,900 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 id: 112765, date: 2016-08-02 16:35:08 qBid Bid Ask qAsk 0 8,600 11.33 11.33 3,400 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 5,200 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112781, date: 2016-08-02 16:35:44 qBid Bid Ask qAsk 0 13,400 11.33 11.33 5,900 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 7,500 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112803, date: 2016-08-02 16:36:09 qBid Bid Ask qAsk 0 7,500 11.33 11.33 7,100 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 400 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112805, date: 2016-08-02 16:36:13 qBid Bid Ask qAsk 0 19,900 11.33 11.33 8,100 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 11,800 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112806, date: 2016-08-02 16:36:14 qBid Bid Ask qAsk 0 11,800 11.33 11.33 8,300 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 3,500 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112807, date: 2016-08-02 16:36:15 qBid Bid Ask qAsk 0 3,500 11.33 11.32 600 1 18,700 11.32 11.34 27,900 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 2,900 11.33 11.34 27,900 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112808, date: 2016-08-02 16:36:25 qBid Bid Ask qAsk 0 300 11.40 11.34 27,900 1 2,900 11.33 11.35 45,600 2 18,700 11.32 11.36 61,800 3 13,700 11.31 11.37 59,800 4 100 11.30 11.38 20,000 corrected qBid Bid Ask qAsk 0 2,900 11.33 11.34 27,600 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112811, date: 2016-08-02 16:37:18 qBid Bid Ask qAsk 0 2,900 11.33 11.30 1,700 1 18,700 11.32 11.34 27,600 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 1,200 11.33 11.34 27,600 1 18,700 11.32 11.35 45,600 2 13,700 11.31 11.36 61,800 3 100 11.30 11.37 59,800 4 53,900 11.29 11.38 20,000 id: 112813, date: 2016-08-02 16:37:56 qBid Bid Ask qAsk 0 1,200 11.33 11.30 2,000 1 18,700 11.32 11.34 27,600 2 13,700 11.31 11.35 45,600 3 100 11.30 11.36 61,800 4 53,900 11.29 11.37 59,800 corrected qBid Bid Ask qAsk 0 18,700 11.32 11.30 800 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 id: 112813, date: 2016-08-02 16:37:56 qBid Bid Ask qAsk 0 18,700 11.32 11.30 800 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 corrected qBid Bid Ask qAsk 0 17,900 11.32 11.34 27,600 1 13,700 11.31 11.35 45,600 2 100 11.30 11.36 61,800 3 53,900 11.29 11.37 59,800 4 7,100 11.28 11.38 20,000 id: 112930, date: 2016-08-02 17:10:08 qBid Bid Ask qAsk 0 17,900 11.32 11.00 200 1 13,700 11.31 11.34 27,600 2 100 11.30 11.35 45,600 3 53,900 11.29 11.36 61,800 4 7,100 11.28 11.37 59,800 Environment.step(): Market closed at 16:30:00! MidPrice = 11.34. Trial aborted. Simulator.run(): Trial 8 Environment.reset(): Trial set up to use 20160803.csv file corrected Empty DataFrame Columns: [qBid, Bid, Ask, qAsk] Index: [] Environment.step(): Market closed at 16:30:00! MidPrice = 0.00. Trial aborted. Simulator.run(): Trial 9 Environment.reset(): Trial set up to use 20160804.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 9400, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 13500}, action = BEST_BOTH, price_action = ['11.85', '12.06'], reward = 0.0, time = 2016-08-04 10:10:00 BasicAgent.update(): position = -100, inputs = {'qAsk': 11300, 'spread': 1, 'qAggr': 173800.0, 'qTraded': 189600.0, 'midPrice': '12.06', 'deltaMid': '0.010', 'qOfi': 206000.0, 'qBid': 27400}, action = SELL, price_action = ['12.06'], reward = -0.42, time = 2016-08-04 10:15:06 id: 3169, date: 2016-08-04 10:15:06 qBid Bid Ask qAsk 0 23,700 12.06 12.06 100 1 27,400 12.05 NaN NaN 2 11,700 12.04 NaN NaN 3 146,600 12.03 NaN NaN 4 26,700 12.02 NaN NaN corrected qBid Bid Ask qAsk 0 23,600 12.06 NaN NaN 1 27,400 12.05 NaN NaN 2 11,700 12.04 NaN NaN 3 146,600 12.03 NaN NaN 4 26,700 12.02 NaN NaN BasicAgent.update(): position = -100, inputs = {'qAsk': 40600, 'spread': 1, 'qAggr': 300.0, 'qTraded': 300.0, 'midPrice': '11.90', 'deltaMid': '0.000', 'qOfi': 300.0, 'qBid': 46400}, action = BEST_BID, price_action = ['11.85', '11.80'], reward = 16.0, time = 2016-08-04 11:15:06 BasicAgent.update(): position = -100, inputs = {'qAsk': 46800, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.98', 'deltaMid': '0.000', 'qOfi': -7200.0, 'qBid': 8300}, action = BEST_BID, price_action = ['11.80', '11.87'], reward = -8.0, time = 2016-08-04 12:15:06 BasicAgent.update(): position = -100, inputs = {'qAsk': 13000, 'spread': 1, 'qAggr': 2200.0, 'qTraded': 2200.0, 'midPrice': '12.07', 'deltaMid': '0.000', 'qOfi': 5300.0, 'qBid': 12100}, action = BEST_BOTH, price_action = ['11.87', '11.96', '12.17'], reward = -9.0, time = 2016-08-04 13:15:06 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 9800, 'spread': 1, 'qAggr': -16500.0, 'qTraded': 30300.0, 'midPrice': '12.04', 'deltaMid': '0.000', 'qOfi': -61600.0, 'qBid': 18200}, action = HIT, price_action = ['12.03'], reward = 1.58, time = 2016-08-04 14:15:06 id: 107887, date: 2016-08-04 15:08:10 qBid Bid Ask qAsk 0 49,600 12.09 12.09 100 1 100 12.08 12.10 311,700 2 42,800 12.07 12.11 99,700 3 100 12.06 12.12 279,000 4 24,900 12.05 12.17 100 corrected qBid Bid Ask qAsk 0 49,500 12.09 12.10 311,700 1 100 12.08 12.11 99,700 2 42,800 12.07 12.12 279,000 3 100 12.06 12.17 100 4 24,900 12.05 NaN NaN BasicAgent.update(): position = -200.0, inputs = {'qAsk': 25000, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '12.08', 'deltaMid': '0.000', 'qOfi': -1600.0, 'qBid': 15900}, action = None, price_action = [], reward = 0, time = 2016-08-04 15:15:07 id: 114962, date: 2016-08-04 15:28:04 qBid Bid Ask qAsk 0 100 12.05 12.05 5,400 1 139,900 12.04 12.06 15,400 2 47,600 12.03 12.07 57,900 3 16,500 12.02 12.08 24,500 4 100 12.01 12.09 38,000 corrected qBid Bid Ask qAsk 0 139,900 12.04 12.05 5,300 1 47,600 12.03 12.06 15,400 2 16,500 12.02 12.07 57,900 3 100 12.01 12.08 24,500 4 20,900 12.00 12.09 38,000 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 5200, 'spread': 1, 'qAggr': -159200.0, 'qTraded': 181400.0, 'midPrice': '11.96', 'deltaMid': '-0.050', 'qOfi': -114400.0, 'qBid': 95000}, action = BUY, price_action = ['11.96'], reward = 15.58, time = 2016-08-04 15:32:58 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 9100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.00', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 33500}, action = None, price_action = ['12.17'], reward = -4.0, time = 2016-08-04 16:33:00 Environment.step(): Market closed at 16:30:00! MidPrice = 11.98. Trial aborted. Simulator.run(): Trial 10 Environment.reset(): Trial set up to use 20160805.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 67900, 'spread': 1, 'qAggr': -300.0, 'qTraded': 300.0, 'midPrice': '12.11', 'deltaMid': '12.115', 'qOfi': 100.0, 'qBid': 100}, action = None, price_action = [], reward = 0, time = 2016-08-05 10:10:22 BasicAgent.update(): position = 0, inputs = {'qAsk': 89700, 'spread': 1, 'qAggr': 1200.0, 'qTraded': 1200.0, 'midPrice': '11.86', 'deltaMid': '0.000', 'qOfi': 1100.0, 'qBid': 15000}, action = None, price_action = [], reward = 0, time = 2016-08-05 11:10:22 BasicAgent.update(): position = 0, inputs = {'qAsk': 10100, 'spread': 1, 'qAggr': 1000.0, 'qTraded': 1000.0, 'midPrice': '11.84', 'deltaMid': '0.000', 'qOfi': 4300.0, 'qBid': 36200}, action = None, price_action = [], reward = 0, time = 2016-08-05 12:10:22 BasicAgent.update(): position = 0, inputs = {'qAsk': 5900, 'spread': 1, 'qAggr': -1800.0, 'qTraded': 1800.0, 'midPrice': '11.84', 'deltaMid': '-0.010', 'qOfi': -23500.0, 'qBid': 46700}, action = BEST_BOTH, price_action = ['11.73', '11.94'], reward = 0.0, time = 2016-08-05 13:10:22 id: 61813, date: 2016-08-05 13:37:24 qBid Bid Ask qAsk 0 100 11.80 11.79 8,100 1 12,400 11.78 11.80 25,900 2 100 11.73 11.81 12,900 corrected qBid Bid Ask qAsk 0 12,400 11.78 11.79 8,000 1 100 11.73 11.80 25,900 BasicAgent.update(): position = 0, inputs = {'qAsk': 12100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.78', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 60000}, action = None, price_action = ['11.73', '11.94'], reward = 0.0, time = 2016-08-05 14:10:24 BasicAgent.update(): position = 0, inputs = {'qAsk': 17100, 'spread': 1, 'qAggr': 1200.0, 'qTraded': 1200.0, 'midPrice': '11.80', 'deltaMid': '0.000', 'qOfi': 5700.0, 'qBid': 28800}, action = BEST_BID, price_action = ['11.69'], reward = 0.0, time = 2016-08-05 15:10:24 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 39300, 'spread': 1, 'qAggr': -900.0, 'qTraded': 3900.0, 'midPrice': '11.73', 'deltaMid': '0.000', 'qOfi': -1000.0, 'qBid': 48900}, action = HIT, price_action = ['11.72'], reward = -1.41, time = 2016-08-05 16:10:24 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 27000, 'spread': 1, 'qAggr': 12200.0, 'qTraded': 67400.0, 'midPrice': '11.70', 'deltaMid': '0.000', 'qOfi': 13700.0, 'qBid': 77900}, action = BUY, price_action = ['11.69'], reward = 3.59, time = 2016-08-05 16:49:09 Environment.step(): Market closed at 16:30:00! MidPrice = 11.69. Trial aborted. Simulator.run(): Trial 11 Environment.reset(): Trial set up to use 20160808.csv file BasicAgent.update(): position = -100.0, inputs = {'qAsk': 16600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.76', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 22100}, action = HIT, price_action = ['11.75'], reward = -1.41, time = 2016-08-08 10:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 102400, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.94', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 36300}, action = None, price_action = [], reward = 0, time = 2016-08-08 11:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 30000, 'spread': 1, 'qAggr': 1100.0, 'qTraded': 1100.0, 'midPrice': '11.92', 'deltaMid': '0.000', 'qOfi': 500.0, 'qBid': 9500}, action = BEST_BOTH, price_action = ['11.82', '12.03'], reward = -16.0, time = 2016-08-08 12:10:04 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 16300, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.92', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 3400}, action = BEST_BID, price_action = ['12.03', '11.82', '11.81'], reward = 0.0, time = 2016-08-08 13:10:05 id: 57769, date: 2016-08-08 13:24:23 qBid Bid Ask qAsk 0 800 11.91 11.91 100 1 63,300 11.90 11.92 24,600 2 23,000 11.89 11.93 12,700 3 79,900 11.88 11.94 67,000 4 11,600 11.87 11.95 13,900 corrected qBid Bid Ask qAsk 0 700 11.91 11.92 24,600 1 63,300 11.90 11.93 12,700 2 23,000 11.89 11.94 67,000 3 79,900 11.88 11.95 13,900 4 11,600 11.87 11.96 64,800 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 39100, 'spread': 1, 'qAggr': -3600.0, 'qTraded': 3600.0, 'midPrice': '11.90', 'deltaMid': '0.000', 'qOfi': -35700.0, 'qBid': 36000}, action = None, price_action = ['11.81'], reward = 2.0, time = 2016-08-08 14:10:05 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 5300, 'spread': 1, 'qAggr': 8500.0, 'qTraded': 8500.0, 'midPrice': '11.94', 'deltaMid': '0.000', 'qOfi': 12100.0, 'qBid': 53700}, action = BEST_BOTH, price_action = ['11.84', '12.05'], reward = -4.0, time = 2016-08-08 15:10:05 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 244800, 'spread': 1, 'qAggr': 12900.0, 'qTraded': 12900.0, 'midPrice': '11.94', 'deltaMid': '0.005', 'qOfi': 21500.0, 'qBid': 28100}, action = HIT, price_action = ['11.94'], reward = -0.42, time = 2016-08-08 16:10:07 Environment.step(): Market closed at 16:30:00! MidPrice = 11.89. Trial aborted. Simulator.run(): Trial 12 Environment.reset(): Trial set up to use 20160809.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 13200, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.93', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 20300}, action = BEST_BOTH, price_action = ['11.83', '12.04'], reward = 0.0, time = 2016-08-09 10:10:00 BasicAgent.update(): position = -100, inputs = {'qAsk': 79900, 'spread': 3, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.02', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 15000}, action = SELL, price_action = ['12.04'], reward = 1.58, time = 2016-08-09 10:21:20 BasicAgent.update(): position = -100, inputs = {'qAsk': 6500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.00', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 24300}, action = None, price_action = [], reward = 0, time = 2016-08-09 11:21:20 BasicAgent.update(): position = -100, inputs = {'qAsk': 30600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 49000}, action = None, price_action = [], reward = 0, time = 2016-08-09 12:21:20 BasicAgent.update(): position = 0, inputs = {'qAsk': 14800, 'spread': 2, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.84', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 77400}, action = BUY, price_action = ['11.83'], reward = 18.59, time = 2016-08-09 12:47:50 BasicAgent.update(): position = 0, inputs = {'qAsk': 60000, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.77', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 62400}, action = None, price_action = [], reward = 0, time = 2016-08-09 13:47:50 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 48900, 'spread': 1, 'qAggr': 900.0, 'qTraded': 900.0, 'midPrice': '11.82', 'deltaMid': '0.000', 'qOfi': 1400.0, 'qBid': 43000}, action = HIT, price_action = ['11.82'], reward = -0.41, time = 2016-08-09 14:47:52 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 25000, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '11.82', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 48500}, action = TAKE, price_action = ['11.83'], reward = -1.41, time = 2016-08-09 15:47:52 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 78300, 'spread': 1, 'qAggr': 600.0, 'qTraded': 600.0, 'midPrice': '11.86', 'deltaMid': '0.000', 'qOfi': 400.0, 'qBid': 12700}, action = TAKE, price_action = ['11.87'], reward = -1.42, time = 2016-08-09 16:47:52 Environment.step(): Market closed at 16:30:00! MidPrice = 11.87. Trial aborted. Simulator.run(): Trial 13 Environment.reset(): Trial set up to use 20160810.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 7800, 'spread': 1, 'qAggr': -2000.0, 'qTraded': 2000.0, 'midPrice': '11.94', 'deltaMid': '11.945', 'qOfi': -2000.0, 'qBid': 3000}, action = BEST_BID, price_action = ['11.84'], reward = 0.0, time = 2016-08-10 10:10:11 BasicAgent.update(): position = 100, inputs = {'qAsk': 28000, 'spread': 1, 'qAggr': -5600.0, 'qTraded': 7800.0, 'midPrice': '11.84', 'deltaMid': '-0.010', 'qOfi': -76300.0, 'qBid': 20100}, action = BUY, price_action = ['11.84'], reward = -0.41, time = 2016-08-10 10:41:43 BasicAgent.update(): position = 100, inputs = {'qAsk': 8500, 'spread': 1, 'qAggr': -4000.0, 'qTraded': 4000.0, 'midPrice': '11.74', 'deltaMid': '0.000', 'qOfi': -10700.0, 'qBid': 33300}, action = BEST_BOTH, price_action = ['11.63', '11.84'], reward = -10.0, time = 2016-08-10 11:41:46 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 300, 'spread': 1, 'qAggr': -99000.0, 'qTraded': 104200.0, 'midPrice': '11.64', 'deltaMid': '-0.020', 'qOfi': -75400.0, 'qBid': 58700}, action = BUY, price_action = ['11.63'], reward = -9.41, time = 2016-08-10 12:11:55 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 23200, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '11.68', 'deltaMid': '0.000', 'qOfi': 2200.0, 'qBid': 56500}, action = BEST_BOTH, price_action = ['11.58', '11.84', '11.79'], reward = 8.0, time = 2016-08-10 13:11:55 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 9300, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '11.66', 'deltaMid': '0.000', 'qOfi': 36900.0, 'qBid': 52600}, action = BEST_BID, price_action = ['11.79', '11.58', '11.56'], reward = -4.0, time = 2016-08-10 14:11:56 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 68100, 'spread': 1, 'qAggr': -500.0, 'qTraded': 2700.0, 'midPrice': '11.77', 'deltaMid': '0.000', 'qOfi': 4000.0, 'qBid': 23600}, action = None, price_action = ['11.56'], reward = 22.0, time = 2016-08-10 15:11:57 BasicAgent.update(): position = 300.0, inputs = {'qAsk': 26100, 'spread': 1, 'qAggr': -6900.0, 'qTraded': 7300.0, 'midPrice': '11.73', 'deltaMid': '0.000', 'qOfi': -21400.0, 'qBid': 43800}, action = TAKE, price_action = ['11.73'], reward = -8.41, time = 2016-08-10 16:11:57 Environment.step(): Market closed at 16:30:00! MidPrice = 11.68. Trial aborted. Simulator.run(): Trial 14 Environment.reset(): Trial set up to use 20160811.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 59300, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.66', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 10500}, action = None, price_action = [], reward = 0, time = 2016-08-11 10:10:00 BasicAgent.update(): position = 0, inputs = {'qAsk': 17100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.68', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 93900}, action = None, price_action = [], reward = 0, time = 2016-08-11 11:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 20500, 'spread': 1, 'qAggr': 300.0, 'qTraded': 300.0, 'midPrice': '11.78', 'deltaMid': '0.000', 'qOfi': 300.0, 'qBid': 7200}, action = HIT, price_action = ['11.78'], reward = -0.41, time = 2016-08-11 12:10:01 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 42200, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '11.84', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 1600}, action = None, price_action = [], reward = 0, time = 2016-08-11 13:10:01 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 14700, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 22300}, action = BEST_BOTH, price_action = ['11.85', '12.06'], reward = -18.0, time = 2016-08-11 14:10:01 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 9600, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '11.96', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 84400}, action = HIT, price_action = ['11.96'], reward = -0.42, time = 2016-08-11 15:10:01 BasicAgent.update(): position = -300.0, inputs = {'qAsk': 62500, 'spread': 2, 'qAggr': 31300.0, 'qTraded': 31500.0, 'midPrice': '12.05', 'deltaMid': '0.005', 'qOfi': 12100.0, 'qBid': 40700}, action = SELL, price_action = ['12.06'], reward = -17.42, time = 2016-08-11 15:52:09 Environment.step(): Market closed at 16:30:00! MidPrice = 12.07. Trial aborted. Simulator.run(): Trial 15 Environment.reset(): Trial set up to use 20160812.csv file id: 1244, date: 2016-08-12 10:07:42 qBid Bid Ask qAsk 0 3,700 12.20 12.20 100 1 20,800 12.19 12.21 13,800 2 25,200 12.18 NaN NaN 3 17,000 12.17 NaN NaN 4 21,400 12.16 NaN NaN corrected qBid Bid Ask qAsk 0 3,600 12.20 12.21 13,800 1 20,800 12.19 NaN NaN 2 25,200 12.18 NaN NaN 3 17,000 12.17 NaN NaN 4 21,400 12.16 NaN NaN BasicAgent.update(): position = -100.0, inputs = {'qAsk': 5500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.12', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 13400}, action = HIT, price_action = ['12.12'], reward = -0.42, time = 2016-08-12 10:10:00 id: 20005, date: 2016-08-12 10:32:36 qBid Bid Ask qAsk 0 6,700 12.31 12.30 200 1 89,100 12.30 12.32 45,900 2 6,700 12.29 NaN NaN 3 14,700 12.28 NaN NaN 4 75,300 12.27 NaN NaN corrected qBid Bid Ask qAsk 0 6,500 12.31 12.32 45,900 1 89,100 12.30 NaN NaN 2 6,700 12.29 NaN NaN 3 14,700 12.28 NaN NaN 4 75,300 12.27 NaN NaN BasicAgent.update(): position = -100.0, inputs = {'qAsk': 100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.32', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 61900}, action = None, price_action = [], reward = 0, time = 2016-08-12 11:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 55900, 'spread': 1, 'qAggr': 7600.0, 'qTraded': 9600.0, 'midPrice': '12.26', 'deltaMid': '0.010', 'qOfi': 81900.0, 'qBid': 8400}, action = BEST_BOTH, price_action = ['12.15', '12.36'], reward = -14.0, time = 2016-08-12 12:10:01 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 15800, 'spread': 1, 'qAggr': -18000.0, 'qTraded': 30200.0, 'midPrice': '12.22', 'deltaMid': '0.000', 'qOfi': 25700.0, 'qBid': 29700}, action = HIT, price_action = ['12.21'], reward = 2.57, time = 2016-08-12 13:10:01 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 13200, 'spread': 1, 'qAggr': -32400.0, 'qTraded': 38200.0, 'midPrice': '12.16', 'deltaMid': '-0.010', 'qOfi': -92500.0, 'qBid': 140700}, action = BUY, price_action = ['12.15'], reward = 12.57, time = 2016-08-12 13:46:58 id: 111297, date: 2016-08-12 14:46:20 qBid Bid Ask qAsk 0 100 12.15 12.15 20,000 1 55,300 12.13 12.16 69,600 2 23,200 12.12 12.17 60,800 3 8,000 12.11 12.18 30,300 4 10,100 12.10 12.19 128,600 corrected qBid Bid Ask qAsk 0 55,300 12.13 12.15 19,900 1 23,200 12.12 12.16 69,600 2 8,000 12.11 12.17 60,800 3 10,100 12.10 12.18 30,300 4 34,000 12.09 12.19 128,600 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 46200, 'spread': 1, 'qAggr': -400.0, 'qTraded': 400.0, 'midPrice': '12.12', 'deltaMid': '0.000', 'qOfi': -12100.0, 'qBid': 20500}, action = BEST_BOTH, price_action = ['12.02', '12.36', '12.23'], reward = 4.0, time = 2016-08-12 14:46:58 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 76200, 'spread': 2, 'qAggr': 51900.0, 'qTraded': 53900.0, 'midPrice': '12.17', 'deltaMid': '0.005', 'qOfi': 6800.0, 'qBid': 10800}, action = TAKE, price_action = ['12.18'], reward = -6.43, time = 2016-08-12 15:46:58 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 18200, 'spread': 2, 'qAggr': -158400.0, 'qTraded': 165400.0, 'midPrice': '12.03', 'deltaMid': '-0.025', 'qOfi': -20700.0, 'qBid': 117000}, action = BUY, price_action = ['12.02'], reward = 0.58, time = 2016-08-12 16:31:32 Environment.step(): Market closed at 16:30:00! MidPrice = 12.01. Trial aborted. Simulator.run(): Trial 16 Environment.reset(): Trial set up to use 20160815.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 3100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.16', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 26500}, action = None, price_action = [], reward = 0, time = 2016-08-15 10:10:00 BasicAgent.update(): position = 0, inputs = {'qAsk': 99800, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.24', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 17100}, action = BEST_BOTH, price_action = ['12.13', '12.34'], reward = 0.0, time = 2016-08-15 11:10:00 BasicAgent.update(): position = 0, inputs = {'qAsk': 24600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.24', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 110500}, action = BEST_BOTH, price_action = ['12.13', '12.14', '12.34', '12.35'], reward = 0.0, time = 2016-08-15 12:10:00 BasicAgent.update(): position = 0, inputs = {'qAsk': 48500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.32', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 24300}, action = BEST_BID, price_action = ['12.35', '12.14', '12.22'], reward = 0.0, time = 2016-08-15 13:10:00 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 21100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.30', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 96000}, action = TAKE, price_action = ['12.31'], reward = -1.43, time = 2016-08-15 14:10:00 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 16100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.27', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 7000}, action = HIT, price_action = ['12.27'], reward = -3.43, time = 2016-08-15 15:10:00 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 60100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.30', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 9600}, action = BEST_BID, price_action = ['12.22', '12.20'], reward = 0.0, time = 2016-08-15 16:10:00 Environment.step(): Market closed at 16:30:00! MidPrice = 12.29. Trial aborted. Simulator.run(): Trial 17 Environment.reset(): Trial set up to use 20160816.csv file BasicAgent.update(): position = -100.0, inputs = {'qAsk': 11500, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.30', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 19600}, action = HIT, price_action = ['12.29'], reward = -1.43, time = 2016-08-16 10:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 13100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.36', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 6500}, action = None, price_action = [], reward = 0, time = 2016-08-16 11:10:00 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 27400, 'spread': 1, 'qAggr': -3600.0, 'qTraded': 3600.0, 'midPrice': '12.32', 'deltaMid': '0.000', 'qOfi': -900.0, 'qBid': 6400}, action = None, price_action = [], reward = 0, time = 2016-08-16 12:10:01 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 139500, 'spread': 1, 'qAggr': -3300.0, 'qTraded': 3300.0, 'midPrice': '12.44', 'deltaMid': '0.000', 'qOfi': 100.0, 'qBid': 7300}, action = None, price_action = [], reward = 0, time = 2016-08-16 13:10:01 BasicAgent.update(): position = -100.0, inputs = {'qAsk': 96200, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.48', 'deltaMid': '0.000', 'qOfi': 5000.0, 'qBid': 40600}, action = None, price_action = [], reward = 0, time = 2016-08-16 14:10:01 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 61700, 'spread': 1, 'qAggr': -100.0, 'qTraded': 100.0, 'midPrice': '12.52', 'deltaMid': '0.000', 'qOfi': -100.0, 'qBid': 40000}, action = HIT, price_action = ['12.52'], reward = -22.44, time = 2016-08-16 15:10:01 BasicAgent.update(): position = -200.0, inputs = {'qAsk': 66500, 'spread': 1, 'qAggr': -100.0, 'qTraded': 100.0, 'midPrice': '12.50', 'deltaMid': '0.000', 'qOfi': -100.0, 'qBid': 79100}, action = BEST_BID, price_action = ['12.39'], reward = 4.0, time = 2016-08-16 16:10:01 Environment.step(): Market closed at 16:30:00! MidPrice = 12.51. Trial aborted. Simulator.run(): Trial 18 Environment.reset(): Trial set up to use 20160817.csv file BasicAgent.update(): position = 0, inputs = {'qAsk': 100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.42', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 43700}, action = BEST_BOTH, price_action = ['12.32', '12.53'], reward = 0.0, time = 2016-08-17 10:10:00 BasicAgent.update(): position = 100, inputs = {'qAsk': 7400, 'spread': 1, 'qAggr': -78700.0, 'qTraded': 80500.0, 'midPrice': '12.32', 'deltaMid': '-0.015', 'qOfi': -44400.0, 'qBid': 67200}, action = BUY, price_action = ['12.32'], reward = -0.43, time = 2016-08-17 10:59:04 BasicAgent.update(): position = 0, inputs = {'qAsk': 93400, 'spread': 1, 'qAggr': 169800.0, 'qTraded': 191600.0, 'midPrice': '12.52', 'deltaMid': '0.030', 'qOfi': 216700.0, 'qBid': 300}, action = SELL, price_action = ['12.53'], reward = 20.56, time = 2016-08-17 11:36:12 BasicAgent.update(): position = 0, inputs = {'qAsk': 6800, 'spread': 1, 'qAggr': 8300.0, 'qTraded': 8300.0, 'midPrice': '12.48', 'deltaMid': '0.000', 'qOfi': 7400.0, 'qBid': 25700}, action = BEST_BOTH, price_action = ['12.37', '12.58'], reward = 0.0, time = 2016-08-17 12:36:12 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 19900, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '12.52', 'deltaMid': '0.000', 'qOfi': -2600.0, 'qBid': 21800}, action = TAKE, price_action = ['12.52'], reward = -0.44, time = 2016-08-17 13:36:12 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 73300, 'spread': 1, 'qAggr': -200.0, 'qTraded': 200.0, 'midPrice': '12.58', 'deltaMid': '0.000', 'qOfi': 11200.0, 'qBid': 16300}, action = SELL, price_action = ['12.58'], reward = 5.56, time = 2016-08-17 14:16:24 BasicAgent.update(): position = 0.0, inputs = {'qAsk': 7400, 'spread': 1, 'qAggr': -5200.0, 'qTraded': 5200.0, 'midPrice': '12.60', 'deltaMid': '-0.010', 'qOfi': -24200.0, 'qBid': 34700}, action = None, price_action = [], reward = 0, time = 2016-08-17 15:16:24 BasicAgent.update(): position = 100.0, inputs = {'qAsk': 4700, 'spread': 1, 'qAggr': -25400.0, 'qTraded': 46000.0, 'midPrice': '12.72', 'deltaMid': '-0.010', 'qOfi': -61600.0, 'qBid': 18000}, action = TAKE, price_action = ['12.72'], reward = -0.45, time = 2016-08-17 16:16:24 Environment.step(): Market closed at 16:30:00! MidPrice = 12.74. Trial aborted. Simulator.run(): Trial 19 Environment.reset(): Trial set up to use 20160818.csv file BasicAgent.update(): position = 100.0, inputs = {'qAsk': 20600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.82', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 19800}, action = TAKE, price_action = ['12.83'], reward = -1.45, time = 2016-08-18 10:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 53600, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.93', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 30400}, action = TAKE, price_action = ['12.94'], reward = 9.55, time = 2016-08-18 11:10:00 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 14800, 'spread': 1, 'qAggr': 100.0, 'qTraded': 100.0, 'midPrice': '12.88', 'deltaMid': '0.000', 'qOfi': -6100.0, 'qBid': 41700}, action = BEST_BID, price_action = ['12.77'], reward = -10.0, time = 2016-08-18 12:10:03 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 32700, 'spread': 1, 'qAggr': -1100.0, 'qTraded': 3100.0, 'midPrice': '12.93', 'deltaMid': '0.005', 'qOfi': 11000.0, 'qBid': 10000}, action = BEST_BOTH, price_action = ['12.77', '12.83', '13.04'], reward = 10.0, time = 2016-08-18 13:10:05 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 133100, 'spread': 1, 'qAggr': 0.0, 'qTraded': 0.0, 'midPrice': '12.94', 'deltaMid': '0.000', 'qOfi': 0.0, 'qBid': 48000}, action = BEST_BID, price_action = ['13.04', '12.83', '12.84'], reward = 2.0, time = 2016-08-18 14:10:10 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 2000, 'spread': 1, 'qAggr': 5400.0, 'qTraded': 10200.0, 'midPrice': '12.92', 'deltaMid': '0.000', 'qOfi': -10600.0, 'qBid': 18300}, action = BEST_BID, price_action = ['12.84', '12.82'], reward = -4.0, time = 2016-08-18 15:10:13 BasicAgent.update(): position = 200.0, inputs = {'qAsk': 297000, 'spread': 1, 'qAggr': 19200.0, 'qTraded': 24600.0, 'midPrice': '12.98', 'deltaMid': '0.000', 'qOfi': -6600.0, 'qBid': 25100}, action = None, price_action = [], reward = 0, time = 2016-08-18 16:10:13 id: 86051, date: 2016-08-18 16:21:40 qBid Bid Ask qAsk 0 100 13.02 13.02 43,700 1 63,000 13.01 13.03 151,900 2 8,400 13.00 NaN NaN 3 118,800 12.99 NaN NaN 4 58,100 12.98 NaN NaN corrected qBid Bid Ask qAsk 0 63,000 13.01 13.02 43,600 1 8,400 13.00 13.03 151,900 2 118,800 12.99 NaN NaN 3 58,100 12.98 NaN NaN 4 53,100 12.97 NaN NaN CPU times: user 4min 33s, sys: 3.4 s, total: 4min 36s Wall time: 4min 35s
WOOOOWWWWWWWWWWW ... it worked. Now.... after almost a month doing that (today is 16th september), I can finally ...... start the Udacity projet =/
Style notebook and change matplotlib defaults
#loading style sheet
from IPython.core.display import HTML
HTML( open('ipython_style.css').read())
#changing matplotlib defaults
%matplotlib inline
import seaborn as sns
sns.set_palette("deep", desat=.6)
sns.set_context(rc={"figure.figsize": (8, 4)})
sns.set_style("whitegrid")
sns.set_palette(sns.color_palette("Set2", 10))