Skip to content

Commit

Permalink
Merge pull request #111 from AsyncAlgoTrading/cancel_order
Browse files Browse the repository at this point in the history
adding ib position query
  • Loading branch information
timkpaine committed Oct 2, 2020
2 parents 8806066 + 11c9879 commit 11e9502
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ iexlive: ## Clean and make target, run target
ib: ## Clean and make target, run target
$(PYTHON) -m aat --config ./config/ib.cfg

ibpositions: ## Clean and make target, run target
$(PYTHON) -m aat --config ./config/ib_positions.cfg

coinbasesandbox: ## Clean and make target, run target
$(PYTHON) -m aat --config ./config/coinbase_sandbox.cfg

Expand Down
40 changes: 36 additions & 4 deletions aat/exchange/public/ib/ib.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import asyncio
import threading
from datetime import datetime
from queue import Queue
from random import randint

from ibapi.client import EClient # type: ignore
from ibapi.wrapper import EWrapper # type: ignore
from ibapi.contract import Contract # type: ignore

from aat.exchange import Exchange
from aat.config import EventType, TradingType, Side
from aat.core import ExchangeType, Event, Trade, Order
from aat.core import ExchangeType, Event, Trade, Order, Position

from .utils import _constructContract, _constructContractAndOrder, _constructInstrument


class _API(EWrapper, EClient):
def __init__(self, account, delayed, order_event_queue, market_data_queue, contract_info_queue):
def __init__(self, account, exchange, delayed, order_event_queue, market_data_queue, contract_info_queue, account_position_queue):
EClient.__init__(self, self)
self.nextOrderId = None
self.nextReqId = 1

# account # if more than one
self._account = account

# exchange
self._exchange = exchange

# delayed data?
self._delayed = delayed

Expand All @@ -31,6 +36,12 @@ def __init__(self, account, delayed, order_event_queue, market_data_queue, contr
self._order_event_queue = order_event_queue
self._market_data_queue = market_data_queue
self._contract_info_queue = contract_info_queue
self._account_position_queue = account_position_queue

self._positions = []

def reqPositions(self):
super().reqPositions()

def nextValidId(self, orderId: int):
super().nextValidId(orderId)
Expand Down Expand Up @@ -94,6 +105,19 @@ def tickPrice(self, reqId, tickType, price, attrib):
price=price
))

def position(self, account: str, contract: Contract, position: float, avgCost: float):
super().position(account, contract, position, avgCost)
self._positions.append(Position(size=position,
price=avgCost / position,
timestamp=datetime.now(),
instrument=_constructInstrument(contract),
exchange=self._exchange,
trades=[]))

def accountSummaryEnd(self, reqId):
self._account_position_queue.put(self._positions)
self._positions = []


class InteractiveBrokersExchange(Exchange):
'''Interactive Brokers Exchange'''
Expand All @@ -114,7 +138,8 @@ def __init__(self, trading_type, verbose, account='', delayed=True, **kwargs):
self._order_event_queue = Queue()
self._market_data_queue = Queue()
self._contract_lookup_queue = Queue()
self._api = _API(account, delayed, self._order_event_queue, self._market_data_queue, self._contract_lookup_queue)
self._account_position_queue = Queue()
self._api = _API(account, self.exchange(), delayed, self._order_event_queue, self._market_data_queue, self._contract_lookup_queue, self._account_position_queue)

# *************** #
# General methods #
Expand Down Expand Up @@ -223,7 +248,14 @@ async def tick(self):
# ******************* #
async def accounts(self):
'''get accounts from source'''
return []
self._api.reqPositions()
i = 0
while i < 5:
if self._account_position_queue.qsize() > 0:
return self._account_position_queue.get()
else:
await asyncio.sleep(1)
i += 1

async def newOrder(self, order):
'''submit a new order to the exchange. should set the given order's `id` field to exchange-assigned id
Expand Down
2 changes: 2 additions & 0 deletions aat/strategy/sample/readonly.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def __init__(self, *args, **kwargs) -> None:

async def onStart(self, event: Event) -> None:
pprint(self.instruments())
pprint(self.positions())

async def onTrade(self, event: Event) -> None:
pprint(event)
Expand All @@ -24,6 +25,7 @@ async def onExit(self, event: Event) -> None:
if __name__ == "__main__":
from aat import TradingEngine, parseConfig
cfg = parseConfig(['--trading_type', 'backtest',
'--load_accounts',
'--exchanges', 'aat.exchange.generic:CSV,{}'.format(os.path.join(os.path.dirname(__file__), 'data', 'aapl.csv')),
'--strategies', 'aat.strategy.sample.readonly:ReadOnlyStrategy'
])
Expand Down
12 changes: 12 additions & 0 deletions config/ib_positions.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[general]
verbose=0
trading_type=sandbox
load_accounts=1

[exchange]
exchanges=
aat.exchange.public.ib:InteractiveBrokersExchange

[strategy]
strategies =
aat.strategy.sample.readonly:ReadOnlyStrategy

0 comments on commit 11e9502

Please sign in to comment.