public TurtleBuyStrategy(IMemberStock memberStock, IBaseData baseData, bool isBackTest = false, bool testStatus = false) : base(baseData) { _isBackTest = isBackTest; _memberStock = memberStock; _testStatus = testStatus; }
public Task SetMemberStockAsync(string memberEmail, CountryKind country, string stockId, BuySellStrategyType strategy, bool isNotify) { IMemberStock stock = MemberStockTable.Find(a => string.Equals(a.MemberEmail, memberEmail, StringComparison.OrdinalIgnoreCase) && a.Country == country && string.Equals(a.StockId, stockId, StringComparison.OrdinalIgnoreCase)); if (!(stock is MemberStock target)) { return(Task.CompletedTask); } target.Strategy = strategy; target.IsNotify = isNotify; return(Task.CompletedTask); }
public ITradingStrategy GetBuyStrategy(IMemberStock memberStock, IBaseData baseData, bool testStatus = false) { if (memberStock.Strategy == BuySellStrategyType.N20 || memberStock.Strategy == BuySellStrategyType.N40 || memberStock.Strategy == BuySellStrategyType.N60) { return(new TurtleBuyStrategy(memberStock, baseData, testStatus: testStatus)); } if (memberStock.Strategy == BuySellStrategyType.MA20 || memberStock.Strategy == BuySellStrategyType.MA40 || memberStock.Strategy == BuySellStrategyType.MA60) { return(new MovingAverageBuyStrategy(baseData, testStatus: testStatus)); } return(null); }
private async Task MovingAverageBuyInternalAsync(CountryKind country, IMemberStock memberStock, ICurrentPriceStorage storage) { string stockFullId = $"{country.GetShortName()}.{memberStock.StockId}"; if (!storage.TryGetItem(country, memberStock.StockId, out ICurrentPrice target) || target == null || !BaseData.CurrentTime.IsSameDay(target.LastTradeTime)) { return; } decimal todayHigh = target.TodayHighPrice; decimal?previousMovingAveragePrice = await GetBreakThroughComparedPriceAsync(stockFullId, memberStock.Strategy).ConfigureAwait(false); if (!previousMovingAveragePrice.HasValue || previousMovingAveragePrice.Value >= todayHigh) { return; } bool isUserHoldStock = await IfUserHoldStock(memberStock.MemberEmail, stockFullId).ConfigureAwait(false); if (isUserHoldStock) { return; } // TODO : refactor // check if notify today if (!PriceNotificationChecker.CanNotify(memberStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, memberStock.Strategy, StockBuyState.Buy)) { return; } string stockName = await GetStockNameAsync(stockFullId).ConfigureAwait(false); // should change to some EmailTemplateProvider IEmailTemplate emailMessage = EmailTemplateProvider.GetBreakThroughEmailTemplate(memberStock.MemberEmail, stockFullId, stockName, memberStock.Strategy, todayHigh, previousMovingAveragePrice.HasValue ? previousMovingAveragePrice.Value : -1); if (_testStatus) { await EmailService.SendEmailAsync(country, BaseData.CurrentTime, emailMessage).ConfigureAwait(false); } else { await EmailService.SendEmailAsync(country, BaseData.CurrentTime, emailMessage).ConfigureAwait(false); } PriceNotificationChecker.InsertRecord(memberStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, memberStock.Strategy, StockBuyState.Buy); if (!_testStatus) { _ = BaseData.GetLogger().WriteToWorkerLogAsync(country, BaseData.CurrentTime, "MovingAverageBuyStrategy", $"{memberStock.Strategy}, first buy ({stockFullId}) email is sent to {memberStock.MemberEmail}"); } if (_isBackTest) { //await BackTestFirstBuyOperationAsync(previousHighBoundPrice.Value); } }
private async Task FirstBuyInternalAsync(IMemberStock memberStock, ICurrentPriceStorage priceStorage) { if (!priceStorage.TryGetItem(memberStock.Country, memberStock.StockId, out ICurrentPrice target) || target == null || !BaseData.CurrentTime.IsSameDay(target.LastTradeTime)) { return; } decimal todayHigh = target.TodayHighPrice; string stockFullId = $"{memberStock.Country.GetShortName()}.{memberStock.StockId}"; decimal?previousHighBoundPrice = await GetBreakThroughComparedPriceAsync(stockFullId, memberStock.Strategy).ConfigureAwait(false); // check if breaks through high price in N system if (!previousHighBoundPrice.HasValue || previousHighBoundPrice.Value >= todayHigh) { return; } // check if this member bought the stock. if bought, no notification. bool isUserHold = await IfUserHoldStock(_memberStock.MemberEmail, stockFullId).ConfigureAwait(false); if (isUserHold) { return; } // check if notify today if (!PriceNotificationChecker.CanNotify(_memberStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, _memberStock.Strategy, StockBuyState.Buy)) { return; } string stockName = await GetStockNameAsync(stockFullId).ConfigureAwait(false); // should change to some EmailTemplateProvider IEmailTemplate emailMessage = EmailTemplateProvider.GetBreakThroughEmailTemplate(_memberStock.MemberEmail, stockFullId, stockName, _memberStock.Strategy, todayHigh, previousHighBoundPrice ?? -1); if (_testStatus) { _ = EmailService.SendEmailAsync(BaseData.Country, BaseData.CurrentTime, emailMessage).ConfigureAwait(false); } else { _ = EmailService.SendEmailAsync(BaseData.Country, BaseData.CurrentTime, emailMessage).ConfigureAwait(false); } PriceNotificationChecker.InsertRecord(_memberStock.MemberEmail, stockFullId, StockNotificationType.Buy, BaseData.CurrentTime, _memberStock.Strategy, StockBuyState.Buy); if (!_testStatus) { _ = BaseData.GetLogger().WriteToWorkerLogAsync(BaseData.Country, BaseData.CurrentTime, "TurtleBuyStrategy", $"{_memberStock.Strategy}, first buy ({stockFullId}) email is sent to {_memberStock.MemberEmail}").ConfigureAwait(false); } if (_isBackTest) { await BackTestFirstBuyOperationAsync(previousHighBoundPrice.Value).ConfigureAwait(false); } }