示例#1
0
 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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
            }
        }