Exemple #1
0
        /// <summary>
        /// Checks order that are in waiting state, and changes it to placed state if is needed (Here transaction confirmations are verified))
        /// </summary>
        /// <param name="aWaitingOrders">Orders with waiting state</param>
        /// <param name="aCurrencyItem">Order currency item</param>
        /// <param name="aCurrencyTransactions">Pandora's currency transactions</param>
        /// <param name="aListExchangeCoinMarket">Markets to look for</param>
        private void VerifyWaitingOrders(IEnumerable <UserTradeOrder> aWaitingOrders, ICurrencyIdentity aCurrencyItem, IEnumerable <TransactionRecord> aCurrencyTransactions)
        {
            long lCurrencyBlockHeight;
            int  lExchangeminConf;

            ScanForCancelledOrders(aWaitingOrders);
            if (!aWaitingOrders.Any() || !aCurrencyTransactions.Any() ||
                (lExchangeminConf = FExchanger.GetConfirmations(aCurrencyItem)) < 0 ||
                (lCurrencyBlockHeight = FPandorasWalletConnection.GetBlockHeight(aCurrencyItem.Id)) <= 0)
            {
                return;
            }
            var lConfirmedTxs = aCurrencyTransactions.Where(lTx => lTx.Block != 0 && (lCurrencyBlockHeight - lTx.Block) > lExchangeminConf);

            foreach (var lTx in lConfirmedTxs)
            {
                UserTradeOrder lItem = aWaitingOrders.Where(lOrder => lOrder.CoinTxID == lTx.TxId).FirstOrDefault();
                if (lItem == null)
                {
                    continue;
                }
                if (lItem.Status == OrderStatus.Waiting && lItem.Market != null)
                {
                    TryToPlaceOrder(lItem);
                }
            }
        }
Exemple #2
0
        public bool RefundOrder(UserTradeOrder aOrder, string aAddress, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder.Status == OrderStatus.Withdrawn)
            {
                return(false);
            }

            PoloniexClientOptions lPoloniexClientOptions = new PoloniexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (PoloniexClient lClient = aUseProxy ? new PoloniexClient(lPoloniexClientOptions) : new PoloniexClient())
            {
                var lResponse = lClient.Withdraw(aOrder.Market.SellingCurrencyInfo.Ticker, aOrder.SentQuantity, aAddress);
                if (!lResponse.Success)
                {
                    throw new Exception("Failed to refund order. Error message:" + lResponse.Error.Message);
                }
                if (!string.IsNullOrEmpty(lResponse.Data.error))
                {
                    throw new Exception($"Failed to refund order. Error message: {lResponse.Data.error}");
                }
            }

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Tries to form a transaction that meets the order requeriments and then sends it to the exchange user address. Also does amount verification
        /// </summary>
        /// <param name="aOrder">Order to fulfill</param>
        /// <param name="aMarket">Order's market</param>
        /// <param name="aCurrencyID">Selected currency id</param>
        private async void TryToTransferMoneyToExchange(UserTradeOrder aOrder)
        {
            const string lAlreadyProcessingFlag = "Processing";

            try
            {
                if (aOrder.CoinTxID == lAlreadyProcessingFlag)
                {
                    return;
                }
                FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Info, string.Format("Stop price reached, trying to send coins to exchange.", FExchanger.GetConfirmations(aOrder.Market.SellingCurrencyInfo)));
                string  lExchangeAddress = FExchanger.GetDepositAddress(aOrder.Market);
                decimal lAmount          = aOrder.Market.MarketDirection == MarketDirection.Sell ? aOrder.SentQuantity : aOrder.SentQuantity + (aOrder.SentQuantity * (decimal)0.025);
                aOrder.CoinTxID = lAlreadyProcessingFlag;
                string lTxID = await Task.Run(() => OnTransferCoinsNeeded?.Invoke(lAmount, lExchangeAddress, aOrder.Market.SellingCurrencyInfo.Id, aOrder.CoinSendingTxFee));

                if (string.IsNullOrEmpty(lTxID))
                {
                    throw new Exception("Unable to broadcast transaction.");
                }
                aOrder.CoinTxID = lTxID;
                FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Waiting);
                FExchangeOrderManager.WriteTransactionLogEntry(aOrder);
                FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Info, string.Format("Number of confirmations needed: {0} confirmations", FExchanger.GetConfirmations(aOrder.Market.SellingCurrencyInfo)));
            }
            catch (Exception ex)
            {
                FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Interrupted);
                FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.FatalError, string.Format("Failed to send transaction. Details: {0}.", ex.Message));
            }
        }
