dougdellolio / coinbasepro-csharp

The unofficial .NET/C# client library for the Coinbase Pro/GDAX API
MIT License
192 stars 90 forks source link

Example for automatically sending sell order after filled buy order #263

Closed jamesboyer closed 3 years ago

jamesboyer commented 3 years ago

I was wondering what would be the recommended way to send a limit sell order after placing and filling a buy order. I have similar to the following, however I never get a Done matching my buyId so I can place a sell limit order. Is there a different web socket event I should be listening to?

var authenticator = new Authenticator(GetApiKey(), GetApiSecret(), GetPassphrase());
var coinbaseConnection = new CoinbasePro.CoinbaseProClient(authenticator);

var buyId = Guid.NewGuid();
void WebSocket_OnDoneReceived(object sender, WebfeedEventArgs<Done> e)
{
    if (!e.LastOrder.OrderId.Equals(buyId)) {
      return;
    }
    coinbaseConnection.OrdersService.PlaceLimitOrderAsync(
        OrderSide.Sell,
        bid.ProductType,
        bidSize,
        sellPrice,
        clientOid: sellOrderId);
}
coinbaseConnection.WebSocket.OnDoneReceived += WebSocket_OnDoneReceived;

var buyResult = await coinbaseConnection
    .OrdersService
    .PlaceLimitOrderAsync(
      OrderSide.Buy,
      bid.ProductType,
      bidSize,
      bidPrice,
      timeInForce: TimeInForce.Fok,
      postOnly: false,
      clientOid: buyOrderId);
dougdellolio commented 3 years ago

hey @jamesboyer,

A few things here:

The client_oid that you are passing in when placing the order is different than the OrderId on LastOrder so the match you are doing won't work. The correct way to do this would be to use the id property returned from your buyResult as the match in your OnDoneRecieved instead of the buyId. Something like this:

var tradeId = buyResult.Id;

void WebSocket_OnDoneReceived(object sender, WebfeedEventArgs<Done> e)
{
    if (e.LastOrder.OrderId == tradeId)
    {
        Console.WriteLine("ORDER HAS BEEN FILLED");
    }
}

The client_oid will only be available on the public feed for a received message and according to the docs will NOT be used after the recieved message is sent. But if you want to be able to see your trade on the public feed you'll have to subscribe to OnReceivedReceived from the websocket. Also, don't forget to subscribe to the Full channel for this otherwise the messages won't come in. For example:

coinbaseConnection.WebSocket.OnReceivedReceived += WebSocket_OnReceivedReceived;

void WebSocket_OnReceivedReceived(object sender, WebfeedEventArgs<Received> e)
{
    if (e.LastOrder.ClientOid == buyId)
    {
        Console.WriteLine("We match!");
    }
}

hope this helps. Let me know if you are still running into any issues or it's not clear.

jamesboyer commented 3 years ago

Makes sense. Only downside is that the WebSocket_OnDoneReceived could get handled prior to me setting tradeId. Will have to figure out a way around that but shouldn't be too hard. Important thing is at least I do have the right event. Thanks for the help.