Exemplo n.º 1
0
        public MatchOrder(App.OpenOrder ord)
        {
            InitializeComponent();
            WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
            window_order          = ord;

            string trade_symbol = App.MarketList[App.exchange_market].trade_symbol;
            string base_symbol  = App.MarketList[App.exchange_market].base_symbol;

            min_ord = ord.minimum_amount;
            if (min_ord > ord.amount)
            {
                min_ord = ord.amount;
            }

            if (ord.type == 0)
            {
                //Buy Order
                Header.Content           = "Buy Order Details";
                Order_Type.Content       = "Requesting:";
                Order_Amount.Content     = "" + String.Format(CultureInfo.InvariantCulture, "{0:0.########}", ord.amount);
                Order_Min_Amount.Content = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", min_ord);
                Price.Content            = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", ord.price);
                decimal my_balance = App.GetMarketBalance(App.exchange_market, 1);                //If they are buying, we are selling

                Order_Amount.Content     += " " + trade_symbol;
                Order_Min_Amount.Content += " " + trade_symbol;
                Price.Content            += " " + base_symbol;
                My_Amount_Header.Content  = "Amount (" + trade_symbol + "):";
                Total_Cost_Header.Content = "Total Receive (" + base_symbol + "):";
                My_Balance.Content        = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", my_balance) + " " + trade_symbol;
            }
            else
            {
                //Sell Order
                Header.Content           = "Sell Order Details";
                Order_Type.Content       = "Available:";
                Order_Amount.Content     = "" + String.Format(CultureInfo.InvariantCulture, "{0:0.########}", ord.amount);
                Order_Min_Amount.Content = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", min_ord);
                Price.Content            = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", ord.price);
                decimal my_balance = App.GetMarketBalance(App.exchange_market, 0);                //If they are selling, we are buying

                Order_Amount.Content     += " " + trade_symbol;
                Order_Min_Amount.Content += " " + trade_symbol;
                Price.Content            += " " + base_symbol;
                My_Amount_Header.Content  = "Amount (" + trade_symbol + "):";
                Total_Cost_Header.Content = "Total Cost (" + base_symbol + "):";
                My_Balance.Content        = String.Format(CultureInfo.InvariantCulture, "{0:0.########}", my_balance) + " " + base_symbol;
            }
        }
