/// <summary> /// Analyze the list of market data, and return a number between -1 and 1 indicating favorability of the market /// </summary> /// <param name="marketBuffer"></param> /// <returns>-1 to recommend a buy, 0 for no recommendation, and 1 to recomment a sell.</returns> public float GetRecommendation(MarketUpdate currentValue, IEnumerable <MarketUpdate> marketBuffer) { var previousSmall = this.averageSmall.MovingAverage; var previousLarge = this.averageLarge.MovingAverage; var preDiff = previousSmall < previousLarge; this.averageSmall.CalculateMovingAverage(currentValue.Close); this.averageLarge.CalculateMovingAverage(currentValue.Close); var postDiff = this.averageSmall.MovingAverage < this.averageLarge.MovingAverage; if (preDiff && !postDiff) { // Buy! golden cross return(-1); } if (!preDiff && postDiff) { // Sell! death cross return(1); } //TODO: try to figure out probability of cross based on slope return(0); }
/// <summary> /// This method gets called whenever new market data is pulled. Used to make buy/sell decisions /// This is where we can aggregate some amount of the market data to do things like rolling averages /// </summary> /// <param name="value">The new market data</param> public void OnNext(MarketUpdate value) { //Control size of the buffer updates.AddFirst(value); while ((value.Time - updates.Last.Value.Time) > maxDataSpan) { updates.RemoveLast(); } var recommendations = indicators.Select(indicator => indicator.GetRecommendation(value, updates)).ToList(); //var message = String.Join('\t', recommendations.Zip(indicators, (rec, ind) => ind.PrintRecommendation(rec))); //Console.Out.WriteLineAsync(message); var recommendation = recommendations.Average(); if (recommendation <= -0.4) { // The closer to -1 it is, the higher percentage we should buy var recommendationStrength = ((-recommendation - 0.4) / 0.6) * confidenceModifier; Buy(this, new BuyRecommendation { BuyAmount = this.Position.USD * recommendationStrength / value.High }); } else if (recommendation >= 0.4) { // The closer to 1 it is, the higher percentage we should sell var recommendationStrength = ((recommendation - 0.4) / 0.6) * confidenceModifier; Sell(this, new SellRecommendation { SellAmount = this.Position.BTC * recommendationStrength }); } }
public Generator(Market market) { Market = market; _random = new Random(); _marketUpdate = new MarketUpdate(); digits = CalculateDigitsOnTickSize(Market.TickSize); _marketUpdate.MarketId = Market.MarketId; }
public ActionResult <MarketUpdateDto> GetLastUpdateMarketById([FromRoute] long marketId) { MarketUpdate marketUpdate = new MarketUpdate(); _generatorService.LastMarketUpdates.TryGetValue(marketId, out marketUpdate); return(Ok(_mapper.Map <MarketUpdateDto>(marketUpdate))); }
protected override async Task PollSource() { foreach (var data in fileData) { await Task.Yield(); var update = new MarketUpdate(data.Open, data.Close, data.High, data.Low, UnixTimeToDateTime(data.Timestamp)); this.NotifyObservers(update); } }
protected override async Task PollSource() { while (true) { await Task.Delay(5000); var update = new MarketUpdate(5, 9, 10, 4, DateTime.UtcNow); this.NotifyObservers(update); } }
/// <summary> /// A utility method used to push updated information to the observers /// </summary> /// <param name="update">The updated data snippit</param> protected void NotifyObservers(MarketUpdate update) { try { if (_observers != null) { _observers.ForEach((observer) => observer.OnNext(update)); } } catch (Exception e) { ; } }
private async void btnAddStock_ClickAsync(object sender, EventArgs e) { string ticker = txtMarketQuote.Text; try { YahooFinanceApi.Security sensex = await MarketUpdate.StockUpdate(ticker); sqFileOperations.AddInFile(sensex.Symbol.ToString(), sensex.ShortName.ToString()); // ConfigurationManager.AppSettings.Add(sensex.Symbol.ToString(), sensex.ShortName.ToString()); } catch (Exception ex) { MessageBox.Show("Quote not found"); } ListViewPopulate(); }
/// <summary> /// updates the current position based on the new market price /// </summary> /// <param name="update"></param> /// <returns></returns> private MarketUpdate UpdateModel(MarketUpdate update) { this.position.orders = position.orders.Where(order => { switch (order.OrderType) { case OrderType.MarketBuy: position.USD -= order.OrderQty * update.Open; position.BTC += order.OrderQty; Console.Out.WriteLineAsync($"{this.position}\t{this.position.BTC * update.Open + this.position.USD:C2}\tBought\t{order.OrderQty:F5} at {update.Open:F5}"); return(false); case OrderType.MarketSell: position.USD += order.OrderQty * update.Open; position.BTC -= order.OrderQty; Console.Out.WriteLineAsync($"{this.position}\t{this.position.BTC * update.Open + this.position.USD:C2}\tSold\t{order.OrderQty:F5} at {update.Open:F5}"); return(false); case OrderType.LimitBuy: if (DoesOrderExecute(order, update)) { position.USD -= order.OrderQty * order.Price.Value; position.BTC += order.OrderQty; return(false); } break; case OrderType.LimitSell: if (DoesOrderExecute(order, update)) { position.USD += order.OrderQty * order.Price.Value; position.BTC -= order.OrderQty; return(false); } break; } return(true); }).ToList(); return(update); }
/// <summary> /// Analyze the list of market data, and return a number between -1 and 1 indicating favorability of the market /// </summary> /// <param name="marketBuffer"></param> /// <returns>-1 to recommend a buy, 0 for no recommendation, and 1 to recomment a sell.</returns> public float GetRecommendation(MarketUpdate currentValue, IEnumerable <MarketUpdate> marketBuffer) { var lastRsi = RSICalculator.RSI; if (lastRsi == double.NaN || !RSICalculator.CalculateNextRSI(currentValue.Close)) { return(0); } if (lastRsi < 30 && RSICalculator.RSI >= 30) { return(-1); } if (lastRsi > 70 && RSICalculator.RSI <= 70) { return(1); } return(0); }
/// <summary> /// This method gets called whenever new market data is pulled. Used to make buy/sell decisions /// This is where we can aggregate some amount of the market data to do things like rolling averages /// </summary> /// <param name="value">The new market data</param> public void OnNext(MarketUpdate value) { updates.AddFirst(value); if (updates.Count > maxDataLength) { updates.RemoveLast(); } var average = updates.Average(update => update.Open); if (value.High < average) { Buy(this, new BuyRecommendation { BuyAmount = this.Position.USD * 0.1 / value.High }); } if (value.Low > average) { Sell(this, new SellRecommendation { SellAmount = this.Position.BTC * 0.1 }); } }
private async System.Threading.Tasks.Task StockUpdateLatest(string ticker) { try { if (ticker.Contains("~")) { ticker = ticker.Split('~')[0]; } else { ticker = ticker.Trim(); } YahooFinanceApi.Security sensex = await MarketUpdate.StockUpdate(ticker); lblRegularMarketPriceUpdate.Text = $"{Math.Round(sensex.RegularMarketPrice, 2)}"; lblRatesUpdateDifference.Text = $"{Math.Round(sensex.RegularMarketChange, 2)} ({Math.Round(sensex.RegularMarketChangePercent, 2)}%)"; if (sensex.RegularMarketChange > 0) { lblRatesUpdateDifference.ForeColor = Color.LightGreen; lblRatesUpdateDifference.Text = $"+{lblRatesUpdateDifference.Text}"; } else if (sensex.RegularMarketChange < 0) { lblRatesUpdateDifference.ForeColor = Color.Pink; } else { lblRatesUpdateDifference.ForeColor = Color.White; } long dateNumber = sensex.RegularMarketTime; long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; DateTime dt = new DateTime(beginTicks + dateNumber * 10000000, DateTimeKind.Utc); lblRatesUpdateDate.Text = dt.ToShortDateString(); lblMarketName.Text = sensex.ShortName.ToString(); lsbMarketDetails.Items.Clear(); lsbMarketDetails.Items.Add($"RegularMarketChange: {sensex.RegularMarketChange.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketChangePercent: {sensex.RegularMarketChangePercent.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketDayHigh: {sensex.RegularMarketDayHigh.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketDayLow: {sensex.RegularMarketDayLow.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketOpen: {sensex.RegularMarketOpen.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketPreviousClose: {sensex.RegularMarketPreviousClose.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketPrice: {sensex.RegularMarketPrice.ToString()}"); lsbMarketDetails.Items.Add($"RegularMarketTime:{dt.ToLocalTime().ToString()}"); //lsbMarketDetails.Items.Add($"RegularMarketVolume: {sensex.RegularMarketVolume.ToString()}"); lsbMarketDetails.Items.Add($"ShortName: {sensex.ShortName.ToString()}"); lsbMarketDetails.Items.Add($"ExchangeTimezoneName: {sensex.ExchangeTimezoneName.ToString()}"); lsbMarketDetails.Items.Add($"ExchangeTimezoneShortName: {sensex.ExchangeTimezoneShortName.ToString()}"); lsbMarketDetails.Items.Add($"SourceInterval: {sensex.SourceInterval.ToString()}"); lsbMarketDetails.Items.Add($"Symbol: {sensex.Symbol.ToString()}"); //lsbMarketDetails.Items.Add($"SharesOutstanding: {sensex.SharesOutstanding.ToString()}"); //lsbMarketDetails.Items.Add($"Ask: {sensex.Ask.ToString()}"); //lsbMarketDetails.Items.Add($"AskSize: {sensex.AskSize.ToString()}"); //lsbMarketDetails.Items.Add($"AverageDailyVolume10Day: {sensex.AverageDailyVolume10Day.ToString()}"); //lsbMarketDetails.Items.Add($"AverageDailyVolume3Month: {sensex.AverageDailyVolume3Month.ToString()}"); //lsbMarketDetails.Items.Add($"Bid: {sensex.Bid.ToString()}"); //lsbMarketDetails.Items.Add($"BidSize: {sensex.BidSize.ToString()}"); //lsbMarketDetails.Items.Add($"BookValue: {sensex.BookValue.ToString()}"); //lsbMarketDetails.Items.Add($"Currency: {sensex.Currency.ToString()}"); //lsbMarketDetails.Items.Add($"DividendDate: {sensex.DividendDate.ToString()}"); //lsbMarketDetails.Items.Add($"EarningsTimestamp: {sensex.EarningsTimestamp.ToString()}"); //lsbMarketDetails.Items.Add($"EarningsTimestampEnd: {sensex.EarningsTimestampEnd.ToString()}"); //lsbMarketDetails.Items.Add($"EarningsTimestampStart: {sensex.EarningsTimestampStart.ToString()}"); //lsbMarketDetails.Items.Add($"EpsForward: {sensex.EpsForward.ToString()}"); //lsbMarketDetails.Items.Add($"EpsTrailingTwelveMonths: {sensex.EpsTrailingTwelveMonths.ToString()}"); //lsbMarketDetails.Items.Add($"Exchange: {sensex.Exchange.ToString()}"); // lsbMarketDetails.Items.Add($"ExchangeDataDelayedBy: {sensex.ExchangeDataDelayedBy.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyDayAverage: {sensex.FiftyDayAverage.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyDayAverageChange: {sensex.FiftyDayAverageChange.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyDayAverageChangePercent: {sensex.FiftyDayAverageChangePercent.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekHigh: {sensex.FiftyTwoWeekHigh.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekHighChange: {sensex.FiftyTwoWeekHighChange.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekHighChangePercent: {sensex.FiftyTwoWeekHighChangePercent.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekLow: {sensex.FiftyTwoWeekLow.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekLowChange: {sensex.FiftyTwoWeekLowChange.ToString()}"); //lsbMarketDetails.Items.Add($"FiftyTwoWeekLowChangePercent: {sensex.FiftyTwoWeekLowChangePercent.ToString()}"); //lsbMarketDetails.Items.Add($"FinancialCurrency: {sensex.FinancialCurrency.ToString()}"); //lsbMarketDetails.Items.Add($"ForwardPE: {sensex.ForwardPE.ToString()}"); //lsbMarketDetails.Items.Add($"FullExchangeName: {sensex.FullExchangeName.ToString()}"); //lsbMarketDetails.Items.Add($"GmtOffSetMilliseconds: {sensex.GmtOffSetMilliseconds.ToString()}"); //lsbMarketDetails.Items.Add($"Language: {sensex.Language.ToString()}"); //lsbMarketDetails.Items.Add($"LongName: {sensex.LongName.ToString()}"); //lsbMarketDetails.Items.Add($"Market: {sensex.Market.ToString()}"); //lsbMarketDetails.Items.Add($"MarketCap: {sensex.MarketCap.ToString()}"); //lsbMarketDetails.Items.Add($"MarketState: {sensex.MarketState.ToString()}"); //lsbMarketDetails.Items.Add($"MessageBoardId: {sensex.MessageBoardId.ToString()}"); //lsbMarketDetails.Items.Add($"PriceHint: {sensex.PriceHint.ToString()}"); //lsbMarketDetails.Items.Add($"PriceToBook: {sensex.PriceToBook.ToString()}"); //lsbMarketDetails.Items.Add($"QuoteSourceName: {sensex.QuoteSourceName.ToString()}"); //lsbMarketDetails.Items.Add($"QuoteType: {sensex.QuoteType.ToString()}"); //lsbMarketDetails.Items.Add($"Tradeable: {sensex.Tradeable.ToString()}"); //lsbMarketDetails.Items.Add($"TrailingAnnualDividendRate: {sensex.TrailingAnnualDividendRate.ToString()}"); //lsbMarketDetails.Items.Add($"TrailingAnnualDividendYield: {sensex.TrailingAnnualDividendYield.ToString()}"); //lsbMarketDetails.Items.Add($"TrailingPE: {sensex.TrailingPE.ToString()}"); //lsbMarketDetails.Items.Add($"TwoHundredDayAverage: {sensex.TwoHundredDayAverage.ToString()}"); //lsbMarketDetails.Items.Add($"TwoHundredDayAverageChange: {sensex.TwoHundredDayAverageChange.ToString()}"); //lsbMarketDetails.Items.Add($"TwoHundredDayAverageChangePercent: {sensex.TwoHundredDayAverageChangePercent.ToString()}"); } catch (Exception ex) { MessageBox.Show(ex.StackTrace); } }
private bool DoesOrderExecute(Order o, MarketUpdate u) { return(o.Price.HasValue && o.Price.Value >= u.Low && o.Price.Value <= u.High); }