Exemple #4
0
        public bool RefundOrder(UserTradeOrder aOrder, string aAddress, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder.Status == OrderStatus.Withdrawn)
            {
                return(false);
            }

            BitfinexClientOptions lBittrexClientOptions = new BitfinexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (BitfinexClient lClient = aUseProxy ? new BitfinexClient(lBittrexClientOptions) : new BitfinexClient())
            {
                var lResponse = lClient.WithdrawAsync(aOrder.Market.SellingCurrencyInfo.Name.ToLowerInvariant(), WithdrawWallet.Exchange, aOrder.SentQuantity, aAddress).Result;
                if (!lResponse.Success)
                {
                    throw new Exception("Failed to withdraw. Error message:" + lResponse.Error.Message);
                }
            }

            return(true);
        }
Exemple #5
0
        public void CancelOrder(UserTradeOrder aOrder, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder == null)
            {
                throw new ArgumentNullException(nameof(aOrder), "Invalid argument: " + nameof(aOrder));
            }

            PoloniexClientOptions lPoloniexClientOptions = new PoloniexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (PoloniexClient lClient = aUseProxy ? new PoloniexClient(lPoloniexClientOptions) : new PoloniexClient())
            {
                var lResponse = lClient.CancelOrder(Convert.ToInt64(aOrder.ID));
                if (!lResponse.Success || !Convert.ToBoolean(lResponse.Data.success))
                {
                    throw new Exception($"Failed to cancel order in exchange. Message: {lResponse.Data?.message ?? lResponse.Error.Message}");
                }
            }
        }
        public void CancelOrder(UserTradeOrder aOrder, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder == null)
            {
                throw new ArgumentNullException(nameof(aOrder), "Invalid argument: " + nameof(aOrder));
            }

            BittrexClientOptions lBittrexClientOptions = new BittrexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (BittrexClient lClient = aUseProxy ? new BittrexClient(lBittrexClientOptions) : new BittrexClient())
            {
                var lResponse = lClient.CancelOrderAsync(aOrder.ID).Result;
                if (!lResponse.Success)
                {
                    throw new Exception("Failed to cancel order in exchange. Message: " + lResponse.Error.Message);
                }
            }
        }
        public int?WriteOrder(UserTradeOrder aMarketTransaction)
        {
            if (!Initialized && !FReadOnly)
            {
                throw new Exception("Save manager not initialized");
            }
            using (SQLiteConnection lConnection = new SQLiteConnection(FConnectionString))
            {
                SQLiteTransaction lTransaction;
                lConnection.Open();
                lTransaction = lConnection.BeginTransaction();
                try
                {
                    SQLiteCommand lCommand1 = new SQLiteCommand("INSERT OR REPLACE INTO ExchangeTx (ID, Market, Quantity, OpenTime, Rate, Stop, Completed, Cancelled, Status, CoinTXID, CurrencyId, CurrencyTicker, Name, ProfileID) VALUES (@Id, @Market, @Quantity, @Opentime, @Rate, @Stop, @Completed, @Cancelled, @Status, @CoinTxID, @CurrencyId, @CurrencyTicker, @Name, @ProfileID); " +
                                                                "SELECT InternalID FROM ExchangeTx where CoinTXID = @CoinTxID;", lConnection);
                    lCommand1.Parameters.Add(new SQLiteParameter("@Id", aMarketTransaction.ID));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Market", aMarketTransaction.Market.MarketID));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Quantity", aMarketTransaction.SentQuantity));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Opentime", aMarketTransaction.OpenTime));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Rate", aMarketTransaction.Rate));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Stop", aMarketTransaction.StopPrice));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Completed", aMarketTransaction.Completed));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Cancelled", aMarketTransaction.Cancelled));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Status", aMarketTransaction.Status));
                    lCommand1.Parameters.Add(new SQLiteParameter("@CurrencyId", aMarketTransaction.Market.SellingCurrencyInfo.Id));
                    lCommand1.Parameters.Add(new SQLiteParameter("@CurrencyTicker", aMarketTransaction.Market.SellingCurrencyInfo.Ticker));
                    lCommand1.Parameters.Add(new SQLiteParameter("@CoinTxID", aMarketTransaction.CoinTxID));
                    lCommand1.Parameters.Add(new SQLiteParameter("@Name", aMarketTransaction.Name));
                    lCommand1.Parameters.Add(new SQLiteParameter("@ProfileID", aMarketTransaction.ProfileID));

                    var lScalarResult = lCommand1.ExecuteScalar()?.ToString();
                    if (lScalarResult == null)
                    {
                        throw new Exception("Failed to retrieve order id. Operation failed when writing order");
                    }
                    var lId = int.Parse(lScalarResult);

                    SQLiteCommand lCommand2 = new SQLiteCommand("INSERT OR REPLACE INTO Relationship_ExchangeID_OrderID (InternalOrderID, ExchangeID) Values (@InternalID, @ExchangeID)", lConnection);
                    lCommand2.Parameters.Add(new SQLiteParameter("@InternalID", lId));
                    lCommand2.Parameters.Add(new SQLiteParameter("@ExchangeID", aMarketTransaction.Market.ExchangeID));
                    lCommand2.ExecuteNonQuery();

                    lTransaction.Commit();
                    return(lId);
                }
                catch (Exception ex)
                {
                    lTransaction.Rollback();
                    Universal.Log.Write(Universal.LogLevel.Error, $"Error writing exchange order from db. Exception details: {ex}");
                    return(null);
                }
                finally
                {
                    lConnection.Close();
                }
            }
        }
