2022-10-17 06:20:30 +00:00
|
|
|
# Trade handling
|
2022-10-27 17:08:40 +00:00
|
|
|
from alpaca.common.exceptions import APIError
|
|
|
|
from alpaca.trading.enums import OrderSide, TimeInForce
|
|
|
|
from alpaca.trading.requests import LimitOrderRequest, MarketOrderRequest
|
|
|
|
|
|
|
|
from core.util import logs
|
|
|
|
|
|
|
|
log = logs.get_logger(__name__)
|
2022-10-17 06:20:30 +00:00
|
|
|
|
2022-10-21 23:15:27 +00:00
|
|
|
|
2022-10-17 06:20:30 +00:00
|
|
|
def sync_trades_with_db(user):
|
|
|
|
pass
|
2022-10-27 17:08:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
def post_trade(trade):
|
|
|
|
# the trade is not placed yet
|
|
|
|
trading_client = trade.account.get_client()
|
|
|
|
if trade.direction == "buy":
|
|
|
|
direction = OrderSide.BUY
|
|
|
|
elif trade.direction == "sell":
|
|
|
|
direction = OrderSide.SELL
|
|
|
|
else:
|
|
|
|
raise Exception("Unknown direction")
|
|
|
|
|
|
|
|
cast = {"symbol": trade.symbol, "side": direction, "time_in_force": TimeInForce.IOC}
|
|
|
|
if trade.amount is not None:
|
|
|
|
cast["qty"] = trade.amount
|
|
|
|
if trade.amount_usd is not None:
|
|
|
|
cast["notional"] = trade.amount_usd
|
|
|
|
if not trade.amount and not trade.amount_usd:
|
|
|
|
return (False, "No amount specified")
|
|
|
|
if trade.take_profit:
|
|
|
|
cast["take_profit"] = {"limit_price": trade.take_profit}
|
|
|
|
if trade.stop_loss:
|
|
|
|
stop_limit_price = trade.stop_loss - (trade.stop_loss * 0.005)
|
|
|
|
cast["stop_loss"] = {
|
|
|
|
"stop_price": trade.stop_loss,
|
|
|
|
"limit_price": stop_limit_price,
|
|
|
|
}
|
|
|
|
if trade.type == "market":
|
|
|
|
market_order_data = MarketOrderRequest(**cast)
|
|
|
|
try:
|
|
|
|
order = trading_client.submit_order(order_data=market_order_data)
|
|
|
|
except APIError as e:
|
|
|
|
log.error(f"Error placing market order: {e}")
|
|
|
|
return (False, e)
|
|
|
|
elif trade.type == "limit":
|
|
|
|
if not trade.price:
|
|
|
|
return (False, "Limit order with no price")
|
|
|
|
cast["limit_price"] = trade.price
|
|
|
|
limit_order_data = LimitOrderRequest(**cast)
|
|
|
|
try:
|
|
|
|
order = trading_client.submit_order(order_data=limit_order_data)
|
|
|
|
except APIError as e:
|
|
|
|
log.error(f"Error placing limit order: {e}")
|
|
|
|
return (False, e)
|
|
|
|
|
|
|
|
else:
|
|
|
|
raise Exception("Unknown trade type")
|
|
|
|
trade.response = order
|
|
|
|
trade.status = "posted"
|
|
|
|
trade.order_id = order["id"]
|
|
|
|
trade.client_order_id = order["client_order_id"]
|
|
|
|
trade.save()
|
|
|
|
return (True, order)
|
|
|
|
|
|
|
|
|
|
|
|
def update_trade(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def close_trade(trade):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def get_position_info(account, asset_id):
|
|
|
|
trading_client = account.get_client()
|
|
|
|
try:
|
|
|
|
position = trading_client.get_open_position(asset_id)
|
|
|
|
except APIError as e:
|
|
|
|
return (False, e)
|
|
|
|
return (True, position)
|