コード例 #1
0
        /// <summary>
        /// Place a "Buy" order on the Kraken exchange market.
        /// </summary>
        /// <param name="assetName"></param>
        /// <param name="price"></param>
        /// <param name="ratio"></param>
        /// <param name="dt"></param>
        /// <param name="dry"></param>
        /// <returns>true if the order is properly placed, false otherwise.</returns>
        public virtual bool Buy(AssetSymbol assetName, double price, double ratio, DateTime?dt, bool dry)
        {
            if ((ratio == 0) || (_privateAPI == false))
            {
                return(false);
            }
            var dd = dt ?? DateTime.Now;

            var fiatSymbol   = assetName.QuoteName;                 // "XRPEUR" => "ZEUR"
            var assetSymbol  = assetName.SymbolName;
            var totalBalance = Balance(fiatSymbol);                 // Total balance of the portfolio on this exchange market
            var amount       = (totalBalance * ratio) / 100.0;      // Percentage of this total balance that can be used to place order.
            var bal          = Balances();
            var availBalance = (double)bal[fiatSymbol];             // Available money for trading.

            if (amount > availBalance)
            {
                amount = availBalance;
            }
            var qty = amount / price;

            if (qty >= assetName.OrderMin)
            {
                _logger.Info("Place Order: Buy (" + assetSymbol + ") - Quantity: " + qty + " - Price:" + price + " - Total: " + amount + " " + assetName.QuoteName);
                var order = RetryHelper <KrakenPlacedOrder> .RetryOnException(_retryTimes, _retryDelay, () => kc.PlaceOrder(assetSymbol, OrderSide.Buy, OrderType.Market, quantity: (decimal)qty, validateOnly: dry));

                RateLimiterPenality += 3000;
                return(order.Success);
            }

            return(false);
        }
コード例 #2
0
        /// <summary>
        /// Return the prices history for a given asset
        /// </summary>
        /// <param name="assetName">An normalized asset built from a normalized symbol name.</param>
        /// <returns></returns>
        public virtual Dictionary <double, double> PricesHistory(AssetSymbol assetName)
        {
            // To Do: Return here the Prices History on the specified symbol
            var db = new Dictionary <double, double>();

            return(db);
        }
コード例 #3
0
        /// <summary>
        /// The recent trades history for a given symbol
        /// </summary>
        /// <param name="assetName"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public virtual KrakenTradesResult TradesHistory(AssetSymbol assetName, DateTime dt)
        {
            var l = RetryHelper <KrakenTradesResult> .RetryOnException(_retryTimes, _retryDelay, () => kc.GetRecentTrades(assetName.SymbolName, dt));

            RateLimiterPenality += 6000;
            return(l.Data);
        }
