Exemple #1
0
        /// <summary>
        /// Update account balances and total USD value
        /// </summary>
        private void UpdateAccounts(object sender, EventArgs e)
        {
            try
            {
                var assets   = 0.0M;
                var balances = GeminiClient.GetBalances();
                foreach (var balance in balances)
                {
                    switch (balance.Currency)
                    {
                    case "BTC":
                        textboxBtcBalance.Text = balance.Amount.ToString();
                        assets += balance.Amount * LastTrades["btcusd"].Price;
                        break;

                    case "ETH":
                        textboxEthBalance.Text = balance.Amount.ToString();
                        assets += balance.Amount * LastTrades["ethusd"].Price;
                        break;

                    case "USD":
                        textboxUsdBalance.Text = balance.Amount.ToString();
                        assets += balance.Amount;
                        break;
                    }
                }
                labelAssetValue.Text = String.Format("Total Value: ${0}", Math.Round(assets, 2));
            }
            catch (Exception ex)
            {
                Logger.WriteException(Logger.Level.Error, ex);
            }
        }
Exemple #2
0
        public LibraMain()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.ProcessExit += Exit;

            /* Callback for API errors */
            GeminiClient.InstallErrorHandler(ErrorHandler);

            /* Update runtime clock every second  */
            runtime.Tick    += UpdateRuntime;
            runtime.Interval = 1000;
            runtime.Start();


            /* Also update account balance whenever API Keys are loaded */
            GeminiClient.Wallet.OnChange += UpdateAccounts;
            GeminiClient.Wallet.OnChange += OrderEventStart;
            GeminiClient.Wallet.OnChange += delegate(object sender, EventArgs e) { labelAddress.Text = GeminiClient.Wallet.Key(); };

            /* Initialize Websockets */
            InitialPrices();
            MarketDataStart();

            /* Websocket PriceChanged event handles ticker data and pending Stop orders */
            PriceChanged += UpdateTicker;
            PriceChanged += OrderTracker.CheckPendingOrders;

            /* Websocket OrderChanged event */
            OrderChanged += UpdateOrders;
        }
Exemple #3
0
 /// <summary>
 /// Check all orders in the pending queue, and execute if price condition is met.
 /// This is called by the OrderEvents websocket
 /// </summary>
 /// <param name="currency"></param>
 /// <param name="data"></param>
 public static void CheckPendingOrders(string currency, MarketDataEvent data)
 {
     Parallel.ForEach(Pending, order =>
     {
         var price = decimal.Parse(order.Price);
         if (order.Symbol == currency)
         {
             if (order.Side == "buy")
             {
                 /* If currenct price is above the stop-buy price, execute */
                 if (price <= data.Price)
                 {
                     order.Price          = (data.Price + 0.01M).ToString();
                     order.ClientOrderID += "STOP";
                     order.Options        = new string[] { "immediate-or-cancel" };
                     GeminiClient.PlaceOrder(order);
                     Pending.Remove(order);
                 }
             }
             else
             {
                 /* if curenct price is below the stop-loss price, execute */
                 if (price >= data.Price)
                 {
                     /* Decrease by 10, since this is still viewed as a limit order
                      * by the server, and this increases our chances of getting filled */
                     order.Price          = (data.Price - 0.01M).ToString();
                     order.ClientOrderID += "STOP";
                     GeminiClient.PlaceOrder(order);
                     Pending.Remove(order);
                 }
             }
         }
     });
 }
Exemple #4
0
 private void bNewAddress_Click(object sender, EventArgs e)
 {
     try
     {
         tbNewAddress.Text = GeminiClient.GetDepositAddress(cbAddress.Text, "LIBRA" + Time.Timestamp().ToString());
     }
     catch { }
 }
Exemple #5
0
 private void bWithdraw_Click(object sender, EventArgs e)
 {
     try
     {
         GeminiClient.Withdraw(cbWithdraw.Text, tbWithdrawAddress.Text, tbWithdrawAmount.Text);
         UpdateAccounts(null, null);
     }
     catch { }
 }
Exemple #6
0
 private void bMaxWithdraw_Click(object sender, EventArgs e)
 {
     try
     {
         tbWithdrawAmount.Text = GeminiClient.GetBalances()
                                 .First((x) => x.Currency == cbWithdraw.Text)
                                 .AvailableForWithdrawal.ToString();
     }
     catch { }
 }
Exemple #7
0
 public DataClient()
 {
     Binance  = new BinanceClient();
     Bitfinex = new BitfinexClient();
     Poloniex = new PoloniexClient();
     Bitstamp = new BitstampClient();
     Gdax     = new GdaxClient();
     Gemini   = new GeminiClient();
     Kraken   = new KrakenClient();
     Okex     = new OkexClient();
 }
Exemple #8
0
        public void LoadPastOrders(object sender, DoWorkEventArgs e)
        {
            string[] symbols = { "btcusd", "ethusd", "ethbtc" };

            foreach (var symbol in symbols)
            {
                foreach (var trade in GeminiClient.GetPastTrades(symbol, 50, 0))
                {
                    (sender as BackgroundWorker).ReportProgress(0, trade);
                }
            }
            ;
        }
Exemple #9
0
        /// <summary>
        /// Seed the last trade dictionary
        /// </summary>
        public void InitialPrices()
        {
            Parallel.ForEach(Symbols, s =>
            {
                var t         = GeminiClient.GetTicker(s);
                LastTrades[s] = new MarketDataEvent()
                {
                    Price = t.Last,
                };
                PV[s] = t.Volume.Currency2;
                V[s]  = t.Volume.Currency1;
            });

            UpdateTicker(null, null);
        }