Exemple #8
0
 private void RefundOrder(UserTradeOrder aOrderToWithdraw, OrderStatus?aOriginalStatus = null)
 {
     if (aOriginalStatus.HasValue && aOriginalStatus.Value == OrderStatus.Waiting)
     {
         FExchangeOrderManager.WriteTransactionLogEntry(aOrderToWithdraw, OrderMessage.OrderMessageLevel.Info, $"Waiting for transaction {aOrderToWithdraw.CoinTxID} to be confirmed at exchange to try withdraw coins.");
         FWaitingToRefund.TryAdd(aOrderToWithdraw.InternalID, aOrderToWithdraw);
     }
     else
     {
         TryRefundOrder(aOrderToWithdraw);
     }
 }
Exemple #9
0
        public UserTradeOrder SaveNewOrder(UserTradeOrder aNewOrder)
        {
            var lInternalID = FSaveManager.WriteOrder(aNewOrder);

            if (!lInternalID.HasValue)
            {
                throw new Exception("Failed to write new order in disk");
            }
            aNewOrder.InternalID = lInternalID.Value;
            SetOrderInCache(aNewOrder);
            return(aNewOrder);
        }
Exemple #10
0
 private void TryCancelOrder(UserTradeOrder aOrder)
 {
     try
     {
         FExchanger.CancelOrder(aOrder);
         FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Error, $"Order id: {aOrder.ID} successfully cancelled at exchange.");
     }
     catch (Exception ex)
     {
         Universal.Log.Write(Universal.LogLevel.Error, string.Format("Order: {0}. Exception: {1}", aOrder.InternalID, ex.ToString()));
         FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Error, $"Error on cancel remote order: {ex.Message}.");
     }
 }
