Exemple #1
0
        public static List <Candle> GetCandles(string instrumentID, CandleType type, DateTime fromTradingDay)
        {
            List <Candle> minuteCandles = CandleDAL.Get(instrumentID, fromTradingDay);

            if (type == CandleType.Minute)
            {
                return(minuteCandles);
            }
            else
            {
                return(CandleHelper.ConvertCandleToCandle(minuteCandles, type));
            }
        }
Exemple #2
0
        public void StartWork()
        {
            if (Working)
            {
                return;
            }
            if (Done)
            {
                return;
            }

            _thread = new Thread(() => {
                Working = true;
                Done    = false;
                CandleHelper.RetrieveCandles(Symbol, Interval, Start, End);
                Working = false;
                Done    = true;
            });

            _thread.Start();
        }
        public string Backtest(string source, string market, KlineInterval kline, DateTime start, DateTime end, StrategyOptions actStrat)
        {
            //var source = "";
            //var market = "BTCTUSDT";
            //var kline = Binance.Net.Objects.KlineInterval.FifteenMinutes;
            //var start = new DateTime(2019, 11, 1);
            //var end = new DateTime(2019, 12, 30);
            //var actStrat = new StrategyOptions();

            // get all candles
            CandleHelper.RetrieveCandles(market, kline, start, end);


            DateTime          small      = DateTime.MinValue;
            DateTime          big        = DateTime.MinValue;
            List <CandleInfo> allCandles = null;


            if (!CandleHelper.CandlesAvailable(market, kline, start, end, out small, out big, out allCandles))
            {
                return("no candles available");
            }



            var temp = new Context(allCandles);


            temp.ActiveStrategyOptions = Globals.ActiveStrategyOptions;
            if (!CryptoGlobals.RunScript(source, ref temp))
            {
                return("error in script: " + temp.SCRIPT_ERROR);
            }



            var c = new Context(allCandles);

            c.ActiveStrategyOptions = actStrat;

            var startingBalance = c.ActiveStrategyOptions.BacktestStartingBalance;

            var originalBalance = startingBalance;

            var l = new List <CandleInfo>();

            dynamic script = CSScript.RoslynEvaluator.LoadCode(source);

            foreach (var item in allCandles)
            {
                l.Add(item);

                if (l.Count < 20)
                {
                    continue;
                }

                c.RawCandles = l;

                try
                {
                    script.OnData(c);
                }catch (Exception ex)
                {
                    return("error: " + ex.Message);
                }
            }


            foreach (var item in c.GetOpenOrders())
            {
                c.CloseOrder(item);
            }



            var orders = c.GetAllOrders();

            var candlesAndOrders = new SortedDictionary <DateTime, List <OrderInfo> >();

            foreach (var item in orders)
            {
                var buyDate  = item.BuyCandle.OpenTime;
                var sellDate = item.SellCandle.OpenTime;

                if (!candlesAndOrders.ContainsKey(buyDate))
                {
                    candlesAndOrders[buyDate] = new List <OrderInfo>();
                }

                if (!candlesAndOrders.ContainsKey(sellDate))
                {
                    candlesAndOrders[sellDate] = new List <OrderInfo>();
                }


                candlesAndOrders[buyDate].Add(item);
                candlesAndOrders[sellDate].Add(item);
            }

            candlesAndOrders.OrderBy(x => x.Key);



            var originalEquity = originalBalance;


            double finalEquity = 0f;

            var equityOrders = new Dictionary <string, OrderInfo>();

            List <OrderResultInfo> finalOrders = new List <OrderResultInfo>();

            double totalProfits = 0f;


            var tempCount       = 0;
            var alreadyAddedIds = new List <string>();

            foreach (var cao in candlesAndOrders)
            {
                var currDate  = cao.Key;
                var orderList = cao.Value;
                foreach (var item in orderList)
                {
                    tempCount++;

                    var isSell = false;
                    if (alreadyAddedIds.Contains(item.Id))
                    {
                        isSell = true;
                    }
                    else
                    {
                        alreadyAddedIds.Add(item.Id);
                    }

                    var ord = item;

                    var      id = ord.Id;
                    string   type;
                    DateTime time;
                    double   orderPrice = 0.0f;;
                    double   size       = ord.BuyAmountInUSD;
                    double   profitLoss = 0f;
                    double   balance    = 0f;



                    if (isSell == false) // buy
                    {
                        originalBalance -= ord.BuyAmountInUSD;

                        originalBalance = Math.Round(originalBalance, 2);

                        time       = ord.BuyCandle.OpenTime;
                        type       = "Buy";
                        orderPrice = Math.Round(ord.BuyPrice, 2);

                        equityOrders[ord.Id] = ord;
                    }
                    else // sell
                    {
                        var tUsd = ord.TotalUSD();
                        tUsd = Math.Round(tUsd, 2);

                        originalBalance += tUsd;

                        originalBalance = Math.Round(originalBalance, 2);

                        time = ord.SellCandle.OpenTime;
                        type = "Sell";
                        var tmpPL = Math.Round(tUsd - ord.BuyAmountInUSD, 2);
                        profitLoss = tmpPL;
                        balance    = originalBalance;
                        balance    = Math.Round(balance, 2);


                        totalProfits += tmpPL;

                        orderPrice = Math.Round(ord.GetSellPrice(), 2);

                        equityOrders.Remove(ord.Id);
                    }


                    size = Math.Round(size, 8);


                    var finalBalance = balance;// (isSell) ? "$ " + balance.ToString() : "";

                    finalEquity = 0f;


                    CandleInfo tempCandle = (isSell) ? orderList[0].SellCandle : orderList[0].BuyCandle;

                    double ttttemp = 0f;
                    foreach (var eOrd in equityOrders.Values)
                    {
                        finalEquity += tempCandle.MidPrice * ord.CoinAmount;
                        ttttemp     += ord.BuyAmountInUSD;
                    }

                    ttttemp = Math.Round(ttttemp, 3);

                    finalEquity = Math.Round(finalEquity, 3);

                    var ori = new OrderResultInfo()
                    {
                        Id = id.ToString(), Time = time, Type = type, OrderPrice = orderPrice, OrderAmountUSD = size, ProfitLoss = profitLoss, FinalBalance = finalBalance, FinalEquity = finalEquity
                    };
                    finalOrders.Add(ori);
                }
            }

            var finalPL = Math.Round(originalBalance - startingBalance, 2);

            finalOrders.Add(new OrderResultInfo()
            {
                Id = "", Time = DateTime.MinValue, Type = "blank", OrderPrice = 0f, OrderAmountUSD = 0f, ProfitLoss = 0f, FinalBalance = 0f
            });
            finalOrders.Add(new OrderResultInfo()
            {
                Id = "", Time = DateTime.MinValue, Type = "blank2", OrderPrice = 0f, OrderAmountUSD = 0f, ProfitLoss = finalPL, FinalBalance = originalBalance
            });

            var final = JsonConvert.SerializeObject(finalOrders);

            return(final);
        }