Exemplo n.º 2
0
        private async void Match_Order(object sender, RoutedEventArgs e)
        {
            if (My_Amount.Text.Length == 0 || Total_Amount.Text.Length == 0)
            {
                return;
            }
            if (My_Amount.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }
            if (Total_Amount.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }
            decimal amount = decimal.Parse(My_Amount.Text, CultureInfo.InvariantCulture);
            decimal total  = decimal.Parse(Total_Amount.Text, CultureInfo.InvariantCulture);

            if (amount < min_ord)
            {
                //Cannot be less than the minimum order
                MessageBox.Show("Amount cannot be less than the minimum match.", "Notice!", MessageBoxButton.OK);
                return;
            }
            if (amount > window_order.amount)
            {
                //Cannot be greater than request
                MessageBox.Show("Amount cannot be greater than the order.", "Notice!", MessageBoxButton.OK);
                return;
            }

            if (App.MarketList[App.exchange_market].base_wallet == 3 || App.MarketList[App.exchange_market].trade_wallet == 3)
            {
                //Make sure amount is greater than ndexfee x 2
                if (amount < App.ndex_fee * 2)
                {
                    MessageBox.Show("This order amount is too small. Must be at least twice the CN fee (" + String.Format(CultureInfo.InvariantCulture, "{0:0.########}", App.ndex_fee * 2) + " NDEX)", "Notice!", MessageBoxButton.OK);
                    return;
                }
            }

            string  msg       = "";
            decimal mybalance = 0;
            int     mywallet  = 0;

            //Now check the balances
            if (window_order.type == 1)                                       //They are selling, so we are buying
            {
                mybalance = total;                                            //Base pair balance
                mywallet  = App.MarketList[window_order.market].base_wallet;  //This is the base pair wallet
            }
            else                                                              //They are buying so we are selling
            {
                mybalance = amount;                                           //Base pair balance
                mywallet  = App.MarketList[window_order.market].trade_wallet; //This is the trade pair wallet
            }
            bool good = App.CheckWalletBalance(mywallet, mybalance, ref msg);

            if (good == true)
            {
                //Now check the fees
                good = App.CheckMarketFees(App.exchange_market, 1 - window_order.type, mybalance, ref msg, true);
            }

            if (good == false)
            {
                //Not enough funds or wallet unavailable
                MessageBox.Show(msg, "Notice!", MessageBoxButton.OK);
                return;
            }

            //Make sure that total is greater than blockrate for the base market and the amount is greater than blockrate for trade market
            decimal block_fee1 = 0;
            decimal block_fee2 = 0;
            int     trade_wallet_blockchaintype = App.GetWalletBlockchainType(App.MarketList[App.exchange_market].trade_wallet);
            int     base_wallet_blockchaintype  = App.GetWalletBlockchainType(App.MarketList[App.exchange_market].base_wallet);

            block_fee1 = App.blockchain_fee[trade_wallet_blockchaintype];
            block_fee2 = App.blockchain_fee[base_wallet_blockchaintype];

            //Now calculate the totals for ethereum blockchain
            if (trade_wallet_blockchaintype == 6)
            {
                block_fee1 = App.GetEtherContractTradeFee(App.Wallet.CoinERC20(App.MarketList[App.exchange_market].trade_wallet));
            }
            if (base_wallet_blockchaintype == 6)
            {
                block_fee2 = App.GetEtherContractTradeFee(App.Wallet.CoinERC20(App.MarketList[App.exchange_market].base_wallet));
            }

            if (total < block_fee2 || amount < block_fee1)
            {
                //The trade amount is too small
                MessageBox.Show("This trade amount is too small to match because it is lower than the blockchain fee.", "Notice!", MessageBoxButton.OK);
                return;
            }

            //ERC20 only check
            bool    sending_erc20 = false;
            decimal erc20_amount  = 0;
            int     erc20_wallet  = 0;

            if (window_order.type == 1 && App.Wallet.CoinERC20(App.MarketList[App.exchange_market].base_wallet) == true)
            {
                //Maker is selling so we are buying trade with ERC20
                sending_erc20 = true;
                erc20_amount  = total;
                erc20_wallet  = App.MarketList[App.exchange_market].base_wallet;
            }
            else if (window_order.type == 0 && App.Wallet.CoinERC20(App.MarketList[App.exchange_market].trade_wallet) == true)
            {
                //Maker is buying so we are selling trade that is also an ERC20
                sending_erc20 = true;
                erc20_amount  = amount;
                erc20_wallet  = App.MarketList[App.exchange_market].trade_wallet;
            }

            if (sending_erc20 == true)
            {
                //Make sure the allowance is there already
                decimal allowance = App.GetERC20AtomicSwapAllowance(App.GetWalletAddress(erc20_wallet), App.ERC20_ATOMICSWAP_ADDRESS, erc20_wallet);
                if (allowance < 0)
                {
                    MessageBox.Show("Error determining ERC20 token contract allowance, please try again.", "Notice!", MessageBoxButton.OK);
                    return;
                }
                else if (allowance < erc20_amount)
                {
                    //We need to increase the allowance to send to the atomic swap contract eventually
                    MessageBoxResult result = MessageBox.Show("Permission is required from this token's contract to send this amount to the NebliDex atomic swap contract.", "Confirmation", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                    if (result == MessageBoxResult.OK)
                    {
                        //Create a transaction with this permission to send up to this amount
                        allowance = 1000000;                         //1 million tokens by default
                        if (erc20_amount > allowance)
                        {
                            allowance = erc20_amount;
                        }
                        App.CreateAndBroadcastERC20Approval(erc20_wallet, allowance, App.ERC20_ATOMICSWAP_ADDRESS);
                        MessageBox.Show("Now please wait for your approval to be confirmed by the Ethereum network then try again.", "Notice!", MessageBoxButton.OK);
                    }
                    return;
                }
            }

            //Because tokens are indivisible at the moment, amounts can only be in whole numbers
            bool ntp1_wallet = App.IsWalletNTP1(App.MarketList[App.exchange_market].trade_wallet);

            if (ntp1_wallet == true)
            {
                if (Math.Abs(Math.Round(amount) - amount) > 0)
                {
                    MessageBox.Show("All NTP1 tokens are indivisible at this time. Must be whole amounts.", "Notice!", MessageBoxButton.OK);
                    return;
                }
                amount = Math.Round(amount);
            }

            //Cannot match order when another order is involved deeply in trade
            bool too_soon = false;

            lock (App.MyOpenOrderList){
                for (int i = 0; i < App.MyOpenOrderList.Count; i++)
                {
                    if (App.MyOpenOrderList[i].order_stage > 0)
                    {
                        too_soon = true; break;
                    }                                                                                 //Your maker order is matching something
                    if (App.MyOpenOrderList[i].is_request == true)
                    {
                        too_soon = true; break;
                    }                                                                                    //Already have another taker order
                }
            }

            if (too_soon == true)
            {
                MessageBox.Show("Another order is currently involved in trade. Please wait and try again.", "Notice!", MessageBoxButton.OK);
                return;
            }

            //Check to see if any other open orders of mine
            if (App.MyOpenOrderList.Count >= App.total_markets)
            {
                MessageBox.Show("You have exceed the maximum amount (" + App.total_markets + ") of open orders.", "Notice!", MessageBoxButton.OK);
                return;
            }

            //Everything is good, create the request now
            //This will be a match open order (different than a general order)
            App.OpenOrder ord = new App.OpenOrder();
            ord.is_request      = true;        //Match order
            ord.order_nonce     = window_order.order_nonce;
            ord.market          = window_order.market;
            ord.type            = 1 - window_order.type;  //Opposite of the original order type
            ord.price           = window_order.price;
            ord.amount          = amount;
            ord.original_amount = amount;
            ord.order_stage     = 0;
            ord.my_order        = true;      //Very important, it defines how much the program can sign automatically

            //Try to submit order request to CN
            Match_Button.IsEnabled = false;
            Match_Button.MinWidth  = 150;
            Match_Button.Content   = "Contacting CN...";           //This will allow us to wait longer as user is notified
            bool worked = await Task.Run(() => App.SubmitMyOrderRequest(ord));

            if (worked == true)
            {
                //Add to lists and close form
                if (App.MyOpenOrderList.Count > 0)
                {
                    //Close all the other open orders until this one is finished
                    await Task.Run(() => App.QueueAllOpenOrders());
                }

                lock (App.MyOpenOrderList){
                    App.MyOpenOrderList.Add(ord);                     //Add to our own personal list
                }
                Window1.PendOrder(ord.order_nonce);
                App.main_window.Open_Orders_List.Items.Refresh();
                this.Close(); return;
            }
            Match_Button.MinWidth  = 120;
            Match_Button.Content   = "Match";
            Match_Button.IsEnabled = true;
        }
Exemplo n.º 3
0
        private async void Make_Order(object sender, RoutedEventArgs e)
        {
            //Create our order!
            //Get the price
            if (App.IsNumber(Price_Input.Text) == false)
            {
                return;
            }
            if (Price_Input.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }
            decimal price = decimal.Parse(Price_Input.Text, CultureInfo.InvariantCulture);

            if (price <= 0)
            {
                return;
            }
            if (price > App.max_order_price)
            {
                //Price cannot exceed the max
                MessageBox.Show("This price is higher than the maximum price of 10 000 000", "Notice!", MessageBoxButton.OK);
                return;
            }

            //Get the amount
            if (App.IsNumber(Amount_Input.Text) == false)
            {
                return;
            }
            if (Amount_Input.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }
            decimal amount = decimal.Parse(Amount_Input.Text, CultureInfo.InvariantCulture);

            if (amount <= 0)
            {
                return;
            }

            if (App.IsNumber(Min_Amount_Input.Text) == false)
            {
                return;
            }
            if (Min_Amount_Input.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }
            decimal min_amount = decimal.Parse(Min_Amount_Input.Text, CultureInfo.InvariantCulture);

            if (min_amount <= 0)
            {
                MessageBox.Show("The minimum amount is too small.", "Notice!", MessageBoxButton.OK);
                return;
            }
            if (min_amount > amount)
            {
                MessageBox.Show("The minimum amount cannot be greater than the amount.", "Notice!", MessageBoxButton.OK);
                return;
            }

            decimal total = Math.Round(price * amount, 8);

            if (Total_Input.Text.IndexOf(",") >= 0)
            {
                MessageBox.Show("NebliDex does not recognize commas for decimals at this time.", "Notice!", MessageBoxButton.OK);
                return;
            }

            if (App.MarketList[App.exchange_market].base_wallet == 3 || App.MarketList[App.exchange_market].trade_wallet == 3)
            {
                //Make sure amount is greater than ndexfee x 2
                if (amount < App.ndex_fee * 2)
                {
                    MessageBox.Show("This order amount is too small. Must be at least twice the CN fee (" + String.Format(CultureInfo.InvariantCulture, "{0:0.########}", App.ndex_fee * 2) + " NDEX)", "Notice!", MessageBoxButton.OK);
                    return;
                }
            }

            int    wallet = 0;
            string msg    = "";
            bool   good   = false;

            if (order_type == 0)
            {
                //This is a buy order we are making, so we need base market balance
                wallet = App.MarketList[App.exchange_market].base_wallet;
                good   = App.CheckWalletBalance(wallet, total, ref msg);
                if (good == true)
                {
                    //Now check the fees
                    good = App.CheckMarketFees(App.exchange_market, order_type, total, ref msg, false);
                }
            }
            else
            {
                //Selling the trade wallet amount
                wallet = App.MarketList[App.exchange_market].trade_wallet;
                good   = App.CheckWalletBalance(wallet, amount, ref msg);
                if (good == true)
                {
                    good = App.CheckMarketFees(App.exchange_market, order_type, amount, ref msg, false);
                }
            }

            //Show error messsage if balance not available
            if (good == false)
            {
                //Not enough funds or wallet unavailable
                MessageBox.Show(msg, "Notice!", MessageBoxButton.OK);
                return;
            }

            //Make sure that total is greater than blockrate for the base market and the amount is greater than blockrate for trade market
            decimal block_fee1 = 0;
            decimal block_fee2 = 0;
            int     trade_wallet_blockchaintype = App.GetWalletBlockchainType(App.MarketList[App.exchange_market].trade_wallet);
            int     base_wallet_blockchaintype  = App.GetWalletBlockchainType(App.MarketList[App.exchange_market].base_wallet);

            block_fee1 = App.blockchain_fee[trade_wallet_blockchaintype];
            block_fee2 = App.blockchain_fee[base_wallet_blockchaintype];

            //Now calculate the totals for ethereum blockchain

            //ERC20 tokens should not require a minimum trade amount (or maybe use double epsilon)

            if (trade_wallet_blockchaintype == 6)
            {
                block_fee1 = App.GetEtherContractTradeFee(App.Wallet.CoinERC20(App.MarketList[App.exchange_market].trade_wallet));
                if (App.Wallet.CoinERC20(App.MarketList[App.exchange_market].trade_wallet) == true)
                {
                    block_fee1 = Convert.ToDecimal(App.double_epsilon);                     // The minimum trade size for ERC20 tokens
                }
            }
            if (base_wallet_blockchaintype == 6)
            {
                block_fee2 = App.GetEtherContractTradeFee(App.Wallet.CoinERC20(App.MarketList[App.exchange_market].base_wallet));
                if (App.Wallet.CoinERC20(App.MarketList[App.exchange_market].base_wallet) == true)
                {
                    block_fee2 = Convert.ToDecimal(App.double_epsilon);                     // The minimum trade size for ERC20 tokens
                }
            }

            if (total < block_fee2 || amount < block_fee1)
            {
                //The trade amount is too small
                MessageBox.Show("This trade amount is too small to create because it is lower than the blockchain fee.", "Notice!", MessageBoxButton.OK);
                return;
            }

            //ERC20 only check
            bool    sending_erc20 = false;
            decimal erc20_amount  = 0;
            int     erc20_wallet  = 0;

            if (order_type == 0 && App.Wallet.CoinERC20(App.MarketList[App.exchange_market].base_wallet) == true)
            {
                //Buying trade with ERC20
                sending_erc20 = true;
                erc20_amount  = total;
                erc20_wallet  = App.MarketList[App.exchange_market].base_wallet;
            }
            else if (order_type == 1 && App.Wallet.CoinERC20(App.MarketList[App.exchange_market].trade_wallet) == true)
            {
                //Selling trade that is also an ERC20
                sending_erc20 = true;
                erc20_amount  = amount;
                erc20_wallet  = App.MarketList[App.exchange_market].trade_wallet;
            }

            if (sending_erc20 == true)
            {
                //And now look at all your other open orders on the exhange that send this token
                lock (App.MyOpenOrderList){
                    for (int i = 0; i < App.MyOpenOrderList.Count; i++)
                    {
                        if (App.MyOpenOrderList[i].type == 0 && App.MarketList[App.MyOpenOrderList[i].market].base_wallet == erc20_wallet)
                        {
                            //We are sending this token in another order, add it to the erc20_amount
                            erc20_amount += Math.Round(App.MyOpenOrderList[i].price * App.MyOpenOrderList[i].amount, 8);
                        }
                        else if (App.MyOpenOrderList[i].type == 1 && App.MarketList[App.MyOpenOrderList[i].market].trade_wallet == erc20_wallet)
                        {
                            erc20_amount += App.MyOpenOrderList[i].amount;
                        }
                    }
                }

                //Make sure the allowance is there already
                decimal allowance = App.GetERC20AtomicSwapAllowance(App.GetWalletAddress(erc20_wallet), App.ERC20_ATOMICSWAP_ADDRESS, erc20_wallet);
                if (allowance < 0)
                {
                    MessageBox.Show("Error determining ERC20 token contract allowance, please try again.", "Notice!", MessageBoxButton.OK);
                    return;
                }
                else if (allowance < erc20_amount)
                {
                    //We need to increase the allowance to send to the atomic swap contract eventually
                    MessageBoxResult result = MessageBox.Show("Permission is required from this token's contract to send this amount to the NebliDex atomic swap contract.", "Confirmation", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                    if (result == MessageBoxResult.OK)
                    {
                        //Create a transaction with this permission to send up to this amount
                        allowance = 1000000;                         //1 million tokens by default
                        if (erc20_amount > allowance)
                        {
                            allowance = erc20_amount;
                        }
                        App.CreateAndBroadcastERC20Approval(erc20_wallet, allowance, App.ERC20_ATOMICSWAP_ADDRESS);
                        MessageBox.Show("Now please wait for your approval to be confirmed by the Ethereum network then try again.", "Notice!", MessageBoxButton.OK);
                    }
                    return;
                }
            }

            //Because tokens are indivisible at the moment, amounts can only be in whole numbers
            bool ntp1_wallet = App.IsWalletNTP1(App.MarketList[App.exchange_market].trade_wallet);

            if (ntp1_wallet == true)
            {
                if (Math.Abs(Math.Round(amount) - amount) > 0)
                {
                    MessageBox.Show("All NTP1 tokens are indivisible at this time. Must be whole amounts.", "Notice!", MessageBoxButton.OK);
                    return;
                }
                amount = Math.Round(amount);

                if (Math.Abs(Math.Round(min_amount) - min_amount) > 0)
                {
                    MessageBox.Show("All NTP1 tokens are indivisible at this time. Must be whole minimum amounts.", "Notice!", MessageBoxButton.OK);
                    return;
                }
                min_amount = Math.Round(min_amount);
            }

            //Check to see if any other open orders of mine
            if (App.MyOpenOrderList.Count >= App.total_markets)
            {
                MessageBox.Show("You have exceed the maximum amount (" + App.total_markets + ") of open orders.", "Notice!", MessageBoxButton.OK);
                return;
            }

            App.OpenOrder ord = new App.OpenOrder();
            ord.order_nonce     = App.GenerateHexNonce(32);
            ord.market          = App.exchange_market;
            ord.type            = order_type;
            ord.price           = Math.Round(price, 8);
            ord.amount          = Math.Round(amount, 8);
            ord.minimum_amount  = Math.Round(min_amount, 8);
            ord.original_amount = amount;
            ord.order_stage     = 0;
            ord.my_order        = true;      //Very important, it defines how much the program can sign automatically

            //Try to submit order to CN
            Order_Button.IsEnabled = false;
            Order_Button.Content   = "Contacting CN...";           //This will allow us to wait longer
            bool worked = await Task.Run(() => App.SubmitMyOrder(ord, null));

            if (worked == true)
            {
                //Add to lists and close order
                lock (App.MyOpenOrderList){
                    App.MyOpenOrderList.Add(ord);                     //Add to our own personal list
                }
                lock (App.OpenOrderList[App.exchange_market]){
                    App.OpenOrderList[App.exchange_market].Add(ord);
                }
                App.main_window.AddOrderToView(ord);
                App.main_window.Open_Orders_List.Items.Refresh();
                App.AddSavedOrder(ord);
                this.Close(); return;
            }
            Order_Button.Content   = "Create Order";
            Order_Button.IsEnabled = true;
        }