Exemple #11
0
 public void UpdateOrder(UserTradeOrder aNewOrder, OrderStatus aStatus)
 {
     if (aNewOrder.Market == null)
     {
         return;
     }
     FOrders.AddOrUpdate(aNewOrder.InternalID, aNewOrder, (key, lOldValue) => aNewOrder);
     if (!FSaveManager.UpdateOrder(aNewOrder, aStatus))
     {
         throw new Exception("Failed to write new transaction into disk");
     }
     aNewOrder.Status = aStatus;
     OnOrderStatusChanged?.BeginInvoke(aNewOrder.InternalID, aStatus, aNewOrder.Market.SellingCurrencyInfo.Id, null, null);
 }
        public bool UpdateOrder(UserTradeOrder aMarketTransaction, OrderStatus aStatus)
        {
            if (!Initialized && !FReadOnly)
            {
                throw new Exception("Save manager not initialized");
            }
            using (SQLiteConnection lConnection = new SQLiteConnection(FConnectionString))
            {
                lConnection.Open();
                var           lTransaction = lConnection.BeginTransaction();
                SQLiteCommand lCommand1    = new SQLiteCommand("Update ExchangeTx SET ID = @Id, Market = @Market, Quantity = @Quantity, OpenTime = @Opentime, Rate = @Rate, Stop = @Stop, Completed = @Completed, Cancelled = @Cancelled, Status = @Status, CoinTXID = @CoinTxID, CurrencyID = @CurrencyId, CurrencyTicker = @CurrencyTicker,Name = @Name, ProfileID = @ProfileID WHERE InternalID = @InternalID", lConnection);
                lCommand1.Parameters.Add(new SQLiteParameter("@InternalID", aMarketTransaction.InternalID));
                lCommand1.Parameters.Add(new SQLiteParameter("@Id", aMarketTransaction.ID));
                lCommand1.Parameters.Add(new SQLiteParameter("@Market", aMarketTransaction.Market.MarketID));
                lCommand1.Parameters.Add(new SQLiteParameter("@Quantity", aMarketTransaction.SentQuantity));
                lCommand1.Parameters.Add(new SQLiteParameter("@Opentime", aMarketTransaction.OpenTime));
                lCommand1.Parameters.Add(new SQLiteParameter("@Rate", aMarketTransaction.Rate));
                lCommand1.Parameters.Add(new SQLiteParameter("@Stop", aMarketTransaction.StopPrice));
                lCommand1.Parameters.Add(new SQLiteParameter("@Completed", aMarketTransaction.Completed));
                lCommand1.Parameters.Add(new SQLiteParameter("@Cancelled", aMarketTransaction.Cancelled));
                lCommand1.Parameters.Add(new SQLiteParameter("@Status", (int)aStatus));
                lCommand1.Parameters.Add(new SQLiteParameter("@CoinTxID", aMarketTransaction.CoinTxID));
                lCommand1.Parameters.Add(new SQLiteParameter("@CurrencyId", aMarketTransaction.Market.SellingCurrencyInfo.Id));
                lCommand1.Parameters.Add(new SQLiteParameter("@CurrencyTicker", aMarketTransaction.Market.SellingCurrencyInfo.Ticker));
                lCommand1.Parameters.Add(new SQLiteParameter("@Name", aMarketTransaction.Name));
                lCommand1.Parameters.Add(new SQLiteParameter("@ProfileID", aMarketTransaction.ProfileID));

                SQLiteCommand lCommand2 = new SQLiteCommand("Update Relationship_ExchangeID_OrderID SET ExchangeID = @ExchangeID WHERE InternalOrderID = @InternalID", lConnection);
                lCommand2.Parameters.Add(new SQLiteParameter("@InternalID", aMarketTransaction.InternalID));
                lCommand2.Parameters.Add(new SQLiteParameter("@ExchangeID", aMarketTransaction.Market.ExchangeID));

                try
                {
                    lCommand1.ExecuteNonQuery();
                    lCommand2.ExecuteNonQuery();
                    lTransaction.Commit();
                    return(true);
                }
                catch (Exception ex)
                {
                    lTransaction.Rollback();
                    Universal.Log.Write(Universal.LogLevel.Error, $"Error updating exchange order from db. Exception {ex}");
                    return(false);
                }
                finally
                {
                    lConnection.Close();
                }
            }
        }
