modifyOrder changing status from Suspended to Working

Hello, I’m trying to update a stop loss / take profit on an order strategy placed with startOrderStrategy. I’ve been able to identify the OrderId for the Limit and Stop orders separately but I’m unable to use the modifyOrder endpoint without the order status changing from Suspended to Working. Would really appreciate some insight into the matter.

	orderstrategies, err := tv.GetOrderStrategyList()
	if err != nil {
		log.Error("failed to get order strategy list", "error", err)
		return
	}

	// Find the order strategy that has "ActiveStrategy" for status
	var activeOrderStrategyId int
	for _, orderstrategy := range orderstrategies {
		log.Debug("Order strategy", "orderstrategy", orderstrategy)
		if orderstrategy.Status == "ActiveStrategy" {
			activeOrderStrategyId = orderstrategy.Id
			log.Debug("Active order strategy", "orderstrategy", orderstrategy)
			break
		}
	}
	log.Debug("Active order strategy", "orderstrategy", activeOrderStrategyId)

	// Get the dependencies of the existing strategy
	deps, err := tv.GetOrderStrategyLinkDeps(int64(activeOrderStrategyId))
	if err != nil {
		log.Error("failed to get order strategy link deps", "error", err)
		return
	}

	orderVersionMap := make(map[int]orders.OrderVersion)
	for _, dep := range deps {
		orderVersionItem, err := tv.GetOrderVersionItem(int64(dep.OrderId))
		if err != nil {
			log.Error("failed to get order version item", "error", err)
			return
		}
		orderVersionMap[dep.Id] = orderVersionItem
	}
	log.Debug("deps map", "map", orderVersionMap)

	// get a list of ids from the map keys
	var depIds []int64
	for k := range orderVersionMap {
		depIds = append(depIds, int64(k))
	}

	// Get the status of each order by using get order items (to get the order status)
	tvOrders, err := tv.GetOrders(depIds)
	if err != nil {
		log.Error("failed to get orders", "error", err)
		return
	}

	// Sort the orders by id
	sort.Slice(tvOrders, func(i, j int) bool {
		return tvOrders[i].Id < tvOrders[j].Id
	})
	log.Debug("sorted tv orders", "orders", tvOrders[0])

	if tvOrders[0].OrdStatus == "Filled" {
		log.Debug("Main order is filled", "order", tvOrders[0])
	} else {
		log.Debug("Main order is not filled", "order", tvOrders[0])
	}

	// Identify the Stop and Limit orders
	var stopOrder orders.OrderVersion
	var limitOrder orders.OrderVersion

	for _, order := range orderVersionMap {
		if order.OrderId == tvOrders[0].Id {
			log.Debug("Main order", "order", order)
			continue
		}
		switch order.OrderType {
		case "Stop":
			stopOrder = order
		case "Limit":
			limitOrder = order
		}
	}

	// Modify the Limit order
	_, err = tv.ModifyOrder(orders.ModifyOrderRequest{
		OrderId:     limitOrder.OrderId,
		OrderType:   "Limit",
		TimeInForce: "Day",
		Price:       5800.00,
		Text:        "Ticket",
	})
	if err != nil {
		log.Error("failed to modify order", "error", err)
		return
	}

	// Modify the Stop order
	_, err = tv.ModifyOrder(orders.ModifyOrderRequest{
		OrderId:     stopOrder.OrderId,
		OrderType:   "Stop",
		TimeInForce: "Day",
		StopPrice:   5730.00,
		Text:        "Ticket",
	})

And the value being sent in the modifyOrder request:

{"orderId":74059648460,"orderQty":1,"orderType":"Limit","price":5800,"expireTime":"2024-09-26T17:00:00-04:00","activationTime":"2024-09-26T13:52:50.593825-04:00"}

Why do you use an activationTime? You may want to get rid of that.

Also you should be using userSync to get updates on orders and not poll it for updates. This will give you realtime changes.

When you modify a stop loss or take profit, it goes through multiple state changes and should end in “Working” state while it is waiting to be Filled.

Thanks for the reply. Removing the activationTime did resolve the issue (activationTime apparently refers to when the state should change to Working no matter what, as you clearly already know).

When I initially built this out, websockets were not an option due to the environment. That has since changed and will be going down that road when there is time to refactor.

1 Like