Exemple #4
0
        public ActionResult <string> Get(string Symbol)
        {
            var RequestData = new Dictionary <string, string>();

            RequestData = CryptoGlobals.GetRequestData(Request);

            Symbol = Symbol.Replace("-", "");

            var interval = KlineInterval.FifteenMinutes;
            var start    = new DateTime(2019, 7, 1);
            var end      = DateTime.Now;
            var symbol   = Symbol.ToUpper();

            var liteJson = false;
            var justOK   = false;
            var jsonP    = "";



            if (RequestData.ContainsKey("interval"))
            {
                var tempInterval = RequestData["interval"].ToString();

                interval = CryptoGlobals.GetKlineFromString(tempInterval);
            }
            else
            {
                return("interval missing");
            }

            Response.Headers.Add("Access-Control-Allow-Origin", "*");

            if (RequestData.ContainsKey("jsonp"))
            {
                jsonP = RequestData["jsonp"];
            }

            if (RequestData.ContainsKey("justok"))
            {
                justOK = true;
            }

            if (RequestData.ContainsKey("lite") && RequestData["lite"] == "true")
            {
                liteJson = true;
            }

            if (RequestData.ContainsKey("start") && RequestData.ContainsKey("end"))
            {
                var startS = RequestData["start"].ToString();
                var endS   = RequestData["end"].ToString();

                DateTime dt1;
                if (DateTime.TryParseExact(startS,
                                           "yyyy-MM-dd",
                                           CultureInfo.InvariantCulture,
                                           DateTimeStyles.None,
                                           out dt1))
                {
                    start = dt1;
                }
                else
                {
                    return("Invalid start date");
                }

                DateTime dt2;
                if (DateTime.TryParseExact(endS,
                                           "yyyy-MM-dd",
                                           CultureInfo.InvariantCulture,
                                           DateTimeStyles.None,
                                           out dt2))
                {
                    end = dt2.AddDays(1); // because we are NOT getting time. So we want to get UNTIL the next day
                    if (end > DateTime.Now)
                    {
                        end = DateTime.Now;
                    }
                }
                else
                {
                    return("Invalid end date");
                }
            }
            else
            {
                return(JsonConvert.SerializeObject(new KeyValuePair <string, string>("Error", "You have to use start & date query")));
            }


            if (!CandleHelper.Jobs.ContainsKey(symbol) || (CandleHelper.Jobs.ContainsKey(symbol) && CandleHelper.Jobs[symbol].Done))
            {
                if (CandleHelper.Jobs.ContainsKey(symbol))
                {
                    CandleHelper.Jobs.Remove(symbol);
                }



                DateTime          small      = DateTime.MinValue;
                DateTime          big        = DateTime.MinValue;
                List <CandleInfo> allCandles = null;

                if (CandleHelper.CandlesAvailable(symbol, interval, start, end, out small, out big, out allCandles))
                {
                    var finalS = "";

                    if (justOK)
                    {
                        finalS = "ok";
                    }
                    else
                    {
                        if (liteJson)
                        {
                            var temp = new List <CandleInfo>();
                            foreach (var item in allCandles)
                            {
                                temp.Add(item); // timestamp, o,h,l,c
                                                // highchart requires timestamp*1000 or else dates are invalid
                            }

                            finalS = JsonConvert.SerializeObject(temp);
                        }
                        else
                        {
                            finalS = JsonConvert.SerializeObject(allCandles);
                        }
                    }



                    //Response.ContentType = "application/javascript";
                    if (jsonP != "")
                    {
                        return(jsonP + "(" + finalS + ")");
                    }
                    return(finalS);


                    // let's retrieve em all??
                    return("Small: " + small.ToString() + Environment.NewLine + "Big: " + big.ToString());
                }
                else
                {
                    if (big == DateTime.MinValue)
                    {
                        big = start;
                    }
                    else
                    {
                        big = big.MinusKlineInterval(interval).MinusKlineInterval(interval);
                    }
                    CandleHelper.Jobs[symbol] = new CandleJob(symbol, start, end, interval); // we just started the job
                    CandleHelper.Jobs[symbol].StartWork();

                    return("working");
                }
            }
            else
            {
                return("working");
            }
        }