Exemple #13
0
 private void TryRefundOrder(UserTradeOrder aOrderToWithdraw)
 {
     try
     {
         FExchangeOrderManager.WriteTransactionLogEntry(aOrderToWithdraw, OrderMessage.OrderMessageLevel.Info, "Trying to refund coins from exchange.");
         FExchanger.RefundOrder(aOrderToWithdraw, FPandorasWalletConnection.GetCoinAddress(aOrderToWithdraw.Market.SellingCurrencyInfo.Id));
         FExchangeOrderManager.WriteTransactionLogEntry(aOrderToWithdraw, OrderMessage.OrderMessageLevel.Info, "Coins successfully withdrawn. Please wait some minutes to be shown in wallet");
     }
     catch (Exception ex)
     {
         Universal.Log.Write(Universal.LogLevel.Error, string.Format("Order: {0}. Exception: {1}", aOrderToWithdraw.InternalID, ex.ToString()));
         FExchangeOrderManager.WriteTransactionLogEntry(aOrderToWithdraw, OrderMessage.OrderMessageLevel.Error, $"Error on refund process in order: {ex.Message}. Please try to manually withdraw your coins from exchange");
     }
 }
Exemple #14
0
        public bool PlaceOrder(UserTradeOrder aOrder, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder == null || aOrder.Market == null)
            {
                throw new ArgumentNullException(aOrder == null ? nameof(aOrder) : nameof(aOrder.Market), "Invalid argument: " + aOrder == null ? nameof(aOrder) : nameof(aOrder.Market));
            }

            if (aOrder.Status != OrderStatus.Waiting)
            {
                return(false);
            }

            BitfinexClientOptions lBitfinexClientOptions = new BitfinexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (BitfinexClient lClient = aUseProxy ? new BitfinexClient(lBitfinexClientOptions) : new BitfinexClient())
            {
                if (!aOrder.Market.TryCastToLocalMarket(out ExchangeMarket lExchangeMarket))
                {
                    throw new ArgumentException(nameof(aOrder.Market), "Invalid Market");
                }
                var lResponse = lClient.PlaceOrderAsync(lExchangeMarket.MarketPairID, lExchangeMarket.MarketDirection == MarketDirection.Sell ? OrderSide.Sell : OrderSide.Buy, OrderType.ExchangeLimit, lExchangeMarket.MarketDirection == MarketDirection.Sell ? aOrder.SentQuantity : aOrder.SentQuantity / aOrder.Rate, aOrder.Rate).Result;
                if (!lResponse.Success)
                {
                    throw new Exception($"Bitfinex Error. Message: {lResponse.Error.Message}");
                }
                long lUuid = lResponse.Data.Id;

                var lVerifyResponse = lClient.GetOrderAsync(lUuid).Result;
                if (!lResponse.Success)
                {
                    throw new Exception("Failed to verify order with exchange server");
                }
                aOrder.ID        = lUuid.ToString();
                aOrder.OpenTime  = lVerifyResponse.Data.Timestamp;
                aOrder.Cancelled = lVerifyResponse.Data.Canceled;
                aOrder.Completed = lVerifyResponse.Data.RemainingAmount == 0;
            }

            return(true);
        }
Exemple #15
0
        private void SetOrderInCache(UserTradeOrder aOrder, int aExchangeID = -1)
        {
            var lExchangeId = aOrder.Market?.ExchangeID ?? aExchangeID;

            if (lExchangeId < 0)
            {
                return;
            }
            FOrders.AddOrUpdate(aOrder.InternalID, aOrder, (key, oldvalue) => aOrder);
            if (!FOrdersByExchange.TryGetValue(lExchangeId, out ConcurrentBag <UserTradeOrder> lIds))
            {
                lIds = new ConcurrentBag <UserTradeOrder>();
                FOrdersByExchange.TryAdd(lExchangeId, lIds);
            }
            lIds.Add(aOrder);
        }
