コード例 #1
0
        public async Task WriteToErrorLogAsync(CountryKind country, DateTime time, string workerKind, Exception ex)
        {
            if (ex == null ||
                string.IsNullOrEmpty(workerKind) ||
                !_canWriteLog)
            {
                return;
            }

            string        fileName           = $"{country.GetShortName()}-TT2ErrorLog-{time:yyyyMMdd}.csv";
            string        filePath           = Path.Combine(_logFolderPath, fileName);
            StringBuilder errorStringBuilder = new StringBuilder();

            errorStringBuilder.Append("Exception message = ").AppendLine(ex.Message);
            errorStringBuilder.Append("Exception stack trace = ").AppendLine(ex.StackTrace);

            if (ex.InnerException != null)
            {
                errorStringBuilder.Append("  Inner exception message = ").AppendLine(ex.InnerException.Message);
                errorStringBuilder.Append("  Inner exception stack trace = ").AppendLine(ex.InnerException.StackTrace);
            }

            string data = $"{time:HH:mm:ss},{workerKind}, {errorStringBuilder}";

            await WriteContentToLogAsync(data, filePath).ConfigureAwait(false);
        }
コード例 #2
0
        public async Task WriteToHeartBeatLogAsync(CountryKind country, DateTime time, string workerKind)
        {
            if (string.IsNullOrEmpty(workerKind) || !_canWriteLog)
            {
                return;
            }

            string fileName = $"{country.GetShortName()}-TT2HeartBeat-{time:yyyyMMdd}.csv";
            string filePath = Path.Combine(_logFolderPath, fileName);
            string data     = $"{time:HH:mm:ss},{workerKind } sent a heart beat";

            await WriteContentToLogAsync(data, filePath).ConfigureAwait(false);
        }
コード例 #3
0
        public bool TryGetItem(CountryKind country, string stockId, out ICurrentPrice item)
        {
            string stockFullId = $"{country.GetShortName()}.{stockId}";

            if (_storage.TryGetValue(stockFullId, out ICurrentPrice target))
            {
                item = target;
                return(true);
            }

            item = null;
            return(false);
        }
コード例 #4
0
        public void AddOrUpdateItem(CountryKind country, string stockId, ICurrentPrice item)
        {
            string stockFullId = $"{country.GetShortName()}.{stockId}";

            if (_storage.ContainsKey(stockFullId) &&
                _storage[stockFullId] == item)
            {
                return;
            }

            _storage[stockFullId] = item;
            IsAddedOrUpdated      = true;
        }
コード例 #5
0
        public async Task WriteToCurrentPriceLogAsync(CountryKind country, string data)
        {
            if (string.IsNullOrEmpty(data) ||
                country == CountryKind.Test ||
                country == CountryKind.Test2 ||
                country == CountryKind.Unknown ||
                !_canWriteLog)
            {
                return;
            }

            string fileName = $"{country.GetShortName()}-CurrentPrice.csv";
            string filePath = Path.Combine(_logFolderPath, fileName);

            await WriteContentToLogAsync(data, filePath, false).ConfigureAwait(false);
        }
コード例 #6
0
        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);
            }
        }
コード例 #7
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);
            }
        }