protected void AddMarketSummary(PriceTicker ticker) { if (tickersMapping.TryAdd(ticker.Symbol, Tickers.Count)) { Tickers.Add(ticker); } }
protected bool IsTickerChanged(PriceTicker oldTicker, PriceTicker newTicker) { return(oldTicker.LastPrice != newTicker.LastPrice || oldTicker.Bid != newTicker.Bid || oldTicker.Ask != newTicker.Ask || oldTicker.QuoteVolume != newTicker.QuoteVolume); }
public void GetSingleSymbolPriceTickerTest() { PriceTicker ticker = market.GetSymbolPriceTicker("BTCUSDT"); Assert.IsNotNull(ticker); Assert.AreEqual("BTCUSDT", ticker.Symbol); Assert.Greater(ticker.Price, 0); }
public void GetSingleSymbolPriceTickerTest() { try { PriceTicker ticker = market.GetSymbolPriceTicker("BTCUSDT"); Assert.IsNotNull(ticker); Assert.AreEqual("BTCUSDT", ticker.Symbol); Assert.Greater(ticker.Price, 0); } catch (ErrorMessageException e) { Tools.OnThrowErrorMessageException(e); } }
private bool FilterByPrice(PriceTicker ticker, string property, string filter) { var opers = new char[] { '<', '>', '=' }; // filter could be: // LastPrice = 0.45 // LastPrice < 0.45 // LastPrice >= 0.45 if (string.IsNullOrWhiteSpace(filter) || string.IsNullOrWhiteSpace(property) || ticker == null) { return(true); } var oper = new string(filter.Where(ch => opers.Contains(ch)).ToArray()); if (string.IsNullOrWhiteSpace(oper)) { oper = "="; } decimal filterValue = decimal.Zero; if (!decimal.TryParse(filter.Replace(oper, string.Empty), out filterValue)) { return(true); } var value = GetPropertyValue <decimal>(ticker, property); switch (oper) { case ">=": return(value >= filterValue); case "<=": return(value <= filterValue); case ">": return(value > filterValue); case "<": return(value < filterValue); case "=": return(value == filterValue); default: return(true); } }
void Update(PriceTicker ticker) { TreeIter iter; var result = store.GetIterFirst(out iter); while (result) { var bot = store.GetValue(iter, 0) as MonitoringBot; if (bot.Symbol == ticker.Symbol) { bot.UpdateLastPrice(ticker.LastPrice); store.SetValue(iter, 0, bot); // Force UI to refresh it. return; } result = store.IterNext(ref iter); } }
protected void OnRefreshMarketSummary2(PriceTicker ticker) { if (tickersMapping.TryGetValue(ticker.Symbol, out int idx)) { PriceTicker oldTicker = Tickers[idx]; Debug.Assert(oldTicker.Symbol == ticker.Symbol); bool tickerChanged = IsTickerChanged(oldTicker, ticker); #if GTK ticker.PrevLastPrice = oldTicker.LastPrice; marketSummaries[idx] = ticker; #else oldTicker.HighPrice = ticker.HighPrice; //oldTicker.LastPriceUsd = CalcUsdPrice(ticker.LastPrice.GetValueOrDefault(), ticker.SymbolInformation); oldTicker.LowPrice = ticker.LowPrice; oldTicker.PriceChange = ticker.PriceChange; oldTicker.QuoteVolume = ticker.QuoteVolume; oldTicker.WeightedAveragePrice = ticker.WeightedAveragePrice; oldTicker.LastPrice = ticker.LastPrice; oldTicker.Bid = ticker.Bid; oldTicker.Ask = ticker.Ask; if (oldTicker.Volume != null) { oldTicker.Volume = ticker.Volume; } if (oldTicker.PriceChangePercent != null) { oldTicker.PriceChangePercent = ticker.PriceChangePercent; } #endif Debug.Assert(marketsMapping.TryGetValue(ticker.Symbol, out SymbolInformation market)); //BalanceManager.UpdateWithLastPrice(market.ProperSymbol, ticker.LastPrice.GetValueOrDefault()); //if (tickerChanged) //await ProcessTradingRules(ticker); } else if (marketsMapping.ContainsKey(ticker.Symbol)) { // new PriceTicker? if (IsValidMarket(GetSymbolInformation(ticker.Symbol))) { AddMarketSummary(ticker); } } }
// before running the lifecycle, update ALL task orders // with status = ACTIVE | PARTIALLY_FILLED. private async Task Lifecycle(TradeTask tt, PriceTicker ticker) { if (!tt.Jobs.Any()) { // Shutdown the task. tt.Status = TradeTaskStatus.Finished; tt.Updated = DateTime.Now; tt.Events.Add(tt.Updated, "Task finished."); TradeTaskViewModel.SerializeModel(tt); return; } bool isLimitOrdersAllowed = true; // NOTE: this routine relies on condition that // LIMIT orders are always on TOP of MARKET orders in list of jobs. foreach (var job in tt.Jobs.ToList()) { if (job.ExchangeOrder != null) { switch (job.ExchangeOrder.Status) { case OrderStatus.Cancelled: tt.Status = TradeTaskStatus.Stopped; tt.Updated = DateTime.Now; tt.Events.Add(tt.Updated, "Task stopped due to order was cancelled outside."); TradeTaskViewModel.SerializeModel(tt); return; case OrderStatus.Filled: if (job.Kind == OrderKind.StopLoss) { // Shutdown the task. tt.Status = TradeTaskStatus.Finished; tt.Updated = DateTime.Now; tt.Events.Add(tt.Updated, "Task finished by stop loss."); } else if (job.Kind == OrderKind.PanicSell) { tt.Status = TradeTaskStatus.PanicSell; tt.Updated = DateTime.Now; tt.Events.Add(tt.Updated, "Task stopped by panic sell."); } tt.FinishedJobs.Enqueue(job); tt.Jobs.Remove(job); TradeTaskViewModel.SerializeModel(tt); return; case OrderStatus.Active: case OrderStatus.PartiallyFilled: // THIS STATE IS ONLY POSSIBLE FOR LIMIT ORDERS OR PANIC SELL! // so allow ONLY MARKET order to check conditions and execute isLimitOrdersAllowed = false; break; } } else { bool applicable = false; bool isLimitOrder = (job.Type == OrderType.LIMIT || job.Type == OrderType.STOP_LIMIT); // check condition if (job.Kind == OrderKind.Buy) { applicable = (tt.StopLoss.Price < ticker.Ask) && (ticker.Ask < tt.TakeProfit.First().Price); if (!applicable) { var ttvm = TradeTasksList.SingleOrDefault(x => x.Model == tt); ttvm.Status = "Цена вне зоны покупки"; } } else if (job.Kind == OrderKind.PanicSell) { applicable = true; } else { applicable = (job.Type != OrderType.MARKET && job.Type != OrderType.TRAILING) || (ticker.Bid >= job.Price); // NOTE: last part is wrong -- could be market STOP_LOSS, so ticker.Bid <= job.Price is valid for this case } // !!!ALLOW ONLY 1 LIMIT ORDER AT A TIME FOR NOW!!! if (applicable && (isLimitOrdersAllowed || !isLimitOrder) && (tt.Qty > 0 || job.Side == TradeSide.Buy)) { var result = await CancellAllOrders(tt); if (job.Side == TradeSide.Sell) { // Do not sell more then you have :D job.Quantity = Math.Min(tt.Qty, job.Quantity); } job.ExchangeOrder = await ExecuteOrder(job); job.OrderId = job.ExchangeOrder.OrderId; tt.Updated = DateTime.Now; tt.Events.Add(tt.Updated, $"Created order {job.OrderId}."); TradeTaskViewModel.SerializeModel(tt); job.ExchangeOrder.Fills.ForEach(x => tt.RegisterTrade(x)); var ttvm = TradeTasksList.SingleOrDefault(x => x.Model == tt); ttvm.Status = BuildStatusString(tt, job); } return; // exit for } } }
protected override Task ProcessTradingRuleOnPriceTicker(TradingRuleProxy proxy, PriceTicker ticker) { return(Task.CompletedTask); }
private PriceTicker Join(PriceTicker ticker, DSX.Bar bar) { ticker.PriceChange = bar.close - bar.open; ticker.PriceChangePercent = CalcChangePercent(bar.close, bar.open); return(ticker); }