Exemple #5
0
        public static void FillMarketsInDB(bool updatePrices = true)
        {
            bool shouldUpdate = false;

            var tempDt = DBHelper.GetDataTable("SELECT * FROM Markets");

            if (tempDt.Rows.Count > 0)
            {
                // we already have markets. But maybe update the prices.
                if (!updatePrices)
                {
                    return;
                }

                shouldUpdate = true;
            }

            var markets24 = CryptoGlobals.adminBinanceClient.Get24HPricesList();

            if (markets24 != null && markets24.Data != null && markets24.Data.Count() > 0)
            {
                // all good
            }
            else
            {
                return;
            }
            var finalMarkets = new List <Binance24HPrice>();

            foreach (var item in markets24.Data)
            {
                if (CryptoGlobals.GoodMarkets.Contains(item.Symbol))
                {
                    finalMarkets.Add(item);
                }
            }


            List <SQLiteCommand> list = new List <SQLiteCommand>();

            foreach (var item in finalMarkets)
            {
                SQLiteCommand com = new SQLiteCommand();

                if (!shouldUpdate)
                {
                    com.CommandText = "INSERT OR IGNORE INTO Markets " +
                                      "(Symbol,Enabled,Volume,FirstCandleTime,LastPrice) " +
                                      "VALUES (@Symbol,@Enabled,@Volume,@FirstCandleTime,@LastPrice)";
                }
                else
                {
                    com.CommandText = "UPDATE Markets SET LastPrice=@LastPrice WHERE Symbol=@Symbol";
                }

                com.Parameters.AddWithValue("@Volume", item.QuoteVolume);
                com.Parameters.AddWithValue("@FirstCandleTime", CandleHelper.GetFirstCandleDate(item.Symbol).ToSqlDateString());
                com.Parameters.AddWithValue("@Enabled", 1);

                com.Parameters.AddWithValue("@Symbol", item.Symbol);
                com.Parameters.AddWithValue("@LastPrice", item.LastPrice);

                list.Add(com);
            }

            DBHelper.BulkExecuteNonQuery(list);
        }
        private async Task RunAsync(CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                // get live orders


                if (AllMarkets == null)
                {
                    RefreshMarkets();
                }

                if (AllUsers == null)
                {
                    RefreshUsers();
                }


                if (AllContexts == null)
                {
                    AllContexts = new Dictionary <int, Context>();
                }


                foreach (DataRow row in DBHelper.dtJobs.Rows)
                {
                    var job = new JobInfo(row);

                    if (job.IsLive)
                    {
                        // grab the latest candles

                        var kline = CryptoGlobals.GetKlineFromString(job.Interval);
                        var c     = CryptoGlobals.LastCandleInDB(AllMarkets[job.MarketId].Symbol, kline);

                        var shouldGetCandles = false;
                        var firstDate        = DateTime.Today.AddDays(60);

                        if (c == null)
                        {
                            // ouch never got any candles :(
                            shouldGetCandles = true;
                        }
                        else
                        {
                            // we got, that's our start date

                            if (c.OpenTime < CryptoGlobals.MinusKlineInterval(DateTime.UtcNow, kline))
                            {
                                shouldGetCandles = true;
                                firstDate        = c.OpenTime;
                            }
                        }

                        if (shouldGetCandles)
                        {
                            CandleHelper.RetrieveCandles(AllMarkets[job.MarketId].Symbol, kline, firstDate, DateTime.Now.AddDays(1)); // TAKE IT ALLLLL
                        }

                        if (!AllUsers.ContainsKey(job.UserId))
                        {
                            AllUsers = null;
                            RefreshUsers();
                            if (!AllUsers.ContainsKey(job.UserId))
                            {
                                // invalid user
                                continue;
                            }
                        }



                        var user = AllUsers[job.UserId];


                        // get candles

                        var crows = DBHelper.GetDataTable("SELECT * FROM Candles WHERE Symbol='" + AllMarkets[job.MarketId].Symbol + "' AND Interval='" + job.Interval + "'"); // haha crows



                        List <CandleInfo> CurrentCandles = new List <CandleInfo>();

                        foreach (DataRow crow in crows.Rows)
                        {
                            var tempC = new CandleInfo(crow);

                            CurrentCandles.Add(tempC);
                        }

                        StrategyOptions myStrat = null;
                        var             strat   = DBHelper.GetDataTable("SELECT * from Strategies where Id=" + job.ScriptId);
                        if (strat.Rows.Count > 0)
                        {
                            myStrat = (new StrategyInfo(strat.Rows[0])).Options;
                        }
                        else
                        {
                            continue; // cancel!?!?
                        }



                        Context cxt = null;
                        if (!AllContexts.ContainsKey(job.Id))
                        {
                            cxt        = new Context(CurrentCandles);
                            cxt.IsLive = true;
                            cxt.User   = user;
                            cxt.ActiveStrategyOptions = new StrategyOptions()
                            {
                                BacktestStartingBalance = 1000000, Fees = 0, MaxOpenOrders = myStrat.MaxOpenOrders, MinutesInBetweenOrders = myStrat.MinutesInBetweenOrders
                            };
                        }
                        else
                        {
                            cxt            = AllContexts[job.Id];
                            cxt.RawCandles = CurrentCandles;
                        }



                        var l = new List <CandleInfo>();



                        if (CurrentCandles.Count == 0)
                        {
                            continue;
                        }


                        cxt.RawCandles = CurrentCandles;


                        if (cxt.IsLive && !cxt.IsPaper)
                        {
                            //var orders = CryptoGlobals.UserBinances[user.Username].GetOpenOrders();
                            //
                            //foreach (var item in orders.Data)
                            //{
                            //
                            //    if (item.Symbol != AllMarkets[job.MarketId].Symbol) continue;
                            //
                            //    var t = new OrderInfo(cxt, (float)(item.Price * item.ExecutedQuantity));
                            //    t.CoinAmount = (float)item.ExecutedQuantity;
                            //    t.IsOpen = true;
                            //    t.Id = item.ClientOrderId.ToString();
                            //}
                        }
                        else
                        {
                        }


                        if (!Globals.RunScript(cxt.StrategyScript, ref cxt))
                        {
                            continue;
                        }



                        // we now can run the script
                    }
                }


                System.Diagnostics.Debug.WriteLine(DateTime.Now);
                await Task.Delay(1000);
            }
        }