コード例 #4
0
        /// <summary>
        /// Place a 'fake' order on the 'fake' exchange market
        /// </summary>
        /// <param name="assetName"></param>
        /// <param name="orderType"></param>
        /// <param name="dt"></param>
        /// <param name="price"></param>
        /// <param name="amount"></param>
        /// <returns></returns>
        protected virtual bool PlaceOrder(AssetSymbol assetName, Trade.TOrderType orderType, DateTime dt, double price, double amount)
        {
            var t = new Trade();

            t.Timestamp = dt;
            t.RefPrice  = price;
            t.OrderType = orderType;
            t.Asset     = assetName;

            var     bal     = Balances(dt);
            var     balance = bal[assetName.BaseName];
            var     fees    = Fees((price * amount), orderType);
            decimal total   = (decimal)((price * amount) - fees);

            t.Quantity = (double)amount;
            if (orderType == Trade.TOrderType.Buy)
            {
                balance += (decimal)amount;
                _assetPortfolio[assetName.QuoteName] -= (double)total;
            }
            else
            {
                balance -= (decimal)amount;
                _assetPortfolio[assetName.QuoteName] += (double)total;
            }

            _assetPortfolio[assetName.BaseName] = (double)balance;

            _tradeHistory.Add(t);
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// The current price for a given asset
        /// </summary>
        /// <param name="assetName"></param>
        /// <returns></returns>
        public virtual double MarketPrice(AssetSymbol assetName)
        {
            var mk = RetryHelper <Dictionary <string, KrakenRestTick> > .RetryOnException(_retryTimes, _retryDelay, () => kc.GetTickers(symbols: assetName.SymbolName));

            RateLimiterPenality += 6000;
            return((double)mk.Data[assetName.SymbolName].LastTrade.Price);
        }
コード例 #6
0
        /// <summary>
        /// Place a 'fake' buy order
        /// </summary>
        /// <param name="assetName"></param>
        /// <param name="price"></param>
        /// <param name="ratio"></param>
        /// <param name="dt"></param>
        /// <param name="dry"></param>
        /// <returns></returns>
        public override bool Buy(AssetSymbol assetName, double price, double ratio, DateTime?dt, bool dry)
        {
            if (ratio == 0)
            {
                return(false);
            }
            var dd = dt ?? DateTime.Now;

            var fiatSymbol   = assetName.QuoteName;                 // "XRPEUR" => "ZEUR"
            var assetSymbol  = assetName.SymbolName;
            var bal          = Balances(dd);
            var availBalance = (double)bal[fiatSymbol];             // Available money for trading.
            var totalBalance = Balance(fiatSymbol);                 // Total balance of the portfolio on this exchange market
            var amount       = (totalBalance * ratio) / 100.0;      // Percentage of this total balance that can be used to p

            if (amount > availBalance)
            {
                amount = availBalance;
            }

            var qty = amount / price;

            if (qty >= assetName.OrderMin)
            {
                NLog.LogManager.GetCurrentClassLogger().Info(dd + "|Place Order: Buy (" + assetSymbol + ") - Quantity: " + qty + " - Price:" + price + " - Total: " + amount + " " + assetName.QuoteName);
                var success = PlaceOrder(assetName, Trade.TOrderType.Buy, dd, price, qty);
                RateLimiterPenality += 3000;
                return(success);
            }

            return(false);
        }
コード例 #7
0
        /// <summary>
        /// Get the prices history for a given asset
        /// </summary>
        /// <param name="assetName">The nqme of the asset to get the price history</param>
        /// <returns>list of prices</returns>
        public override Dictionary <double, double> PricesHistory(AssetSymbol assetName)
        {
            var con = ExportTradesOnDB(assetName);

            // Get all prices
            var cmd = new SQLiteCommand(con);

            cmd.CommandText = @"SELECT timestamp, price FROM history ORDER BY timestamp";
            cmd.ExecuteNonQuery();

            using SQLiteDataReader rdr = cmd.ExecuteReader();
            var _dict = new Dictionary <double, double>();

            while (rdr.Read())
            {
                var timestamp = (Int64)rdr["timestamp"];
                var dt        = new DateTime(timestamp);
                var oa        = (double)dt.ToOADate();

                var r = (double)rdr["price"];

                if (_dict.ContainsKey(oa))
                {
                    _dict[oa] = r;
                }
                else
                {
                    _dict.Add(oa, r);
                }
            }
            _priceHistory.Add(assetName.BaseName, _dict);
            return(_dict);
        }
コード例 #8
0
        /// <summary>
        /// Normalize a given symbol name, like "XRPEUR" to the equivalent for Kraken Symbol.
        /// </summary>
        /// <param name="symbol">The symbol name (ex: "XRPEUR")</param>
        /// <returns>A generic Asset name object. </returns>
        public virtual AssetSymbol NormalizeSymbolName(string symbol)
        {
            var sym = RetryHelper <Dictionary <string, KrakenSymbol> > .RetryOnException(_retryTimes, _retryDelay, () => kc.GetSymbols(symbols: symbol));

            RateLimiterPenality += 3000;
            var asset = new AssetSymbol(sym.Data.First().Key, sym.Data.First().Value.BaseAsset, sym.Data.First().Value.QuoteAsset);

            asset.OrderMin = (double)sym.Data.First().Value.OrderMin;
            return(asset);
        }
コード例 #9
0
        /// <summary>
        /// Place a 'fake' sell order
        /// </summary>
        /// <param name="assetName"></param>
        /// <param name="marketPrice"></param>
        /// <param name="ratio"></param>
        /// <param name="dt"></param>
        /// <param name="dry"></param>
        /// <returns></returns>
        public override bool Sell(AssetSymbol assetName, double marketPrice, double ratio, DateTime?dt, bool dry)
        {
            var dd = dt ?? DateTime.Now;

            var bal = Balances(dd);
            var qty = bal[assetName.BaseName];

            if (qty > 0)
            {
                NLog.LogManager.GetCurrentClassLogger().Info(dd + "|Place Order: Sell (" + assetName.SymbolName + ") - Quantity: " + (double)qty + " - Price:" + marketPrice + " - Total: " + (double)qty * marketPrice + " " + assetName.QuoteName);
                var success = PlaceOrder(assetName, Trade.TOrderType.Sell, dd, marketPrice, (double)qty);
                RateLimiterPenality += 3000;
                return(success);
            }

            return(false);
        }
コード例 #10
0
        /// <summary>
        /// Get the latest trades done for a given asset name
        /// </summary>
        /// <param name="assetName">The asset name to retreive the trade history on.</param>
        /// <returns></returns>
        public virtual Trade LatestTrade(AssetSymbol assetName)
        {
            var mk = RetryHelper <KrakenUserTradesPage> .RetryOnException(_retryTimes, _retryDelay, () => kc.GetTradeHistory());

            RateLimiterPenality += 6000;
            var rt = mk.Data.Trades.FirstOrDefault(x => x.Value.Symbol == assetName.SymbolName);

            if (rt.Value == null)
            {
                return(null);
            }

            var trade = new Trade();

            trade.RefPrice  = (double)rt.Value.Price;
            trade.OrderType = rt.Value.Side == Kraken.Net.Objects.OrderSide.Buy?Trade.TOrderType.Buy:Trade.TOrderType.Sell;

            return(trade);
        }
コード例 #11
0
        /// <summary>
        /// Place a "Sell" order on the Kraken exchange market.
        /// </summary>
        /// <param name="assetName">The crypto asset to sell for a given currency. ex: "BTCEUR" ></param>
        /// <param name="price">The wanted price (on the currency).</param>
        /// <param name="ratio">the pourcentage to qpply on the transaction.</param>
        /// <param name="dt">When schedule that order.</param>
        /// <param name="dry">Is it for real or not?</param>
        /// <returns>true if the order was properly placed, false otherwise.</returns>
        public virtual bool Sell(AssetSymbol assetName, double price, double ratio, DateTime?dt, bool dry)
        {
            if (_privateAPI == false)
            {
                return(false);
            }
            var dd = dt ?? DateTime.Now;

            var bal = Balances();
            var qty = bal[assetName.BaseName];

            if (qty > 0)
            {
                _logger.Info("Place Order: Sell (" + assetName.SymbolName + ") - Quantity: " + qty + " - Price:" + price + " - Total: " + (double)qty * price + " " + assetName.QuoteName);
                var order = RetryHelper <KrakenPlacedOrder> .RetryOnException(_retryTimes, _retryDelay, () => kc.PlaceOrder(assetName.SymbolName, OrderSide.Sell, OrderType.Market, quantity: (decimal)qty, validateOnly: dry));

                RateLimiterPenality += 3000;
                return(order.Success);
            }

            return(false);
        }
コード例 #12
0
        /// <summary>
        /// Get the latest transaction performed for a given asset
        /// </summary>
        /// <param name="assetName"></param>
        /// <returns></returns>
        public override Trade LatestTrade(AssetSymbol assetName)
        {
            if (_tradeHistory.Count == 0)
            {
                var tr = new Trade();
                tr.Asset = assetName;
                return(tr);
            }
            var hist = from h in _tradeHistory
                       where h.Asset.SymbolName == assetName.SymbolName
                       orderby h.Timestamp descending
                       select h;

            RateLimiterPenality += 6000;
            if (hist.Count() == 0)
            {
                var tr = new Trade();
                tr.Asset = assetName;
                return(tr);
            }

            return(hist.First());
        }
コード例 #13
0
        /// <summary>
        /// Get the price history for a given asset and store it into a sqlite DB.
        /// </summary>
        /// <param name="assetName"></param>
        /// <returns></returns>
        public SQLiteConnection ExportTradesOnDB(AssetSymbol assetName)
        {
            string cs  = @"URI=file:" + assetName.SymbolName + ".db";
            var    con = new SQLiteConnection(cs);

            con.Open();
            var cmd = new SQLiteCommand(con);

            cmd.CommandText = @"CREATE TABLE IF NOT EXISTS history (my_id integer PRIMARY KEY, timestamp integer, price double, amount double, unique (timestamp,price,amount))";
            cmd.ExecuteNonQuery();
            cmd.CommandText = @"CREATE TABLE IF NOT EXISTS lastcheck (timestamp integer)";
            cmd.ExecuteNonQuery();


            cmd.CommandText = @"SELECT COUNT(*) FROM history";
            var count = Convert.ToInt32(cmd.ExecuteScalar());
            var dt    = new DateTime(2008, 1, 1, 0, 0, 0);

            if (count != 0)
            {
                cmd.CommandText = @"SELECT * FROM lastcheck";
                using (SQLiteDataReader rdr = cmd.ExecuteReader())
                {
                    if (rdr.HasRows)
                    {
                        if (rdr.Read())
                        {
                            var timestamp = rdr.GetInt64(0);
                            dt = new DateTime(timestamp);
                        }
                    }
                }
            }
            else
            {
                cmd.CommandText = @"INSERT INTO lastcheck (timestamp) VALUES (@timestamp)";
                cmd.Parameters.AddWithValue("@timestamp", dt.Ticks);
                cmd.Prepare();
                cmd.ExecuteNonQuery();
            }

            bool fullyUpdated = false;

            while (!fullyUpdated)
            {
                var trades = TradesHistory(assetName, dt);
                using (var transaction = con.BeginTransaction())
                {
                    foreach (var it in trades.Data)
                    {
                        cmd.CommandText = @"INSERT OR IGNORE INTO history(timestamp, price, amount) VALUES (@timestamp, @price, @amount)";
                        cmd.Parameters.AddWithValue("@timestamp", it.Timestamp.Ticks);
                        cmd.Parameters.AddWithValue("@price", it.Price);
                        cmd.Parameters.AddWithValue("@amount", it.Quantity);
                        cmd.Prepare();
                        cmd.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }


                dt = trades.Last;
                cmd.CommandText = @"UPDATE lastcheck SET timestamp = '" + dt.Ticks + "'";
                cmd.ExecuteNonQuery();


                if (trades.Data.Count() < 1000)
                {
                    fullyUpdated = true;
                }

                base.PreventRateLimit(); // To avoid a rate limit exception on Kraken API public calls.
            }

            return(con);
        }