Click here to Skip to main content
15,884,922 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone, I have a C# app with a task, This method call executes 1 time usually but every once in awhile it will do 2 calls. I am using this with ‘Real Money’ so executing the method more than 1 time is not acceptable. I have a task its always running in the background checking a condition. Once its met then it does the other method. I tried adding a counter but its happening farther in the program and it still did more than 1 execute. Any thoughts or suggestions?
C#
private async Task ExecuteTradeTask()
        {
            cancelExecuteTask = new CancellationTokenSource();

            tExecuteTask = Task.Run(async () =>
            {
                while (true)
                {
                    cancelExecuteTask.Token.ThrowIfCancellationRequested();
                    var delayTask = Task.Delay(1000); 

                    if (runHistory)
                    {
                        //if (executeTaskRunning)
                        //{
                        try
                        {
                            if (TradesNow.ContainsKey("Trade1B"))
                            {
                                if (TradePriceValidBuy(CurrentTrade.Price, TradesNow["Trade1B"].StopPrice))
                                {
                                    var response = await StopBuyAsync(TradesNow["Trade1B"].StopPrice, TradesNow["Trade1B"].LimitPrice, TradesNow["Trade1B"].CryptoAmount);

                                    //if failure make global guid and global bools and run async
                                    // Set for 'CHECKING' current Trade Status.
                                    currentGUID = response.Id.ToString();
                                    runStatus = true;
                                    trade1B = false;
                                    TradesNow.Remove("Trade1B");
                                    //RefreshTradesToDo();
                                    PrintToDoTradesAsync();

                                    // GetTradeStatusAsync(response.Id.ToString());
                                    if (!tStatusTask.Status.Equals(TaskStatus.Running))
                                    {
                                         await GetTradeStatusAsync();
                                    }
                                    return;
                                }
                        }
   }
                        catch (Exception)
                        {
                            //MessageBox.Show("Trade Created Exception.\n" + ex.Message, "Error",
                            //             MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        // }
                    }
                    await delayTask;
                }
            }, cancelExecuteTask.Token);
    }
private async Task<OrderResponse> StopBuyAsync(decimal stopPrice, decimal limitPrice, decimal cryptoAmount)
        {
            StopOrders stopOrder = new StopOrders(stopPrice, limitPrice, cryptoAmount);
            OrderResponse response;
            try
            {
                response = await tradeClient.StopOrderBuy(stopOrder);
            }
            catch(Exception)
            {
                throw;
            }
            return response;
        }
        public async Task<OrderResponse> StopOrderBuy(StopOrders order)
        {
            //if (!running) {  running = true; }
            //else  running = false;
            OrderResponse response;
            int isValid = 0;

            //if(isValid == 0)
            //{
                try
                {
                    response = await coinbaseProClient.OrdersService.PlaceStopOrderAsync
                        (
                            OrderSide.Buy,
                            ProductType.BtcUsd,
                            order.CryptoAmount,
                            order.LimitPrice,
                            order.StopPrice
                        );
                    isValid++;
                }
                catch(Exception)// ex)
                {
                    throw;// ex;
                }
            //}


            return response;
            ///return isValid;
        }


What I have tried:

I tried adding a counter in the method but it was happening farther in the program so that didnt work. It doesnt happen every time it's only sometimes. But I need it so it 'NEVER' happens. I'm calling an API for the
C#
var response = await StopBuyAsync(TradesNow["Trade1B"].StopPrice, TradesNow["Trade1B"].LimitPrice, TradesNow["Trade1B"].CryptoAmount);

This is the part that can only happen once.
Posted
Updated 4-Jun-20 3:43am

C#
while (true)

Why are you running that code in a loop if it must never execute more than once? I can only assume there is some situation where the code skips both of the return statements.
 
Share this answer
 
Comments
TheBigBearNow 1-Jun-20 15:39pm    
I need it to continuously check a condition and if the condition is met, then do the method 1 time. The condition is checking a price that is changing every second.
Currently my ExecuteTradeTask() is doing all of that. But id say 90% it executes only 1 time like its supposed to. But every so often itll execute 2-3 times which cant happen because using real money doing a trade more than 1 time is not good.
Richard MacCutchan 1-Jun-20 15:42pm    
Well the only thing I can suggest is that you look very carefully at the design of this piece of code, because as long as that possibility exists then you cannot rely on it.
TheBigBearNow 1-Jun-20 16:15pm    
Ill try to break it up. I have an idea instead of calling my method in the thread I can have the thread set a bool to true and in a separate thread I can call the method one time if its true. I'm new with multi threading applications I currently have a thread getting Trade History, my GUI WPF Thread, a TradeStatus Thread after a trade is executed, and I had this ExecuteTrade Thread.
I think I may have solved the issue:
So far it seems to be working properly without any double trades.

I added a small delay after the method does the trade.
C#
public async Task<OrderResponse> StopOrderSell(StopOrders order)
       {
           OrderResponse response;

               try
               {
                   response = await coinbaseProClient.OrdersService.PlaceStopOrderAsync
                       (
                           OrderSide.Sell,
                           ProductType.BtcUsd,
                           order.CryptoAmount,
                           order.LimitPrice,
                           order.StopPrice
                       );

                   await Task.Delay(500);
                   return response;
               }
               catch (Exception)// ex)
               {
                   throw;
               }

           return response;
       }
 
Share this answer
 
Comments
Richard MacCutchan 4-Jun-20 9:59am    
So you have still not actually solved the problem. Finding a work around is all very well but it is not a solution that you should rely on. If the problem happens again what will you do? Double the time delay? And if it still happens after that ... ?
CHill60 4-Jun-20 10:44am    
I agree with Richard by the way, this is not a robust solution.
In other news, you could simplify your code by removing the try-catch block that isn't actually doing anything other than removing detail of the stack trace
TheBigBearNow 4-Jun-20 11:35am    
You guys are correct if it happens again I have no idea..
I would like to have a solution where this does not happen.
If I remove my try-catch block if an exception happens wouldnt my program break then?
TheBigBearNow 4-Jun-20 13:04pm    
Some bad new everyone.. It's not fixed it does it even less now but a double trade happened. Back to the drawing board...
TheBigBearNow 4-Jun-20 17:43pm    
So I made a log file to see if it would help me understand these double trades.
Here is what i found out. A normal log on top and the duplicate next.
06/04/2020 4:39:50 In ExecuteTradeTaskV3 Start
06/04/2020 4:39:50 Price Valid B1
06/04/2020 4:39:50 StopBuyV2 - before TradeClient call
06/04/2020 4:39:50 Trade Client - StopOrderBuy Start
06/04/2020 4:39:50 Trade Client - StopOrderBuy API Start
06/04/2020 4:39:51 Trade Client - StopOrderBuy API After
06/04/2020 4:39:52 Trade Client - StopOrderBuy End
06/04/2020 4:39:52 StopBuyV2 - end of method()
06/04/2020 4:39:52 B1 - After StopBuyV2 returned
06/04/2020 4:40:27 In ExecuteTradeTaskV3 Start
06/04/2020 4:40:41 In ExecuteTradeTaskV3 Start
06/04/2020 4:41:28 In ExecuteTradeTaskV3 Start
06/04/2020 4:41:28 Price Valid B1
06/04/2020 4:41:28 Price Valid B1
06/04/2020 4:41:28 StopBuyV2 - before TradeClient call
06/04/2020 4:41:29 StopBuyV2 - before TradeClient call
06/04/2020 4:41:29 Trade Client - StopOrderBuy Start
06/04/2020 4:41:29 Trade Client - StopOrderBuy Start
06/04/2020 4:41:29 Trade Client - StopOrderBuy API Start
06/04/2020 4:41:29 Trade Client - StopOrderBuy API Start
06/04/2020 4:41:29 Trade Client - StopOrderBuy API After
06/04/2020 4:41:29 Trade Client - StopOrderBuy API After
06/04/2020 4:41:30 Trade Client - StopOrderBuy End
06/04/2020 4:41:30 StopBuyV2 - end of method()
06/04/2020 4:41:30 B1 - After StopBuyV2 returned

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900