Implement order processor
Basic function that allows to place the order and persist it in the database
This commit is contained in:
parent
a33a60b879
commit
50730110cf
33
app/order_processor.py
Normal file
33
app/order_processor.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
import app.database as database
|
||||||
|
import app.stock_exchange as stock_exchange
|
||||||
|
from app.types import Order
|
||||||
|
|
||||||
|
|
||||||
|
class FailedToProcessOrderError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def process_order(db_connection, order_request, place_order=stock_exchange.place_order):
|
||||||
|
order = Order(
|
||||||
|
id="-1",
|
||||||
|
created_at=datetime.now(),
|
||||||
|
side=order_request.side,
|
||||||
|
type=order_request.type_,
|
||||||
|
instrument=order_request.instrument,
|
||||||
|
limit_price=order_request.limit_price,
|
||||||
|
quantity=order_request.quantity,
|
||||||
|
)
|
||||||
|
|
||||||
|
order = database.insert_order(db_connection, order)
|
||||||
|
try:
|
||||||
|
place_order(order)
|
||||||
|
database.mark_order_as(db_connection, order.id_, "placed")
|
||||||
|
except stock_exchange.OrderPlacementError:
|
||||||
|
database.mark_order_as(db_connection, order.id_, "failed")
|
||||||
|
raise FailedToProcessOrderError(order)
|
||||||
|
finally:
|
||||||
|
db_connection.commit()
|
||||||
|
|
||||||
|
return order
|
62
tests/order_processor_test.py
Normal file
62
tests/order_processor_test.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import app.stock_exchange as stock_exchange
|
||||||
|
from app.api import CreateOrderModel
|
||||||
|
from app.order_processor import FailedToProcessOrderError, process_order
|
||||||
|
from app.types import OrderSide, OrderType
|
||||||
|
|
||||||
|
|
||||||
|
def successful_place_order(_order):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_placing_an_order(db_connection):
|
||||||
|
order_request = CreateOrderModel(
|
||||||
|
type=OrderType.LIMIT,
|
||||||
|
side=OrderSide.BUY,
|
||||||
|
instrument="123456789123",
|
||||||
|
limit_price="12.00",
|
||||||
|
quantity=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
order_count_before = db_connection.execute(
|
||||||
|
"SELECT COUNT(*) from orders"
|
||||||
|
).fetchone()[0]
|
||||||
|
order = process_order(
|
||||||
|
db_connection, order_request, place_order=successful_place_order
|
||||||
|
)
|
||||||
|
order_count_after = db_connection.execute(
|
||||||
|
"SELECT COUNT(*) from orders where status = 'placed'"
|
||||||
|
).fetchone()[0]
|
||||||
|
|
||||||
|
assert order_count_after - order_count_before == 1
|
||||||
|
assert order.id_ is not None
|
||||||
|
|
||||||
|
|
||||||
|
def failing_place_order(_order):
|
||||||
|
raise stock_exchange.OrderPlacementError()
|
||||||
|
|
||||||
|
|
||||||
|
def test_placing_an_order_that_fails(db_connection):
|
||||||
|
order_request = CreateOrderModel(
|
||||||
|
type=OrderType.LIMIT,
|
||||||
|
side=OrderSide.BUY,
|
||||||
|
instrument="123456789123",
|
||||||
|
limit_price="12.00",
|
||||||
|
quantity=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
order_count_before = db_connection.execute(
|
||||||
|
"SELECT COUNT(*) from orders"
|
||||||
|
).fetchone()[0]
|
||||||
|
order = None
|
||||||
|
try:
|
||||||
|
order = process_order(
|
||||||
|
db_connection, order_request, place_order=failing_place_order
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
assert type(e) is FailedToProcessOrderError
|
||||||
|
|
||||||
|
order_count_after = db_connection.execute(
|
||||||
|
"SELECT COUNT(*) from orders where status = 'failed'"
|
||||||
|
).fetchone()[0]
|
||||||
|
|
||||||
|
assert order_count_after - order_count_before == 1
|
Loading…
x
Reference in New Issue
Block a user