Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: abides-sim/abides
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.1
Choose a base ref
...
head repository: abides-sim/abides
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Mar 18, 2020

  1. pov mm agent fix to query the transacted volume

    Mahmoud Mahfouz committed Mar 18, 2020
    Copy the full SHA
    3629af4 View commit details
  2. pov mm agent fix to query the transacted volume

    pov mm agent fix to query the transacted volume
    mamahfouz authored Mar 18, 2020
    Copy the full SHA
    5f62c54 View commit details

Commits on Apr 28, 2020

  1. Broadened Kernel.agent_saved_states concept into Kernel.custom_state,…

    … updated terminology to match, and updated the one agent and two configs affected by the change. (#9)
    davebyrd authored Apr 28, 2020
    Copy the full SHA
    8b4b76c View commit details

Commits on Jun 16, 2020

  1. Simulation speed improvements (#14)

    * Added tag attribute to Order, LimitOrder, TradingAgent.placeLimitOrder, TradingAgent.placeMarketOrder. (#6)
    
    * bug fixes and enhancements (#7)
    
    * modifications to the subscription API to record the exchange timestamp in the published market data message
    
    * market order changes to account for latency and non-zero jitter
    
    * f string removal from all execution agents
    
    * Mm bugfix and Orderbook efficiency improvements (#13)
    
    * modifications to the subscription API to record the exchange timestamp in the published market data message
    
    * market order changes to account for latency and non-zero jitter
    
    * f string removal from all execution agents
    
    * Custom serialization for order logging and deep copying. (#8)
    
    * Dd serialize orders (#11)
    
    * Custom serialization for order logging and deep copying.
    
    * Orderbook updates (#10)
    
    * Commit makes the following 3 changes to orderbook:
    
      1. Speeds up transacted volume computation
      2. Speeds up conversion of log to DataFrame format
      3. Adds `wide-book` compatibility for `book-freq` != 0
    
    * PR10 fix -- removed redundant print statement
    
    * Order._order_ids uses a set instead of a list to manage order IDs
    
    * Dd orderbook updates (#12)
    
    * Commit makes the following 3 changes to orderbook:
    
      1. Speeds up transacted volume computation
      2. Speeds up conversion of log to DataFrame format
      3. Adds `wide-book` compatibility for `book-freq` != 0
    
    * Custom serialization for order logging and deep copying.
    
    * PR10 fix -- removed redundant print statement
    
    * Order._order_ids uses a set instead of a list to manage order IDs
    
    Co-authored-by: Danial Dervovic <ddervs@googlemail.com>
    Co-authored-by: Mahmoud Mahfouz <mahmoud@mahmouds-mbp.mynet>
    Co-authored-by: David Byrd <davebyrd@users.noreply.github.com>
    4 people committed Jun 16, 2020
    Copy the full SHA
    bb49f41 View commit details
  2. Supporting code for tutorials (#17) and RMSC03 (#16)

    Main components are:
      - ` agent/examples/ExampleExperimentalAgent.py` containing appropriate template files for an algorithmic trading agent.
      - `config/exp_agent_demo.py` config housing this agent for easier usage
      - `scripts/rmsc03_demo.sh` and `scripts/experimental_agent_demo.sh ` with the tutorial commands
      - updates to various pieces of plotting code for fixing compatibility errors
      - Introduces RMSC03 config with supporting agents, a script to search through market maker parameters within the configuration, and a fix to the TradingAgent where cancellations to market orders are ignored.
    
    Co-authored-by: Danial Dervovic <ddervs@googlemail.com>
    ddervs committed Jun 16, 2020
    Copy the full SHA
    803c364 View commit details

Commits on Jul 1, 2020

  1. Copy the full SHA
    3fc4df3 View commit details

Commits on Jul 3, 2020

  1. Copy the full SHA
    742eeb4 View commit details

Commits on Jul 9, 2020

  1. Fix bug in OU process (#19)

    * Fix bug in the OU process.
    
    * fund_vol parameter in configs changed to match corrected formula in SparseMeanRevertingOracle
    
    Co-authored-by: IVANBIJIACHUAN <35773312+IVANBIJIACHUAN@users.noreply.github.com>
    Co-authored-by: Danial Dervovic <ddervs@googlemail.com>
    3 people authored Jul 9, 2020
    Copy the full SHA
    5d343fe View commit details
  2. Agent logging update: (#20)

    Made following changes:
    
      - Added `log_to_file=True` keyword argument to Agent class to allow suppression of logging of
    individual agent events to file for speed reasons.
      - Added log_orders=None option to TradingAgent as a shorthand for
    log_orders=False and log_to_file=False.
      - Updated relevant (tutorial) configs.
    
    Co-authored-by: Danial Dervovic <ddervs@googlemail.com>
    ddervs and ddervs authored Jul 9, 2020
    Copy the full SHA
    7d56876 View commit details
  3. Stylized facts plot update. (#21)

    * Stylized facts plot update.
    
    Following changes:
    
      1. Asset return stylized facts interface is streamlined. Interface for
    preprocessed WRDS data removed and ABIDES interface simplified.
      2. Order flow stylized facts processing bugfixes.
      3. Import code for sim data preprocessing refactored.
      4. Efficiency improvement via fewer disk reads from pandas. 
    
    Co-authored-by: Danial Dervovic <ddervs@googlemail.com>
    ddervs and ddervs authored Jul 9, 2020
    Copy the full SHA
    b7c72b5 View commit details

Commits on Sep 1, 2020

  1. bug fix for latency calculations

    EC2 Default User committed Sep 1, 2020
    Copy the full SHA
    aa1210b View commit details
  2. latency changes in the configs used

    EC2 Default User committed Sep 1, 2020
    Copy the full SHA
    9bbd2af View commit details
  3. latency bug fix

    latency bug fix
    mamahfouz authored Sep 1, 2020
    Copy the full SHA
    ff302ad View commit details

Commits on Sep 23, 2020

  1. Merging on to public master

    davebyrd committed Sep 23, 2020
    Copy the full SHA
    d48da61 View commit details

Commits on Sep 24, 2020

  1. PPFL template

    davebyrd committed Sep 24, 2020
    Copy the full SHA
    7fc36b5 View commit details

Commits on Oct 2, 2020

  1. modified markToMarket bug

    selimamrouni committed Oct 2, 2020
    Copy the full SHA
    09f8434 View commit details
  2. changed return and surplus according to wiki definition

    selimamrouni committed Oct 2, 2020
    Copy the full SHA
    3be15aa View commit details
  3. fixed the if statment that should be in the for loop in the function …

    …computeRequiredPrice
    selimamrouni committed Oct 2, 2020
    Copy the full SHA
    d071919 View commit details
  4. reverse the behavior of the OBI agent to be long when there is a lot …

    …of buyers and to be short when there is a lot of sellers
    selimamrouni committed Oct 2, 2020
    Copy the full SHA
    77459a2 View commit details
  5. markToMarket bug fix in the TradingAgent class

    markToMarket bug fix in the TradingAgent class
    mamahfouz authored Oct 2, 2020
    Copy the full SHA
    64f668e View commit details

Commits on Oct 15, 2020

  1. Copy the full SHA
    f4ffa78 View commit details

Commits on Oct 16, 2020

  1. Bugfix obi agent

    Bugfix obi agent
    mamahfouz authored Oct 16, 2020
    Copy the full SHA
    2959adf View commit details
  2. changed return and surplus according to wiki definition

    changed return and surplus according to wiki definition
    mamahfouz authored Oct 16, 2020
    Copy the full SHA
    2bd3559 View commit details

Commits on Oct 20, 2020

  1. merge dev into master

    3fc4df3 Fix pandas version in requirements file and uncomment commands in RMSC tutorial script.
    5d343fe Fix issue found by @IVANBIJIACHUAN in OU process for util/oracle/SparseMeanRevertingOracle.py (see PR #19 )
    7d56876 An update to TradingAgent logging to allow for minimal logging (see PR #20 )
    b7c72b5 An update to stylized fact plots fixing some issues (see PR #21 for details)
    mamahfouz authored Oct 20, 2020
    Copy the full SHA
    f81f2b4 View commit details

Commits on Nov 16, 2020

  1. log_to_file changes for base agents

    EC2 Default User committed Nov 16, 2020
    Copy the full SHA
    cd02075 View commit details
  2. baseline execution agent refactoring and bug fixes

    EC2 Default User committed Nov 16, 2020
    Copy the full SHA
    025b4b2 View commit details

Commits on Nov 19, 2020

  1. bug fixes for execution agents

    bug fixes for execution agents
    mamahfouz authored Nov 19, 2020
    Copy the full SHA
    c4bf157 View commit details
Showing with 4,408 additions and 1,345 deletions.
  1. +3 −1 .gitignore
  2. +31 −5 Kernel.py
  3. +12 −4 agent/Agent.py
  4. +27 −26 agent/ExchangeAgent.py
  5. +2 −2 agent/FinancialAgent.py
  6. +4 −2 agent/NoiseAgent.py
  7. +6 −5 agent/OrderBookImbalanceAgent.py
  8. +54 −54 agent/TradingAgent.py
  9. +3 −2 agent/ValueAgent.py
  10. +146 −0 agent/examples/ExampleExperimentalAgent.py
  11. +2 −2 agent/examples/QLearningAgent.py
  12. +11 −6 agent/examples/SubscriptionAgent.py
  13. +380 −0 agent/examples/crypto/PPFL_ClientAgent.py
  14. +155 −0 agent/examples/crypto/PPFL_ServiceAgent.py
  15. +311 −0 agent/examples/crypto/PPFL_TemplateClientAgent.py
  16. +0 −39 agent/execution/AggressiveAgent.py
  17. +19 −12 agent/execution/ExecutionAgent.py
  18. +4 −3 agent/execution/POVExecutionAgent.py
  19. +0 −51 agent/execution/PassiveAgent.py
  20. +3 −3 agent/execution/TWAPExecutionAgent.py
  21. +4 −4 agent/execution/VWAPExecutionAgent.py
  22. +0 −154 agent/execution/util.py
  23. +290 −0 agent/market_makers/AdaptiveMarketMakerAgent.py
  24. +2 −2 agent/market_makers/POVMarketMakerAgent.py
  25. +24 −24 cli/read_agent_logs.py
  26. +158 −114 config/{execution_iabs_plots.py → execution.py}
  27. +0 −255 config/execution_iabs.py
  28. +0 −193 config/execution_marketreplay.py
  29. +341 −0 config/exp_agent_demo.py
  30. +29 −11 config/hist_fund_diverse.py
  31. +29 −11 config/hist_fund_value.py
  32. +2 −4 config/loop_obi.py
  33. +1 −1 config/obi_rmsc02.py
  34. +281 −0 config/ppfl_icaif20.py
  35. +287 −0 config/ppfl_template.py
  36. +5 −4 config/qlearning.py
  37. +31 −12 config/random_fund_diverse.py
  38. +29 −11 config/random_fund_value.py
  39. +30 −10 config/rmsc01.py
  40. +30 −10 config/rmsc02.py
  41. +372 −0 config/rmsc03.py
  42. +1 −1 config/sparse_zi_100.py
  43. +1 −1 config/sparse_zi_1000.py
  44. +1 −1 config/value_noise.py
  45. BIN data/synthetic_fundamental.bz2
  46. +8 −3 model/LatencyModel.py
  47. +44 −57 realism/asset_returns_stylized_facts.py
  48. +27 −14 realism/impact_multiday_pov.py
  49. +35 −23 realism/impact_single_day_pov.py
  50. +110 −0 realism/market_impact/abm_market_impact.py
  51. +128 −0 realism/market_impact/marketreplay_market_impact.py
  52. +2 −2 realism/metrics/aggregation_normality.py
  53. +4 −6 realism/metrics/autocorrelation.py
  54. +3 −2 realism/metrics/kurtosis.py
  55. +11 −28 realism/metrics/metric.py
  56. +3 −2 realism/metrics/minutely_returns.py
  57. +3 −2 realism/metrics/returns_volatility_correlation.py
  58. +4 −4 realism/metrics/volatility_clustering.py
  59. +3 −2 realism/metrics/volume_volatility_correlation.py
  60. +14 −2 realism/order_flow_stylized_facts.py
  61. +36 −0 realism/plot_configs/plot_configs/multiday/rmsc03_demo_multiday.json
  62. +55 −0 realism/plot_configs/plot_configs/single_day/rmsc03_demo_single_day.json
  63. +12 −8 realism/realism_utils.py
  64. +1 −1 requirements.txt
  65. +14 −0 scripts/execution.sh
  66. +0 −30 scripts/execution_iabs.sh
  67. +0 −21 scripts/execution_marketreplay.sh
  68. +18 −0 scripts/experimental_agent_demo.sh
  69. +111 −0 scripts/market_maker/adaptive_mm_search.sh
  70. +22 −0 scripts/market_maker/params/mm_search_params.example.sh
  71. +28 −0 scripts/rmsc03_demo.sh
  72. +131 −23 util/OrderBook.py
  73. +60 −0 util/crypto/diffieHellman.py
  74. +101 −0 util/crypto/logReg.py
  75. +7 −1 util/formatting/convert_order_book.py
  76. +8 −4 util/formatting/convert_order_stream.py
  77. +8 −2 util/formatting/mid_price_from_orderbook.py
  78. +2 −2 util/formatting/prepare_abides_data_for_plotting.py
  79. +1 −1 util/formatting/prepare_dow_data_for_plotting.py
  80. +3 −2 util/oracle/SparseMeanRevertingOracle.py
  81. +52 −19 util/order/LimitOrder.py
  82. +50 −0 util/order/MarketOrder.py
  83. +48 −27 util/order/Order.py
  84. +10 −0 util/plotting/configs/plot_09.30_11.30.json
  85. +55 −17 util/plotting/liquidity_telemetry.py
  86. +55 −0 util/util.py
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -5,7 +5,9 @@ cache/
local/
log/
.idea/
results/
util/crypto/datasets
venv/
.idea/
.ipynb/
.ipynb_checkpoints/
.ipynb_checkpoints/
36 changes: 31 additions & 5 deletions Kernel.py
Original file line number Diff line number Diff line change
@@ -51,13 +51,19 @@ def __init__(self, kernel_name, random_state = None):
def runner(self, agents = [], startTime = None, stopTime = None,
num_simulations = 1, defaultComputationDelay = 1,
defaultLatency = 1, agentLatency = None, latencyNoise = [ 1.0 ],
agentLatencyModel = None,
agentLatencyModel = None, skip_log = False,
seed = None, oracle = None, log_dir = None):

# agents must be a list of agents for the simulation,
# based on class agent.Agent
self.agents = agents
self.agent_saved_states = [None] * len(self.agents)

# Simulation custom state in a freeform dictionary. Allows config files
# that drive multiple simulations, or require the ability to generate
# special logs after simulation, to obtain needed output without special
# case code in the Kernel. Per-agent state should be handled using the
# provided updateAgentState() method.
self.custom_state = {}

# The kernel start and stop time (first and last timestamp in
# the simulation, separate from anything like exchange open/close).
@@ -67,6 +73,9 @@ def runner(self, agents = [], startTime = None, stopTime = None,
# The global seed, NOT used for anything agent-related.
self.seed = seed

# Should the Kernel skip writing agent logs?
self.skip_log = skip_log

# The data oracle for this simulation, if needed.
self.oracle = oracle

@@ -293,6 +302,12 @@ def runner(self, agents = [], startTime = None, stopTime = None,
ttl_messages / (eventQueueWallClockElapsed / (np.timedelta64(1, 's')))))
log_print ("Ending sim {}", sim)


# The Kernel adds a handful of custom state results for all simulations,
# which configurations may use, print, log, or discard.
self.custom_state['kernel_event_queue_elapsed_wallclock'] = eventQueueWallClockElapsed
self.custom_state['kernel_slowest_agent_finish_time'] = max(self.agentCurrentTimes)

# Agents will request the Kernel to serialize their agent logs, usually
# during kernelTerminating, but the Kernel must write out the summary
# log itself.
@@ -308,7 +323,7 @@ def runner(self, agents = [], startTime = None, stopTime = None,

print ("Simulation ending!")

return self.agent_saved_states
return self.custom_state


def sendMessage(self, sender = None, recipient = None, msg = None, delay = 0):
@@ -482,6 +497,8 @@ def writeLog (self, sender, dfLog, filename=None):
# the Kernel will construct a filename based on the name of the Agent
# requesting log archival.

if self.skip_log: return

path = os.path.join(".", "log", self.log_dir)

if filename:
@@ -515,8 +532,17 @@ def writeSummaryLog (self):
dfLog.to_pickle(os.path.join(path, file), compression='bz2')


def saveState (self, agent_id, state):
self.agent_saved_states[agent_id] = state
def updateAgentState (self, agent_id, state):
""" Called by an agent that wishes to replace its custom state in the dictionary
the Kernel will return at the end of simulation. Shared state must be set directly,
and agents should coordinate that non-destructively.
Note that it is never necessary to use this kernel state dictionary for an agent
to remember information about itself, only to report it back to the config file.
"""

if 'agent_state' not in self.custom_state: self.custom_state['agent_state'] = {}
self.custom_state['agent_state'][agent_id] = state


@staticmethod
16 changes: 12 additions & 4 deletions agent/Agent.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

class Agent:

def __init__ (self, id, name, type, random_state):
def __init__ (self, id, name, type, random_state, log_to_file=True):

# ID must be a unique number (usually autoincremented).
# Name is for human consumption, should be unique (often type + number).
@@ -16,6 +16,7 @@ def __init__ (self, id, name, type, random_state):
self.id = id
self.name = name
self.type = type
self.log_to_file = log_to_file
self.random_state = random_state

if not random_state:
@@ -89,7 +90,7 @@ def kernelTerminating (self):

# If this agent has been maintaining a log, convert it to a Dataframe
# and request that the Kernel write it to disk before terminating.
if self.log:
if self.log and self.log_to_file:
dfLog = pd.DataFrame(self.log)
dfLog.set_index('EventTime', inplace=True)
self.writeLog(dfLog)
@@ -164,8 +165,15 @@ def delay (self, additionalDelay):
def writeLog (self, dfLog, filename=None):
self.kernel.writeLog(self.id, dfLog, filename)

def saveState (self, state):
self.kernel.saveState(self.id, state)
def updateAgentState (self, state):
""" Agents should use this method to replace their custom state in the dictionary
the Kernel will return to the experimental config file at the end of the
simulation. This is intended to be write-only, and agents should not use
it to store information for their own later use.
"""

self.kernel.updateAgentState(self.id, state)


### Internal methods that should not be modified without a very good reason.

53 changes: 27 additions & 26 deletions agent/ExchangeAgent.py
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
warnings.simplefilter(action='ignore', category=FutureWarning)
warnings.simplefilter(action='ignore', category=UserWarning)

import jsons as js
import pandas as pd
pd.set_option('display.max_rows', 500)

@@ -62,7 +61,6 @@ def __init__(self, id, name, type, mkt_open, mkt_close, symbols, book_freq='S',

# Store orderbook in wide format? ONLY WORKS with book_freq == 0
self.wide_book = wide_book
self.wide_book_warning()

# The subscription dict is a dictionary with the key = agent ID,
# value = dict (key = symbol, value = list [levels (no of levels to recieve updates for),
@@ -128,7 +126,7 @@ def receiveMessage(self, currentTime, msg):
if currentTime > self.mkt_close:
# Most messages after close will receive a 'MKT_CLOSED' message in response. A few things
# might still be processed, like requests for final trade prices or such.
if msg.body['msg'] in ['LIMIT_ORDER', 'CANCEL_ORDER', 'MODIFY_ORDER']:
if msg.body['msg'] in ['LIMIT_ORDER', 'MARKET_ORDER', 'CANCEL_ORDER', 'MODIFY_ORDER']:
log_print("{} received {}: {}", self.name, msg.body['msg'], msg.body['order'])
self.sendMessage(msg.body['sender'], Message({"msg": "MKT_CLOSED"}))

@@ -146,8 +144,8 @@ def receiveMessage(self, currentTime, msg):
return

# Log order messages only if that option is configured. Log all other messages.
if msg.body['msg'] in ['LIMIT_ORDER', 'CANCEL_ORDER']:
if self.log_orders: self.logEvent(msg.body['msg'], js.dump(msg.body['order'], strip_privates=True))
if msg.body['msg'] in ['LIMIT_ORDER', 'MARKET_ORDER', 'CANCEL_ORDER', 'MODIFY_ORDER']:
if self.log_orders: self.logEvent(msg.body['msg'], msg.body['order'].to_dict())
else:
self.logEvent(msg.body['msg'], msg.body['sender'])

@@ -241,11 +239,20 @@ def receiveMessage(self, currentTime, msg):
order = msg.body['order']
log_print("{} received LIMIT_ORDER: {}", self.name, order)
if order.symbol not in self.order_books:
log_print("Order discarded. Unknown symbol: {}", order.symbol)
log_print("Limit Order discarded. Unknown symbol: {}", order.symbol)
else:
# Hand the order to the order book for processing.
self.order_books[order.symbol].handleLimitOrder(deepcopy(order))
self.publishOrderBookData()
elif msg.body['msg'] == "MARKET_ORDER":
order = msg.body['order']
log_print("{} received MARKET_ORDER: {}", self.name, order)
if order.symbol not in self.order_books:
log_print("Market Order discarded. Unknown symbol: {}", order.symbol)
else:
# Hand the market order to the order book for processing.
self.order_books[order.symbol].handleMarketOrder(deepcopy(order))
self.publishOrderBookData()
elif msg.body['msg'] == "CANCEL_ORDER":
# Note: this is somewhat open to abuse, as in theory agents could cancel other agents' orders.
# An agent could also become confused if they receive a (partial) execution on an order they
@@ -305,7 +312,8 @@ def publishOrderBookData(self):
"symbol": symbol,
"bids": self.order_books[symbol].getInsideBids(levels),
"asks": self.order_books[symbol].getInsideAsks(levels),
"last_transaction": self.order_books[symbol].last_trade}))
"last_transaction": self.order_books[symbol].last_trade,
"exchange_ts": self.currentTime}))
self.subscription_dict[agent_id][symbol][2] = orderbook_last_update

def logOrderBookSnapshots(self, symbol):
@@ -330,15 +338,12 @@ def get_quote_range_iterator(s):
if book.book_log:

print("Logging order book to file...")
dfLog = pd.DataFrame(book.book_log)
dfLog = book.book_log_to_df()
dfLog.set_index('QuoteTime', inplace=True)
dfLog = dfLog[~dfLog.index.duplicated(keep='last')]
dfLog.sort_index(inplace=True)

if str(self.book_freq).isdigit() and int(self.book_freq) == 0: # Save all possible information
# With all order snapshots saved DataFrame is very sparse
dfLog = pd.SparseDataFrame(dfLog)

# Get the full range of quotes at the finest possible resolution.
quotes = get_quote_range_iterator(dfLog.columns.unique())

@@ -361,16 +366,18 @@ def get_quote_range_iterator(s):
time_idx = pd.date_range(self.mkt_open, self.mkt_close, freq=self.book_freq, closed='right')
dfLog = dfLog.reindex(time_idx, method='ffill')
dfLog.sort_index(inplace=True)
dfLog = dfLog.stack()
dfLog.sort_index(inplace=True)

# Get the full range of quotes at the finest possible resolution.
quotes = get_quote_range_iterator(dfLog.index.get_level_values(1).unique())
if not self.wide_book:
dfLog = dfLog.stack()
dfLog.sort_index(inplace=True)

# Restructure the log to have multi-level rows of all possible pairs of time and quote
# with volume as the only column.
filledIndex = pd.MultiIndex.from_product([time_idx, quotes], names=['time', 'quote'])
dfLog = dfLog.reindex(filledIndex)
# Get the full range of quotes at the finest possible resolution.
quotes = get_quote_range_iterator(dfLog.index.get_level_values(1).unique())

# Restructure the log to have multi-level rows of all possible pairs of time and quote
# with volume as the only column.
filledIndex = pd.MultiIndex.from_product([time_idx, quotes], names=['time', 'quote'])
dfLog = dfLog.reindex(filledIndex)

filename = f'ORDERBOOK_{symbol}_FREQ_{self.book_freq}'

@@ -398,7 +405,7 @@ def sendMessage (self, recipientID, msg):
# Messages that require order book modification (not simple queries) incur the additional
# parallel processing delay as configured.
super().sendMessage(recipientID, msg, delay = self.pipeline_delay)
if self.log_orders: self.logEvent(msg.body['msg'], js.dump(msg.body['order'], strip_privates=True))
if self.log_orders: self.logEvent(msg.body['msg'], msg.body['order'].to_dict())
else:
# Other message types incur only the currently-configured computation delay for this agent.
super().sendMessage(recipientID, msg)
@@ -409,9 +416,3 @@ def getMarketOpen(self):

def getMarketClose(self):
return self.__mkt_close

def wide_book_warning(self):
""" Prints warning message about wide orderbook format usage. """
if self.wide_book and (self.book_freq != 0):
log_print(f"WARNING: (wide_book == True) and (book_freq != 0). Orderbook will be logged in column MultiIndex "
"format at frequency {self.book_freq}.")
4 changes: 2 additions & 2 deletions agent/FinancialAgent.py
Original file line number Diff line number Diff line change
@@ -10,9 +10,9 @@
# exchanges to make this more useful later on.
class FinancialAgent(Agent):

def __init__(self, id, name, type, random_state):
def __init__(self, id, name, type, random_state, log_to_file=True):
# Base class init.
super().__init__(id, name, type, random_state)
super().__init__(id, name, type, random_state, log_to_file)

# Used by any subclass to dollarize an int-cents price for printing.
def dollarize (self, cents):
6 changes: 4 additions & 2 deletions agent/NoiseAgent.py
Original file line number Diff line number Diff line change
@@ -8,10 +8,12 @@

class NoiseAgent(TradingAgent):

def __init__(self, id, name, type, symbol='IBM', starting_cash=100000, log_orders=False, random_state=None, wakeup_time = None ):
def __init__(self, id, name, type, symbol='IBM', starting_cash=100000,
log_orders=False, log_to_file=True, random_state=None, wakeup_time = None ):

# Base class init.
super().__init__(id, name, type, starting_cash=starting_cash, log_orders=log_orders, random_state=random_state)
super().__init__(id, name, type, starting_cash=starting_cash, log_orders=log_orders,
log_to_file=log_to_file, random_state=random_state)

self.wakeup_time = wakeup_time,

11 changes: 6 additions & 5 deletions agent/OrderBookImbalanceAgent.py
Original file line number Diff line number Diff line change
@@ -110,13 +110,13 @@ def receiveMessage(self, currentTime, msg):
target = 100
# If we are flat, we need to decide if we should enter (long or short).
else:
if bid_pct < (0.5 - self.entry_threshold):
if bid_pct > (0.5 + self.entry_threshold):
log_print("OBI agent entering long position: bid_pct < entry_threshold ({:2f} < {:2f})", bid_pct, 0.5 - self.entry_threshold)
target = 100
self.is_long = True
self.trailing_stop = bid_pct + self.trail_dist
log_print("Initial trailing stop: {:2f}", self.trailing_stop)
elif bid_pct > (0.5 + self.entry_threshold):
elif bid_pct < (0.5 - self.entry_threshold):
log_print("OBI agent entering short position: bid_pct > entry_threshold ({:2f} > {:2f})", bid_pct, 0.5 + self.entry_threshold)
target = -100
self.is_short = True
@@ -158,11 +158,12 @@ def computeRequiredPrice (self, direction, shares, known_bids, known_asks):
t = 0

for i in range(len(book)):
p,v = book[i]
p, v = book[i]
t += v

# If we have accumulated enough shares, return this price.
if t >= shares: return p
# If we have accumulated enough shares, return this price.
if t >= shares:
return p

# Not enough shares. Just return worst price (highest ask, lowest bid).
return book[-1][0]
Loading