private void UpdateClientStockOneDir(Direction dir, int precision, CCmdStockChange cmdSockChange) { lock (_outStock) { for (int j = 0; j < _store[precision][dir].Count; j++) { try { _outStock[dir][precision][j].Price = _store[precision][dir][j].Price; _outStock[dir][precision][j].Volume = CUtilConv.GetIntVolume(_store[precision][dir][j].Amount, _decimalVolume); } catch (Exception exc) { _client.Error("CbfxStockStor.UpdateClientStockOneDir", exc); } } for (int i = _store[precision][dir].Count; i < _outStock.Count - _store[precision][dir].Count; i++) { _outStock[dir][precision][i].Price = 0; _outStock[dir][precision][i].Volume = 0; } _outStock.InpCmdStockChange[dir][precision] = cmdSockChange; _outStock.UpdateBidAsk(); _client.UpdateClientStockOneDir(_instrument, dir, precision, _outStock); } }
public void UpdateOrInsert(int prec, decimal price, decimal amount, ref CCmdStockChange cmd, ref Direction dir) { dir = (amount > 0) ? Direction.Down : Direction.Up; decimal amountAbs = Math.Abs(amount); cmd.Volume = CUtilConv.GetIntVolume(amountAbs, _decimalVolume); for (int i = 0; i < _store[prec][dir].Count; i++) { if (_store[prec][dir][i].Price == price) { _store[prec][dir][i].Amount = amountAbs; Log(prec, String.Format("{0} price={1} amount={2}", "==> update", price, amountAbs)); //2018-06-27 perfomance // PrintStock(prec); cmd.Code = EnmStockChngCodes._04_Update; return; } } //cmd.Code = dir Log(prec, String.Format("{0} price={1} amount={2}", "==> add", price, amountAbs)); _store[prec][dir].Add(new CBfxStockRec { Price = price, Amount = Math.Abs(amountAbs) }); Sort(prec, dir); cmd.Code = EnmStockChngCodes._02_Add; //2018-06-27 perfomance //PrintStock(prec); /* CBfxStockRec rec = this[dir].Find(el => el.Price == price); * if (rec == null) * { * Log(String.Format("{0} price={1} amount={2}", "==> add", price, amount)); * this[dir].Add(new CBfxStockRec { Price = price, Amount = Math.Abs(amount) }); * Sort(dir); * } * else * { * Log(String.Format("{0} price={1} amount={2}", "==> update", price, amount)); * * rec.Amount = Math.Abs(amount); * } */ }
public void TestGetRoundTo() { Assert.AreEqual(CUtilConv.GetRoundTo(0.1m), 1); Assert.AreEqual(CUtilConv.GetRoundTo(0.2m), 1); Assert.AreEqual(CUtilConv.GetRoundTo(0.02m), 2); Assert.AreEqual(CUtilConv.GetRoundTo(0.002m), 3); Assert.AreEqual(CUtilConv.GetRoundTo(0.08m), 2); Assert.AreEqual(CUtilConv.GetRoundTo(0.02m), 2); Assert.AreEqual(CUtilConv.GetRoundTo(0.6m), 1); Assert.AreEqual(CUtilConv.GetRoundTo(190m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(0.04m), 2); Assert.AreEqual(CUtilConv.GetRoundTo(0.06m), 2); Assert.AreEqual(CUtilConv.GetRoundTo(14m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(6m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(2m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(8m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(1m), 0); Assert.AreEqual(CUtilConv.GetRoundTo(0.4m), 1); Assert.AreEqual(CUtilConv.GetRoundTo(300), 0); }
private void UpdateClientStockBothDir(int precision, CCmdStockChange cmdSockChange) { lock (_outStock) { foreach (Direction dir in Enum.GetValues(typeof(Direction))) { for (int j = 0; j < _store[precision][dir].Count; j++) { try { _outStock[dir][precision][j].Price = _store[precision][dir][j].Price; _outStock[dir][precision][j].Volume = CUtilConv.GetIntVolume(_store[precision][dir][j].Amount, _decimalVolume); } catch (Exception exc) { _client.Error("CbfxStockStor.UpdateClientStockBothDir", exc); } } } _outStock.InpCmdStockChange[Direction.Up][precision] = cmdSockChange; _outStock.InpCmdStockChange[Direction.Down][precision] = cmdSockChange; } _outStock.UpdateBidAsk(); _client.UpdateCleintStockBothDir(_instrument, precision, _outStock); }
public void TestPriceDecimals() { //BTC Assert.AreEqual(1, CUtilConv.GetPriceDecimals(8894.9m)); //AIDUSD Assert.AreEqual(5, CUtilConv.GetPriceDecimals(0.3204m)); }
private void DrawClusterPriceBarBg(/*double price, int amount*/ CCluster clusterData, double y, DateTime dtInterval, double actualWidthClusterGrid) { GenClusterBrushPen(clusterData, dtInterval); //calculate width of cluster bar long dealsAmountFullBar = CUtilConv.GetIntVolume(Math.Max(_dealsAmountFullBar, 1), _decimalVolume);//zero devide protect _volumeRectWidth = (((double)clusterData.AmountTotal) / ((double)dealsAmountFullBar)) * actualWidthClusterGrid; //draw cluster bar with proportional width //DrawRectangle(_brushCluster, _penCluster, new Rect(0.0, y, _volumeRectWidth, (double)_stirngHeight)); _drwCntxtClustersBg.DrawRectangle(_brushCluster, _penCluster, new Rect(0.0, y, _volumeRectWidth, (double)_stirngHeight)); // FormattedText(text, _cultureInfoDefault, FlowDirection.LeftToRight, _typeFaceDefault, _fontSizeScaled, brush); //2018-02-21 string stAmount = CTerminalUtil.GetAmount(clusterData.AmountTotal, _decimalVolume); //print cluster amount //DrawText(_FrmTxtCurrClustAmount, new Point(0.0, y)); //KAA 2017-03-01 changed to Glyph //2018-05-01 changed to fontsizeScaled GlyphRun gr = _glyphGenBg.GetGlyph(0, y + _fontSizeScaled, _fontSizeScaled, " " + /*clusterData.AmountTotal.ToString()*/ stAmount); _drwCntxtClustersBg.DrawGlyphRun(_brushFontBg, gr); }
public override int GetGUITradeSystemVolume(string instrument, string inpVolume) { decimal decVol = Convert.ToDecimal(inpVolume); int decVolume = GetDecimalVolume(instrument); int intVolume = (int)CUtilConv.GetIntVolume(decVol, decVolume); return(intVolume); }
public void TestStepPrice() { Assert.AreEqual(1, CUtilConv.GetMinStep(0)); //BTC Assert.AreEqual(0.1, CUtilConv.GetMinStep(1)); //AIDUSD Assert.AreEqual(0.00001, CUtilConv.GetMinStep(5)); }
private void ProcessTradeExecute(string inpInstrWithPrefix, JArray jarrTe) { string instrument = CBfxUtils.RemoveFirstT(inpInstrWithPrefix); int decimalVolume = GetDecimalVolume(instrument); long lngMilis = (long)jarrTe[1]; decimal dcmlAmountRaw = (decimal)jarrTe[2]; decimal dcmlAmount = Math.Abs(dcmlAmountRaw); decimal dcmlPrice = (decimal)jarrTe[3]; long amount = CUtilConv.GetIntVolume(dcmlAmount, decimalVolume); //2018-02-22 //Amount is too small. Not possible to understand how it //could be. Was seen on LTC. For now just ignore these trades if (amount == 0) { return; } DateTime dt = CUtilTime.DateTimeFromUnixTimestampMillis(lngMilis); CRawDeal rd = new CRawDeal { Amount = amount, Price = dcmlPrice, Moment = dt }; if (dcmlAmountRaw > 0) { rd.Id_ord_buy = 1; } else { rd.Id_ord_sell = 1; } _client.UpdateDeal(instrument, rd); /* DateTime dtCurr = DateTime.Now; * double ddt = (dtCurr - dt).TotalSeconds; * * if (ddt != 00) * Thread.Sleep(0); * */ }
public void TestGetDecimalVolume() { //BTCUSD Assert.AreEqual(0.002m, CUtilConv.GetDecimalVolume(2, 3)); //LTCUSD Assert.AreEqual(0.08m, CUtilConv.GetDecimalVolume(8, 2)); //ETCUSD Assert.AreEqual(0.6m, CUtilConv.GetDecimalVolume(6, 1)); //RRTUSD Assert.AreEqual(190m, CUtilConv.GetDecimalVolume(190, 0)); }
public void TestGetIntVolume() { //BTC //8432,4 0,01|8433,9 0,04404|8437 0,003|8438,6 0,1|8440,5 1|8440,7 1|8440,9 0,65399871|8441 9,11|8443 0,3|8443, Assert.AreEqual(760, CUtilConv.GetIntVolume(0.76016001m, 3)); Assert.AreEqual(10, CUtilConv.GetIntVolume(0.01m, 3)); Assert.AreEqual(44, CUtilConv.GetIntVolume(0.044m, 3)); Assert.AreEqual(100, CUtilConv.GetIntVolume(0.1m, 3)); Assert.AreEqual(654, CUtilConv.GetIntVolume(0.65399871m, 3)); //TRXUSD 3546,8412 Assert.AreEqual(3547, CUtilConv.GetIntVolume(3546.8412m, 0)); //LTUSD 158,25 0,5853136|158,37 15|158,38 16,5| Assert.AreEqual(59, CUtilConv.GetIntVolume(0.5853136m, 2)); Assert.AreEqual(1500, CUtilConv.GetIntVolume(15m, 2)); Assert.AreEqual(1650, CUtilConv.GetIntVolume(16.5m, 2)); }
private void ProcessSymbolDetails() { Log("GetSymbolDetails start"); ResponseSymbolDetails[] resp = _bfxRestConnectorV1.GetSymbolDetails(); Log("GetSymbolDetails end"); //--- initial fill of DB (on very first start only) if (_bfxNeedInitInstruments) { for (int i = 0; i < resp.Count(); i++) { string instrument = resp[i].pair; string instrUpper = instrument.ToUpper(); //for now intrested only in Xusd pairs if (instrument.Contains("usd")) { DBCommunicator.TransactAddInstrument(instrUpper, CodesStockExch._04_CryptoBitfinex); } } return; } //--- end of initial DB fill foreach (var dbIsntr in Instruments) { for (int i = 0; i < resp.Count(); i++) { decimal decMinOrdSize = Convert.ToDecimal(resp[i].minimum_order_size); if (resp[i].pair == dbIsntr.instrument.ToLower() && decMinOrdSize != dbIsntr.minimum_order_size) { dbIsntr.minimum_order_size = decMinOrdSize; int oldDecimalVolume = dbIsntr.DecimalVolume; dbIsntr.DecimalVolume = CUtilConv.GetRoundTo(dbIsntr.minimum_order_size); DBCommunicator.UpdateCryptoInstrumentData(resp[i].pair, CodesStockExch._04_CryptoBitfinex, decMinOrdSize, dbIsntr.DecimalVolume); Log(String.Format("Update minimum_order_size={0} {1}", dbIsntr.minimum_order_size, dbIsntr.instrument)); if (oldDecimalVolume != dbIsntr.DecimalVolume) { _bfxWebSockConnector.UpdateDecimalVolume(dbIsntr.instrument, dbIsntr.DecimalVolume); Log(String.Format("Update DecimalVolume {0} {1}", dbIsntr.DecimalVolume, dbIsntr.instrument)); } } } } if (_tradeHistStor == null) { _tradeHistStor = new CTradeHistStor(Instruments.GetInstruments(), DBCommunicator); } }
private void UpdatePriceDecimalsAndMinStep(CSharedStocks sourceStock) { int maxCalcedPriceDecimals = 0; int numEl = 0; bool bChanged = false; Dictionary <int, int> _dictAmount = new Dictionary <int, int>(); // Specific algorithm for PriceDecimals and min step calculation. // // // 2018-06-21 Algo changed. Do count all amounts of decimals // and save to dictionary. Use amount of decimals wich has more elements. // Perform analyze only for elements that are near spread, // for this purpose using "window" which determines an area near spread. // // If current value change - do trigger update of client // lock (sourceStock.Lck) { foreach (Direction dir in Enum.GetValues(typeof(Direction))) { int i = 0; int windowSize = 50; //2018-06-22 temprorary only for precision 0 foreach (var el in sourceStock[dir][0]) { if (el.Price == 0) { continue; } if (i > windowSize) { break; } int calcedPriceDecimals = CUtilConv.GetPriceDecimals(el.Price); if (_dictAmount.ContainsKey(calcedPriceDecimals)) { _dictAmount[calcedPriceDecimals]++; } else { _dictAmount[calcedPriceDecimals] = 1; } numEl++; if (calcedPriceDecimals > maxCalcedPriceDecimals) { maxCalcedPriceDecimals = calcedPriceDecimals; } i++; } } } //nothing to do - get out if (numEl == 0) { return; } int maxDecimalsAmount = 0; int decimalsPriceUse = 0; foreach (var kvp in _dictAmount) { if (kvp.Value > maxDecimalsAmount) { maxDecimalsAmount = kvp.Value; decimalsPriceUse = kvp.Key; } } // if (Instrument == "IOTUSD") // bDbgFirst = true; if (decimalsPriceUse != _currentPriceDecimals) { Log(String.Format("Changed pirce decimals {0} --> {1}", _currentPriceDecimals, decimalsPriceUse)); _currentPriceDecimals = decimalsPriceUse; //2018-04-05 temporary disabled //2018-04-23 enabled after change to 4 decimals _clientStockConvCrypto.UpdatePriceDecimals(Instrument, _currentPriceDecimals); bChanged = true; } decimal calcedMinStep = CUtil.GetDecimalMult(_currentPriceDecimals); if (calcedMinStep != _currentMinStep) { Log(String.Format("Changed min_steps {0} --> {1}", _currentMinStep, calcedMinStep)); _currentMinStep = calcedMinStep; //2018-04-05 temporary disabled //2018-04-23 enabled after change to 4 decimals _clientStockConvCrypto.UpdateCurrentMinSteps(Instrument, _currentMinStep); bChanged = true; } // Thread.Sleep(30000); if (bChanged) { _clientStockConvCrypto.TriggerUpdateInstrumentParams(Instrument); } //for (int i=0; i<sourceStock[TradingLib.Enums.Direction. //CBfxUtils.GetPriceDecimals( sourceStock.LstStockConf = new List <CStockConf>(); int dcmlCurr = _currentPriceDecimals; var lst = _client.GetPricePrecisions(); int count = lst.Count; for (int i = 0; i < count; i++) { // if (Instrument == "IOTUSD") // bDbgFirst = true; decimal currMinStep = CUtil.GetDecimalMultUnlim(dcmlCurr); CStockConf stockConf = new CStockConf() { PrecissionNum = i, DecimalsPrice = Math.Max(dcmlCurr, 0), MinStep = currMinStep }; sourceStock.LstStockConf.Add(stockConf); dcmlCurr--; } }