Exemple #16
0
        private void TryToWithdrawOrder(UserTradeOrder aOrder)
        {
            if (aOrder.Status != OrderStatus.Completed)
            {
                return;
            }

            if (aOrder.ErrorCounter % 60 == 0)
            {
                try
                {
                    if (aOrder.Market.BuyingCurrencyInfo.Id == 0)
                    {
                        throw new Exception($"Failed to withdraw order id {aOrder.ID}. No currency data.");
                    }
                    if (FExchanger.WithdrawOrder(aOrder, FPandorasWalletConnection.GetCoinAddress(aOrder.Market.BuyingCurrencyInfo.Id), FExchanger.GetTransactionsFee(aOrder.Market.BuyingCurrencyInfo)))
                    {
                        FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Withdrawn);
                    }
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder);
                    aOrder.ErrorCounter = 0;
                }
                catch (Exception ex)
                {
                    int lNumberofretrys = aOrder.ErrorCounter / 60;

                    if (lNumberofretrys >= 9)
                    {
                        aOrder.Cancelled = true;
                        FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Interrupted);
                        FExchangeOrderManager.WriteTransactionLogEntry(aOrder);
                    }

                    aOrder.ErrorCounter += 1;
                    Universal.Log.Write(Universal.LogLevel.Error, string.Format("Order: {0}. Exception: {1}", aOrder.InternalID, ex.ToString()));
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Error, "Error on Withdraw Order: " + ex.Message);
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Info, string.Format("Retrying in 5 minute. Attempt: {0}/10", (lNumberofretrys + 1)));
                }
            }
            else
            {
                aOrder.ErrorCounter++;
            }
        }
Exemple #17
0
        public void WriteTransactionLogEntry(UserTradeOrder aOrder, OrderMessage.OrderMessageLevel aLevel = OrderMessage.OrderMessageLevel.Info, string aMessage = null)
        {
            if (string.IsNullOrEmpty(aMessage))
            {
                switch (aOrder.Status)
                {
                case OrderStatus.Initial:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Starting transaction process.", OrderMessage.OrderMessageLevel.Info);
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Waiting for market stop price to place order.", OrderMessage.OrderMessageLevel.StageChange);
                    break;

                case OrderStatus.Waiting:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Price reached specified stop price.", OrderMessage.OrderMessageLevel.Info);
                    FSaveManager.WriteOrderLog(aOrder.InternalID, string.Format("{0} coins sent to exchange account. Tx ID: {1}.", aOrder.SentQuantity, aOrder.CoinTxID), OrderMessage.OrderMessageLevel.Info);
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Waiting for confirmations to place the order.", OrderMessage.OrderMessageLevel.StageChange);
                    break;

                case OrderStatus.Placed:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, string.Format("Transaction id {0} has enough confirmations to place the order.", aOrder.CoinTxID), OrderMessage.OrderMessageLevel.Info);
                    FSaveManager.WriteOrderLog(aOrder.InternalID, string.Format("Placed order in exchange. Uuid: {0}. Waiting for order to fulfill.", aOrder.ID.ToString()), OrderMessage.OrderMessageLevel.StageChange);
                    break;

                case OrderStatus.Interrupted:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Transaction cancelled or not found on the exchange.", OrderMessage.OrderMessageLevel.FatalError);
                    break;

                case OrderStatus.Completed:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Transaction completed. Waiting for withdrawal.", OrderMessage.OrderMessageLevel.StageChange);
                    break;

                case OrderStatus.Withdrawn:
                    FSaveManager.WriteOrderLog(aOrder.InternalID, "Cryptocurrencies succesfully withdrawn to Pandora's Wallet.", OrderMessage.OrderMessageLevel.Finisher);
                    break;
                }
            }
            else
            {
                FSaveManager.WriteOrderLog(aOrder.InternalID, aMessage, aLevel);
            }
            if (FSaveManager.ReadOrderLogs(aOrder.InternalID, out List <OrderMessage> lOrderMessages))
            {
                OnNewOrderLogsAdded?.BeginInvoke(aOrder.InternalID, lOrderMessages, null, null);
            }
        }