Exemple #10
0
        /// <summary>
        /// Cancel the order selected in the tree view object
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bCancelSelect_Click(object sender, EventArgs e)
        {
            if (treeOrders.SelectedNode == null)
            {
                return;
            }
            if (treeOrders.SelectedNode?.Level == 0)
            {
                return;
            }
            var node     = treeOrders.SelectedNode.Name;
            var selected = treeOrders.SelectedNode;

            /* This isn't really a *real* order yet */
            if (selected.Parent.Name == "Pending")
            {
                if ((bool)Properties.Settings.Default["RequireConfirmations"])
                {
                    if (MessageBox.Show("Confirm cancellation of order " + node, "Cancel Order", MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return;
                    }
                }
                OrderTracker.Pending.Remove(OrderTracker.Pending.Find((x) => x.ClientOrderID == node));
                selected.Remove();
            }

            /* Order is on the books */
            if (selected.Parent.Name == "Active")
            {
                if ((bool)Properties.Settings.Default["RequireConfirmations"])
                {
                    if (MessageBox.Show("Confirm cancellation of order " + node, "Cancel Order", MessageBoxButtons.YesNo) == DialogResult.No)
                    {
                        return;
                    }
                }
                try
                {
                    var res = GeminiClient.CancelOrder(int.Parse(selected.Text));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    Logger.WriteException(Logger.Level.Error, ex);
                }
            }
        }
Exemple #11
0
 private void bCancelSession_Click(object sender, EventArgs e)
 {
     if ((bool)Properties.Settings.Default["RequireConfirmations"])
     {
         if (MessageBox.Show("Confirm cancellation of session orders", "Cancel Order", MessageBoxButtons.YesNo) == DialogResult.No)
         {
             return;
         }
     }
     try
     {
         GeminiClient.CancelSession();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
         Logger.WriteException(Logger.Level.Error, ex);
     }
 }
Exemple #12
0
        /// <summary>
        /// Callback for when an order is placed, or status has changed
        /// </summary>
        /// <param name="state"></param>
        /// <param name="e"></param>
        private void UpdateOrders(string type, object data)
        {
            TreeNode[] found;

            // Handle "fake" order call, sent by application during refresh to check for pending orders,
            // per issue #2. data will be null
            if (type == "PENDING")
            {
                foreach (var n in OrderTracker.Pending)
                {
                    if ((found = treeOrders.Nodes["Pending"].Nodes.Find(n.ClientOrderID, false)).Count() == 0)
                    {
                        treeOrders.Nodes["Pending"].Nodes.Add(n.ClientOrderID, n.ClientOrderID);
                    }
                }
                return;
            }

            var order = (OrderEvent)data;

            if (type == "closed")
            {
                if ((found = treeOrders.Nodes.Find(order.OrderID, true)).Count() > 0)
                {
                    found.First().Remove();
                }

                OrderTracker.Orders[order.OrderID] = order;
                if (order.IsCancelled)
                {
                    if (order.ClientOrderID == null)
                    {
                        treeOrders.Nodes["Cancelled"].Nodes.Add(order.OrderID, order.OrderID);
                    }
                    else if (!order.ClientOrderID.Contains("STOP"))
                    {
                        treeOrders.Nodes["Cancelled"].Nodes.Add(order.OrderID, order.OrderID);
                    }
                }
                else if (order.ExecutedAmount == order.OriginalAmount)
                {
                    treeOrders.Nodes["Filled"].Nodes.Add(order.OrderID, order.OrderID);
                }
            }
            else if (type == "cancelled")
            {
                var cancel = (OrderEventCancelled)data;

                /*
                 * Our stop orders are placed as immediate or cancel.
                 * We will resubmit it at a slightly worse price, and try again until it succeeds
                 */
                if (cancel.RemainingAmount > 0 && cancel.ClientOrderID != null)
                {
                    if (cancel.ClientOrderID.Contains("STOP"))
                    {
                        var request = new NewOrderRequest()
                        {
                            Side          = order.Side,
                            Price         = Math.Round((cancel.Side == "buy" ? cancel.Price + .01M : cancel.Price - 0.01M), 2).ToString(),
                            Options       = new string[] { "immediate-or-cancel" },
                            Symbol        = cancel.Symbol,
                            Amount        = Math.Round(cancel.RemainingAmount, 8).ToString(),
                            ClientOrderID = String.Format("LIBRA_{0}STOP", DateTime.Now.ToTimestampMs()),
                            Type          = "exchange limit",
                        };
                        GeminiClient.PlaceOrder(request);
                    }
                }
            }
            else if (type == "booked" || type == "initial")
            {
                // Remove existing node from Pending, move it to Active
                if ((found = treeOrders.Nodes["Pending"].Nodes.Find(order.ClientOrderID, false)).Count() > 0)
                {
                    found.First().Remove();
                }

                treeOrders.Nodes["Active"].Nodes.Add(order.OrderID, order.OrderID);
                OrderTracker.Orders[order.OrderID] = order;
            }
            else if (type == "filled")
            {
                order = (OrderEventFilled)data;
                OrderTracker.Orders[order.OrderID] = order;
            }
            UpdateAccounts(null, null);
        }