Creating Order Sometimes Returns Old Orders?

Hello,

I’m running into an issue with creating a new order sometimes. It sometimes returns old orders somehow, is this an issue on my side or is this still work in progress from Coinbase’s side? All other APIs work fine. Here’s my code:

BOOL CCoinBase::PlaceOrder( PCHAR pProductId, PCHAR pSide, DOUBLE dQuantity, DOUBLE dPrice, LPCOINBASE_ORDER pOrderOut )
{
	PCHAR pOrderString = (PCHAR)"{\"product_id\":\"%s\",\"client_order_id\":\"%s\",\"side\":\"%s\",\"order_configuration\":{\"limit_limit_gtc\":{\"limit_price\":\"%f\",\"base_size\":\"%f\"}}}";

	INT iTries = 0; 

Redo:
	CHAR szClientOrderId[32] = {0}; 
	sprintf( szClientOrderId, "%llu%llu", rand() % INT64_MAX, rand() % INT64_MAX ); 

	CHAR szPostFields[512] = {0};
	sprintf( szPostFields, pOrderString, pProductId, szClientOrderId, pSide, dPrice, dQuantity ); 

	BOOL bRet = SendAuthorizedRequest( ECOINBASE_PLACE_ORDER, (PCHAR)"POST", (PCHAR)"", (PCHAR)"", szPostFields );

	if(bRet)
	{
		json Buffer = json::parse( GetBuffer() ); 

		if(Buffer.is_null() )
			return FALSE; 

		json SuccessResponse = Buffer["success_response"]; 

		if(SuccessResponse.is_null() )
			return FALSE; 

		strcpy( &pOrderOut->OrderId[0],			SuccessResponse["order_id"].get<string>().c_str() ); 
		strcpy( &pOrderOut->ClientOrderId[0],	SuccessResponse["client_order_id"].get<string>().c_str() ); 
		strcpy( &pOrderOut->ProductId[0],		SuccessResponse["product_id"].get<string>().c_str() ); 
		strcpy( &pOrderOut->Side[0],			SuccessResponse["side"].get<string>().c_str() ); 
	}

	if(!GetOrder( pOrderOut->OrderId, pOrderOut ) ) //coinbase doesn't return all info, only when grabbing it again
		return FALSE; 

	if( (  (GetTime() - pOrderOut->Time) / 1000) > 5)
	{
		iTries++;

		if(iTries < 20) //sometimes it grabs like 10+ old orders first
		{
			Sleep(50); 
			goto Redo;
		}
	}

	return bRet; 
}

I’m only trying to put in a simple LIMIT order, both BUY and SELL do the same thing. Eventually if I keep trying it works fine. The returned data doesn’t help me out much either, except that the clientorderid isn’t matching the clientorderid I’ve sent to the server. The return status just returns “true” all the time.

Am I doing something wrong?

Thanks in advance!

R

Hello @R4z8r! Thank you for taking an interest in trying out Coinbase APIs. For the details regarding your concern, we will check on this for you with our team. We will get back to you once we have more information. Keep in touch!

2 Likes

Not super familiar with [some version of C?], but I think you probably want to double check your client_order_id. Make sure it is what you think it is, and make sure it’s really truly random. double check parameters etc.

You can only use a client_order_id once, even if you cancel the order later. Coinbase will always associate it with the first order you place with it. If you ever place another order with the same client_order_id, Coinbase will just return info for the first one. This is nice because if you send an order and, say, lose the connection before the response, you can safely try again without worrying about duplicating the order and trading twice as much crypto as you thought.

Correct me if I’m wrong but my understanding is that rand() is pseudo-random, and will generate the same “random” numbers every time you run the program. seeding it with srand() is better, but make sure the seed is different every run or it will still generate the same sequence of numbers.

That’s my best guess as to what’s happening, which would explain why it works after you keep trying for a while. rand() eventually generates a “random” number that Coinbase hasn’t seen yet, and the new order goes through.

I had a similar problem so I just started generating UUIDs for my client IDs and haven’t had that problem since. Hope that helps

1 Like

Thanks for your reply!

Yes, I’ve triple checked all of the clientorderids, they’re all unique. I think it’s a bug in my code somewhere, it returns different old orders for like 10 times sometimes( from old to new, not in random order ). I initialize srand() with time() in the constructor of the class. I think I’m going to rewrite the code and try it again. Weird thing is that all the other APIs work fine though. Thought I was doing something wrong with the postfields, but that seems fine as well.

1 Like

Do you want to be doing that in the constructor or in main? Are you creating multiple orders at once? If you are, then is there a chance you’re doing srand() multiple times in the same second?

None of the other endpoints require a user generated random string, so I feel like it has to be a problem with the client ID generation. idk

Nope, they’re all unique. It doesn’t matter at all, even if I use some kind of counter for clientorderid it does the same thing. I think it’s somewhere in my CURL code or it’s a bug in my account. I use the same code just fine for 3 other exchanges though, that’s the weird issue. I’ve logged everything, everything seems OK. It could also be that it has to do with my account, I’ve used normal CB and CB Pro on this one. Even if I use the new “Advanced Trade API” wallet endpoint which uses the V3 I get 0 balance on some accounts with the same accountids. If I use V2 it’s just fine with the same accountid. I kinda have the feeling it’s not properly merged yet( as Advanced Trade API is still in BETA also ).

Hi there @R4z8r! WIth regards to your concern, can you provide with us your userid? Rest assured that the team is working hard in investigating your case and we would provide an update as soon as we heard from them. On another note, if you could not be able to provide us the information being asked, your query would be better served by creating a support ticket using our Contact Us form: https://help.coinbase.com/en/contact-us. Thank you!

2 Likes