Exemple #18
0
        public bool PlaceOrder(UserTradeOrder aOrder, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder == null)
            {
                throw new ArgumentNullException(nameof(aOrder), $"Invalid order with id {aOrder}");
            }

            if (aOrder.Status != OrderStatus.Waiting)
            {
                return(false);
            }

            using (var lClient = new PoloniexClient())
            {
                WebCallResult <PoloniexOrderPlaceResult> lResponse = null;
                if (!aOrder.Market.TryCastToLocalMarket(out ExchangeMarket lExchangeMarket))
                {
                    throw new ArgumentException(nameof(aOrder.Market), "Invalid Market");
                }
                if (lExchangeMarket.MarketDirection == MarketDirection.Sell)
                {
                    lResponse = lClient.PlaceSellOrder(lExchangeMarket.MarketPairID, aOrder.Rate, aOrder.SentQuantity);
                }
                else if (lExchangeMarket.MarketDirection == MarketDirection.Buy)
                {
                    lResponse = lClient.PlaceBuyOrder(lExchangeMarket.MarketPairID, aOrder.Rate, aOrder.SentQuantity / aOrder.Rate);
                }
                if (lResponse == null || !lResponse.Success)
                {
                    throw new Exception($"Unable to place trade order at exchange. Error: {lResponse?.Error.Message ?? "Failed to get response from server" }");
                }

                aOrder.ID       = lResponse.Data.orderNumber.ToString();
                aOrder.OpenTime = DateTime.UtcNow;
            }
            return(true);
        }
Exemple #19
0
        private void TryToPlaceOrder(UserTradeOrder aOrder)
        {
            if (aOrder.ErrorCounter % 60 == 0)
            {
                try
                {
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Info, "Attempting to place order in exchange.");
                    if (FExchanger.PlaceOrder(aOrder))
                    {
                        FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Placed);
                    }
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder);
                    aOrder.ErrorCounter = 0;
                }
                catch (Exception ex)
                {
                    int lNumberofretrys = aOrder.ErrorCounter / 60;

                    if (lNumberofretrys >= 9)
                    {
                        aOrder.Cancelled = true;
                        FExchangeOrderManager.UpdateOrder(aOrder, OrderStatus.Interrupted);
                        FExchangeOrderManager.WriteTransactionLogEntry(aOrder);
                    }

                    aOrder.ErrorCounter += 1;
                    Universal.Log.Write(Universal.LogLevel.Error, string.Format("Order: {0}. Exception: {1}", aOrder.InternalID, ex.ToString()));

                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Error, "Error while placing Order: " + ex.Message);
                    FExchangeOrderManager.WriteTransactionLogEntry(aOrder, OrderMessage.OrderMessageLevel.Info, string.Format("Retrying in 1 minute. Attempt: {0}/10", (lNumberofretrys + 1)));
                }
            }
            else
            {
                aOrder.ErrorCounter++;
            }
        }
        public bool PlaceOrder(UserTradeOrder aOrder, bool aUseProxy = true)
        {
            if (!IsCredentialsSet)
            {
                throw new Exception("No Credentials were set");
            }

            if (aOrder == null)
            {
                throw new ArgumentNullException(nameof(aOrder), $"Invalid order{aOrder.ID}");
            }

            if (aOrder.Status != OrderStatus.Waiting)
            {
                return(false);
            }

            BittrexClientOptions lBittrexClientOptions = new BittrexClientOptions()
            {
                Proxy          = PandoraProxy.GetApiProxy(),
                ApiCredentials = new ApiCredentials(FUserCredentials.Item1, FUserCredentials.Item2)
            };

            using (BittrexClient lClient = aUseProxy ? new BittrexClient(lBittrexClientOptions) : new BittrexClient())
            {
                if (!aOrder.Market.TryCastToLocalMarket(out ExchangeMarket lExchangeMarket))
                {
                    throw new ArgumentException(nameof(aOrder.Market), "Invalid Market");
                }
                CallResult <BittrexOrder> lResponse;
                if (aOrder.Market.MarketDirection == MarketDirection.Sell)
                {
                    lResponse = lClient.PlaceOrderAsync(lExchangeMarket.MarketPairID, OrderSide.Sell, OrderType.Limit, TimeInForce.GoodTillCancelled, aOrder.SentQuantity, limit: aOrder.Rate).Result;
                }
                else
                {
                    lResponse = lClient.PlaceOrderAsync(lExchangeMarket.MarketPairID, OrderSide.Buy, OrderType.Limit, TimeInForce.GoodTillCancelled, aOrder.SentQuantity / aOrder.Rate, limit: aOrder.Rate).Result;
                }
                if (!lResponse.Success)
                {
                    throw new Exception("Bittrex Error. Message: " + lResponse.Error.Message);
                }

                string lUuid = lResponse.Data.Id;
                CallResult <BittrexOrder> lResponse2 = lClient.GetOrderAsync(lUuid).Result;
                if (!lResponse.Success)
                {
                    throw new Exception("Failed to verify order with server");
                }

                BittrexOrder lReceivedOrder = lResponse2.Data;

                aOrder.ID = lUuid;

                aOrder.OpenTime  = lReceivedOrder.CreatedAt;
                aOrder.Cancelled = lReceivedOrder.OrderToCancel != null;
                aOrder.Completed = lReceivedOrder.ClosedAt.HasValue;

                return(true);
            }
        }
