public Task UpdateMemberBuyStockAsync(string memberEmail, CountryKind country, string stockId, decimal stopPrice, StockBuyState newState) { IMemberBuyStock memberStock = MemberBuyStockTable.Find(a => string.Equals(a.MemberEmail, memberEmail, StringComparison.OrdinalIgnoreCase) && a.Country == country); if (memberStock != null && memberStock is MemberBuyStock mStock) { mStock.StopPrice = stopPrice; mStock.State = newState; } return(Task.CompletedTask); }
public Task SetMemberBuyStockBuyStateAsync(string memberEmail, CountryKind country, string stockID, StockBuyState buyState) { IMemberBuyStock stock = MemberBuyStockTable.FirstOrDefault(a => string.Equals(a.MemberEmail, memberEmail, StringComparison.OrdinalIgnoreCase) && a.Country == country && string.Equals(a.StockId, stockID, StringComparison.OrdinalIgnoreCase)); if (!(stock is MemberBuyStock target)) { return(Task.CompletedTask); } target.State = buyState; return(Task.CompletedTask); }
public ITradingStrategy GetSellStrategy(IMemberBuyStock memberBuyStock, IBaseData baseData, bool testStatus = false) { if (memberBuyStock.Strategy == BuySellStrategyType.N20 || memberBuyStock.Strategy == BuySellStrategyType.N40 || memberBuyStock.Strategy == BuySellStrategyType.N60) { return(new TurtleSellStrategy(memberBuyStock, baseData, testStatus: testStatus)); } if (memberBuyStock.Strategy == BuySellStrategyType.MA20 || memberBuyStock.Strategy == BuySellStrategyType.MA40 || memberBuyStock.Strategy == BuySellStrategyType.MA60) { return(new MovingAverageSellStrategy(baseData, testStatus: testStatus)); } return(null); }
private async Task SellNotificationInternalAsync(CountryKind country, IMemberBuyStock memberBuyStock, CancellationToken token) { if (!BaseData.CurrentPriceStorage.TryGetItem(country, memberBuyStock.StockId, out ICurrentPrice targetItem) || targetItem == null || !BaseData.CurrentTime.IsSameDay(targetItem.LastTradeTime) || token.IsCancellationRequested) { return; } string stockFullId = $"{country.GetShortName()}.{memberBuyStock.StockId}"; decimal? previousMovingAveragePrice = await GetBreakDownComparedPriceAsync(stockFullId, memberBuyStock.Strategy).ConfigureAwait(false); if (previousMovingAveragePrice == null || token.IsCancellationRequested) { return; } // TODO : refactor if (!PriceNotificationChecker.CanNotify(memberBuyStock.MemberEmail, stockFullId, StockNotificationType.SellStop, BaseData.CurrentTime, memberBuyStock.Strategy, StockBuyState.Sold)) { return; } // when CurrentPrice < (LowIn10 or StopPrice), notify the member string stockName = await GetStockNameAsync(memberBuyStock.StockId).ConfigureAwait(false); IEmailTemplate emailTemplate = null; if (targetItem.CurrentPrice < (previousMovingAveragePrice.Value - (2 * memberBuyStock.NValue))) { // lower than previous MA price - 2*N emailTemplate = EmailTemplateProvider.GetBreakDownEmailTemplate(memberBuyStock.MemberEmail, stockFullId, stockName, memberBuyStock.Strategy, previousMovingAveragePrice.Value, previousMovingAveragePrice.Value); } else if (targetItem.CurrentPrice < memberBuyStock.StopPrice) { // lower than stop price emailTemplate = EmailTemplateProvider.GetStopLossEmailTemplate(memberBuyStock.MemberEmail, stockFullId, stockName, memberBuyStock.Strategy, memberBuyStock.StopPrice, memberBuyStock.StopPrice); } if (emailTemplate == null) { return; } if (_testStatus) { await EmailService.SendEmailAsync(country, BaseData.CurrentTime, emailTemplate).ConfigureAwait(false); } else { await EmailService.SendEmailAsync(country, BaseData.CurrentTime, emailTemplate).ConfigureAwait(false); } PriceNotificationChecker.InsertRecord(memberBuyStock.MemberEmail, stockFullId, StockNotificationType.SellStop, BaseData.CurrentTime, memberBuyStock.Strategy, StockBuyState.Sold); if (_isBackTest) { await DatabaseOperations.DeleteMemberBuyStockAsync(memberBuyStock.MemberEmail, memberBuyStock.Country, memberBuyStock.StockId).ConfigureAwait(false); } }
private async Task AddBuyAsync(CancellationToken token) { // get MemberBuyStock from database IMemberBuyStock memberBuyStock = (await DatabaseOperations.GetMemberBuyStocksAsync(_memberStock.MemberEmail).ConfigureAwait(false))? .FirstOrDefault(a => (a.State != StockBuyState.Sold || a.State != StockBuyState.Unknown) && string.Equals(a.MemberEmail, _memberStock.MemberEmail, StringComparison.OrdinalIgnoreCase) && a.Country == _memberStock.Country && string.Equals(a.StockId, _memberStock.StockId, StringComparison.OrdinalIgnoreCase)); if (memberBuyStock == null) { return; } string stockFullId = $"{memberBuyStock.Country.GetShortName()}.{memberBuyStock.StockId}"; decimal buyPrice = memberBuyStock.BuyPrice; decimal nValue = memberBuyStock.NValue; decimal firstAddPrice = buyPrice + nValue; decimal secondAddPrice = firstAddPrice + nValue; decimal thirdAddPrie = secondAddPrice + nValue; decimal fourthAddPrice = thirdAddPrie + nValue; if (!BaseData.CurrentPriceStorage.TryGetItem(memberBuyStock.Country, memberBuyStock.StockId, out ICurrentPrice target) || target == null || !BaseData.CurrentTime.IsSameDay(target.LastTradeTime)) { return; } decimal currentPrice = target.CurrentPrice; IEmailTemplate emailTemplate = null; StockBuyState newBuyState = StockBuyState.Unknown; string stockName = await GetStockNameAsync(stockFullId).ConfigureAwait(false); if (token.IsCancellationRequested) { return; } // TODO : refactor if (firstAddPrice <= currentPrice && currentPrice < secondAddPrice && memberBuyStock.State == StockBuyState.Buy) { newBuyState = StockBuyState.FirstAdd; decimal newStopPrice = firstAddPrice - (nValue * 2); await DatabaseOperations.UpdateMemberBuyStockAsync(memberBuyStock.MemberEmail, memberBuyStock.Country, memberBuyStock.StockId, newStopPrice, newBuyState).ConfigureAwait(false); emailTemplate = EmailTemplateProvider.GetAddOnBuyEmailTemplate(memberBuyStock.MemberEmail, memberBuyStock.StockId, stockName, newStopPrice, newBuyState); } else if (secondAddPrice <= currentPrice && currentPrice < thirdAddPrie && memberBuyStock.State.GetStockBuyStateValue() <= 1) { newBuyState = StockBuyState.SecondAdd; decimal newStopPrice = secondAddPrice - (nValue * 2); await DatabaseOperations.UpdateMemberBuyStockAsync(memberBuyStock.MemberEmail, memberBuyStock.Country, memberBuyStock.StockId, newStopPrice, newBuyState).ConfigureAwait(false); emailTemplate = EmailTemplateProvider.GetAddOnBuyEmailTemplate(memberBuyStock.MemberEmail, memberBuyStock.StockId, stockName, newStopPrice, newBuyState); } else if (thirdAddPrie <= currentPrice && currentPrice < fourthAddPrice && memberBuyStock.State.GetStockBuyStateValue() <= 2) { newBuyState = StockBuyState.ThirdAdd; decimal newStopPrice = thirdAddPrie - (nValue * 2); await DatabaseOperations.UpdateMemberBuyStockAsync(memberBuyStock.MemberEmail, memberBuyStock.Country, memberBuyStock.StockId, newStopPrice, newBuyState).ConfigureAwait(false); emailTemplate = EmailTemplateProvider.GetAddOnBuyEmailTemplate(memberBuyStock.MemberEmail, memberBuyStock.StockId, stockName, newStopPrice, newBuyState); } else if (fourthAddPrice <= currentPrice && memberBuyStock.State.GetStockBuyStateValue() <= 3) { newBuyState = StockBuyState.FourthAdd; decimal newStopPrice = fourthAddPrice - (nValue * 2); await DatabaseOperations.UpdateMemberBuyStockAsync(memberBuyStock.MemberEmail, memberBuyStock.Country, memberBuyStock.StockId, newStopPrice, newBuyState).ConfigureAwait(false); emailTemplate = EmailTemplateProvider.GetAddOnBuyEmailTemplate(memberBuyStock.MemberEmail, memberBuyStock.StockId, stockName, newStopPrice, newBuyState); } if (emailTemplate != null && PriceNotificationChecker.CanNotify(memberBuyStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, memberBuyStock.Strategy, newBuyState)) { if (_testStatus) { await EmailService.SendEmailAsync(BaseData.Country, BaseData.CurrentTime, emailTemplate).ConfigureAwait(false); } else { await EmailService.SendEmailAsync(BaseData.Country, BaseData.CurrentTime, emailTemplate).ConfigureAwait(false); } PriceNotificationChecker.InsertRecord(memberBuyStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, memberBuyStock.Strategy, newBuyState); if (!_testStatus) { Task t = BaseData.GetLogger().WriteToWorkerLogAsync(BaseData.Country, BaseData.CurrentTime, "TurtleBuyStrategy", $"{memberBuyStock.Strategy}, add buy ({stockFullId}) email is sent to {emailTemplate.ReceipentEmail} and new state is {newBuyState}"); } } }