fisk/core/lib/trades.py

83 lines
2.4 KiB
Python

# Trade handling
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__)
def sync_trades_with_db(user):
pass
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, symbol):
trading_client = account.get_client()
try:
position = trading_client.get_open_position(symbol)
except APIError as e:
return (False, e)
return (True, position)