Exemple #21
0
        /// <summary>
        /// Loads currency exchange orders from disk. This should only be called once or to reload orders.
        /// </summary>
        /// <param name="aCurrencyTicker"></param>
        /// <param name="aCurrencyID"></param>
        /// <returns></returns>
        public IEnumerable <UserTradeOrder> LoadOrders(ICurrencyIdentity aCurrency, IPandoraExchangeFactory lExchangeFactory, GetWalletIDDelegate aGetWalletIDFunction)
        {
            var lResult   = new List <UserTradeOrder>();
            var lDBOrders = FSaveManager.ReadOrders(aCurrency);

            if (lDBOrders != null && lDBOrders.Any())
            {
                int lErrorCounter;
                var lMarketCache = new Dictionary <int, IEnumerable <IExchangeMarket> >();
                foreach (var lDBOrder in lDBOrders)
                {
                    bool lOrdersLogs = FSaveManager.ReadOrderLogs(lDBOrder.InternalID, out List <OrderMessage> lMessages);
                    lMessages     = lMessages.OrderBy(lMessage => lMessage.Time).ToList();
                    lErrorCounter = 0;
                    for (int it2 = 0; it2 < lMessages.Count; it2++)
                    {
                        OrderMessage lIndividualMessage = lMessages[it2];

                        switch (lIndividualMessage.Level)
                        {
                        case OrderMessage.OrderMessageLevel.Error:
                            lErrorCounter += 60;
                            break;

                        case OrderMessage.OrderMessageLevel.StageChange:
                            lErrorCounter = 0;
                            break;

                        case OrderMessage.OrderMessageLevel.FatalError:
                            lErrorCounter = -1;
                            break;
                        }
                        if (lErrorCounter == -1)
                        {
                            break;
                        }
                    }

                    var lExchanger = lExchangeFactory.GetPandoraExchange((AvailableExchangesList)lDBOrder.ExchangeID);
                    if (!lMarketCache.TryGetValue(lDBOrder.ExchangeID, out IEnumerable <IExchangeMarket> lMarkets))
                    {
                        lMarkets = lExchanger.GetMarketCoins(aCurrency, aGetWalletIDFunction);
                        lMarketCache.Add(lDBOrder.ExchangeID, lMarkets);
                    }
                    var lUserOrder = new UserTradeOrder
                    {
                        InternalID   = lDBOrder.InternalID,
                        ID           = lDBOrder.ID,
                        Name         = lDBOrder.Name,
                        SentQuantity = lDBOrder.SentQuantity,
                        Status       = lDBOrder.Status,
                        CoinTxID     = lDBOrder.CoinTxID,
                        StopPrice    = lDBOrder.StopPrice,
                        OpenTime     = lDBOrder.OpenTime,
                        Rate         = lDBOrder.Rate,
                        ProfileID    = lDBOrder.ProfileID,
                        ErrorCounter = lErrorCounter,
                        Completed    = lDBOrder.Completed,
                        Cancelled    = lDBOrder.Cancelled,
                        Market       = lMarkets.FindByMarketID(lDBOrder.MarketID)
                    };
                    if (lUserOrder.Market == null)
                    {
                        Log.Write(LogLevel.Warning, $"Exchange: Unable to find market for order of id {lUserOrder.InternalID} of exchange {lExchanger.Name}");
                        continue;
                    }
                    lResult.Add(lUserOrder);
                    SetOrderInCache(lUserOrder, lDBOrder.ExchangeID);
                }
            }
            return(lResult);
        }