Daily and code cleanup for headlines and ExtractLongBusinessSummary
Some checks failed
Build .NET Project / build (push) Has been cancelled
Some checks failed
Build .NET Project / build (push) Has been cancelled
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
CMTSESSIONv1.00
|
||||
LastUpdated=3/20/2026 7:52:23 PM
|
||||
TradeDate=3/20/2026
|
||||
LastUpdated=3/23/2026 9:19:39 PM
|
||||
TradeDate=3/23/2026
|
||||
StartDate=1/1/0001
|
||||
AnalysisDate=3/20/2026
|
||||
AnalysisDate=3/23/2026
|
||||
CashBalance=9449.67
|
||||
NonTradeableCash=6456.42
|
||||
SuspendTrading=False|UsePriceSlopeIndicator=True|UsePriceSlopeIndicatorDays=252|AnalysisDate=3/20/2026|BetaMonths=6|TradeDate=3/20/2026|MarketCapLowerLimit=500000000|SidewaysDetection=False|SidewaysAfterDays=30|PriceTrendDays=20|CheckOutliersInReturnStream=True|DailyReturnLimit=0.25|MaxDailyPositions=3|MaxOpenPositions=3|NoTradeSymbols=CODYY,MARUY,CSTM,CS,NATI,QADA,CRTO,GTBIF,CLCT,PRSC,CMD,STAY,GBTC,YOKU,PNY,RFMD,ASAZY,USMO,VNR,STB,XIV,SYNT,DFP|OnlyTradeSymbols=|MinRSI=70|InitialCash=10000|TotalRiskPercentDecimal=0.05|PositionRiskPercentDecimal=0.12|EquityOnly=False|MinPercentReturnProximityTo52WeekHigh=30|MinPercentReturnOver52WeekLow=80|ProfitMarginCheck=True|EPSCheck=True|MinDaysBetweenReholding=30|LiquidityCheck=True|MinVolume=1000|DMA200Horizon=15|MinDaysBetweenStopAdjustments=30|MinDaysBetweenInitialStopAdjustment=5|MaxPricingExceptions=3|MACDSetup=(12,26,9)|MACDSignalDays=5|MACDRejectStrongSells=True|MACDRejectWeakSells=True|UseMarketIndicator=True|Benchmark=SPY|BenchmarkMovingAverageDays=200|BenchmarkMovingAverageHorizon=5|UseMarketIndicatorVolatility=True|UseMarketIndicatorVolatilityHorizon=60|UseMarketIndicatorVolatilityBenchmark=^VIX|UseStopLimitScaling=True|StopLimitScalingType=AverageTrueRange|StopLimitScalingVolatilityDays=30|SellOnDMABreak=True|DMABreakValues=200|DMABreakForceBreak=False|EntryType=OverExtended,MVP,PriceTrend,VolumeTrend|EntryHorizon=30|CandidateExpiryDays=180|VolumeTrendDays=10|ChannelBreakoutHorizon=40|UseOverExtendedIndicatorDays=45|UseOverExtendedIndicatorViolationThreshhold=1|UseOverExtendedIndicatorMarginPercent=1|MaxBeta=10|UseMaxBeta=False|UseProfitMaximization=True|UseProfitMaximizationExpression=R_THRESSHOLD=4;MAX_ATR=3;MULTIPLIER=MAX_ATR;IF(RMultiple>=R_THRESSHOLD){MULTIPLIER=1.2;}|UseTradeOnlySectors=False|UseTradeOnlySectorsSectors=Healthcare,Technology,Basic Materials,Consumer Defensive,Industrials|EvaluateStopOnUpTrend=False
|
||||
SuspendTrading=False|UsePriceSlopeIndicator=True|UsePriceSlopeIndicatorDays=252|AnalysisDate=3/23/2026|BetaMonths=6|TradeDate=3/23/2026|MarketCapLowerLimit=500000000|SidewaysDetection=False|SidewaysAfterDays=30|PriceTrendDays=20|CheckOutliersInReturnStream=True|DailyReturnLimit=0.25|MaxDailyPositions=3|MaxOpenPositions=3|NoTradeSymbols=CODYY,MARUY,CSTM,CS,NATI,QADA,CRTO,GTBIF,CLCT,PRSC,CMD,STAY,GBTC,YOKU,PNY,RFMD,ASAZY,USMO,VNR,STB,XIV,SYNT,DFP|OnlyTradeSymbols=|MinRSI=70|InitialCash=10000|TotalRiskPercentDecimal=0.05|PositionRiskPercentDecimal=0.12|EquityOnly=False|MinPercentReturnProximityTo52WeekHigh=30|MinPercentReturnOver52WeekLow=80|ProfitMarginCheck=True|EPSCheck=True|MinDaysBetweenReholding=30|LiquidityCheck=True|MinVolume=1000|DMA200Horizon=15|MinDaysBetweenStopAdjustments=30|MinDaysBetweenInitialStopAdjustment=5|MaxPricingExceptions=3|MACDSetup=(12,26,9)|MACDSignalDays=5|MACDRejectStrongSells=True|MACDRejectWeakSells=True|UseMarketIndicator=True|Benchmark=SPY|BenchmarkMovingAverageDays=200|BenchmarkMovingAverageHorizon=5|UseMarketIndicatorVolatility=True|UseMarketIndicatorVolatilityHorizon=60|UseMarketIndicatorVolatilityBenchmark=^VIX|UseStopLimitScaling=True|StopLimitScalingType=AverageTrueRange|StopLimitScalingVolatilityDays=30|SellOnDMABreak=True|DMABreakValues=200|DMABreakForceBreak=False|EntryType=OverExtended,MVP,PriceTrend,VolumeTrend|EntryHorizon=30|CandidateExpiryDays=180|VolumeTrendDays=10|ChannelBreakoutHorizon=40|UseOverExtendedIndicatorDays=45|UseOverExtendedIndicatorViolationThreshhold=1|UseOverExtendedIndicatorMarginPercent=1|MaxBeta=10|UseMaxBeta=False|UseProfitMaximization=True|UseProfitMaximizationExpression=R_THRESSHOLD=4;MAX_ATR=3;MULTIPLIER=MAX_ATR;IF(RMultiple>=R_THRESSHOLD){MULTIPLIER=1.2;}|UseTradeOnlySectors=False|UseTradeOnlySectorsSectors=Healthcare,Technology,Basic Materials,Consumer Defensive,Industrials|EvaluateStopOnUpTrend=False
|
||||
PricingExceptions=0
|
||||
TotalActivePositions=0
|
||||
TotalPositions=135
|
||||
@@ -144,13 +144,11 @@ Symbol=NFLX|PurchaseDate=10/21/2025 12:00:00 AM|SellDate=11/20/2025 12:00:00
|
||||
Symbol=CX|PurchaseDate=10/20/2025 12:00:00 AM|SellDate=2/5/2026 12:00:00 AM|Shares=144|PurchasePrice=9.54|CurrentPrice=11.74|Exposure=1373.7599999999998|MarketValue=1690.56|GainLoss=316.8000000000002|GainLossPcnt=0.23060796645702322|PositionRiskDecimal=0.12|R=1.1472|C=166.14399999999998|P=144.82566248256623|InitialStopLimit=8.4|TrailingStopLimit=12.033928567171097|TotalRiskExposure=165.1968|RMultiple=1.92R|Volatility=0.16408906877040863|Volume=0|LastStopAdjustment=1/28/2026 12:00:00 AM|Comment=Manual close.
|
||||
Symbol=FTI|PurchaseDate=11/20/2025 12:00:00 AM|SellDate=3/6/2026 12:00:00 AM|Shares=41|PurchasePrice=43.23|CurrentPrice=62.83|Exposure=1772.4299999999998|MarketValue=2576.0299999999997|GainLoss=803.5999999999999|GainLossPcnt=0.4533888503354152|PositionRiskDecimal=0.12|R=5.2188|C=218.45950000000005|P=41.86010193914311|InitialStopLimit=38.04|TrailingStopLimit=62.83571408271789|TotalRiskExposure=213.9708|RMultiple=3.76R|Volatility=0.825829267501831|Volume=0|LastStopAdjustment=2/25/2026 12:00:00 AM|Comment=Manual close.
|
||||
Symbol=HWM|PurchaseDate=11/17/2025 12:00:00 AM|SellDate=3/13/2026 12:00:00 AM|Shares=11|PurchasePrice=200.81|CurrentPrice=235.12|Exposure=2208.91|MarketValue=2586.32|GainLoss=377.4100000000003|GainLossPcnt=0.1708580249987552|PositionRiskDecimal=0.12|R=24.0336|C=276.15000000000003|P=11.490163770720992|InitialStopLimit=176.71|TrailingStopLimit=235.233001537323|TotalRiskExposure=264.3696|RMultiple=1.43R|Volatility=3.682325839996338|Volume=0|LastStopAdjustment=2/25/2026 12:00:00 AM|Comment=Manual close.
|
||||
TotalCandidates=123
|
||||
TotalCandidates=122
|
||||
Symbol=FINMY|AnalysisDate=10/2/2025 12:00:00 AM|EPSSlope=0.034999996423721313|ProfitMarginSlope=2.260866165161133|PriceSlope=0.0044867993617732855|Volatility=1.0326875448226929|Volume=0|Violation=False|Slope=0.0044867993617732855|Score=2.6625531836683844|AnnualizedReturn=3.0977419385881366|SharpeRatio=0.3357187697383774|RSquared=0.8595141998438711|BetaMonths=6|Beta=0.8249354197843893
|
||||
Symbol=RYCEY|AnalysisDate=10/1/2025 12:00:00 AM|EPSSlope=0.024999991059303284|ProfitMarginSlope=2.8640356063842773|PriceSlope=0.0037774218594819053|Volatility=0.31766563653945923|Volume=0|Violation=False|Slope=0.0037774218594819053|Score=2.3960549250413017|AnnualizedReturn=2.590653883681473|SharpeRatio=0.3253557777516767|RSquared=0.9248842310175243|BetaMonths=6|Beta=1.3961180603730583
|
||||
Symbol=TTMI|AnalysisDate=9/23/2025 12:00:00 AM|EPSSlope=0.06999999284744263|ProfitMarginSlope=0.4163370132446289|PriceSlope=0.003656353994575963|Volatility=3.1076900959014893|Volume=0|Violation=False|Slope=0.003656353994575963|Score=1.7384068712180738|AnnualizedReturn=2.512808888771404|SharpeRatio=0.3196249939717945|RSquared=0.6918181796420017|BetaMonths=6|Beta=4.404284563097658
|
||||
Symbol=SBSW|AnalysisDate=9/25/2025 12:00:00 AM|EPSSlope=0.14499999582767487|ProfitMarginSlope=8.495691299438477|PriceSlope=0.003797091740226121|Volatility=0.7532111406326294|Volume=0|Violation=False|Slope=0.003797091740226121|Score=1.7225186918919257|AnnualizedReturn=2.6035271414107117|SharpeRatio=0.24173922031779663|RSquared=0.6616096542625576|BetaMonths=6|Beta=1.8709390796649175
|
||||
Symbol=SANM|AnalysisDate=10/6/2025 12:00:00 AM|EPSSlope=0.17499995231628418|ProfitMarginSlope=0.24951171875|PriceSlope=0.0020823921870819274|Volatility=6.522579669952393|Volume=0|Violation=False|Slope=0.0020823921870819274|Score=1.2404476041886014|AnnualizedReturn=1.6900579717285966|SharpeRatio=0.13315785713170303|RSquared=0.7339674880618845|BetaMonths=6|Beta=1.1208093254003801
|
||||
Symbol=BVN|AnalysisDate=9/22/2025 12:00:00 AM|EPSSlope=0.04000002145767212|ProfitMarginSlope=3.3527870178222656|PriceSlope=0.0017883252559627236|Volatility=0.509544312953949|Volume=0|Violation=False|Slope=0.0017883252559627236|Score=1.1871859154563036|AnnualizedReturn=1.5693444187864467|SharpeRatio=0.06274675484127547|RSquared=0.7564852566744646|BetaMonths=6|Beta=0.08520633954692292
|
||||
Symbol=FN|AnalysisDate=11/4/2025 12:00:00 AM|EPSSlope=0.09999990463256836|ProfitMarginSlope=0.06801414489746094|PriceSlope=0.002548681464617965|Volatility=18.239673614501953|Volume=0|Violation=False|Slope=0.002548681464617965|Score=1.1239501014519349|AnnualizedReturn=1.900786464256634|SharpeRatio=0.15670695179226582|RSquared=0.5913079257387773|BetaMonths=6|Beta=1.0711460119912435
|
||||
Symbol=LRCX|AnalysisDate=10/6/2025 12:00:00 AM|EPSSlope=0.2849999666213989|ProfitMarginSlope=1.3532524108886719|PriceSlope=0.0018171246616002163|Volatility=9.071016311645508|Volume=0|Violation=False|Slope=0.0018171246616002163|Score=0.8978742858003759|AnnualizedReturn=1.580775287091166|SharpeRatio=-0.161869015355145|RSquared=0.5679961555146668|BetaMonths=6|Beta=2.1503821821201172
|
||||
Symbol=FLGT|AnalysisDate=11/17/2025 12:00:00 AM|EPSSlope=0.13499999046325684|ProfitMarginSlope=1.8280410766601562|PriceSlope=0.0013361208503431072|Volatility=2.987884759902954|Volume=0|Violation=False|Slope=0.0013361208503431072|Score=0.8232236228345737|AnnualizedReturn=1.4003223418343083|SharpeRatio=-0.2596743407342496|RSquared=0.5878815171628397|BetaMonths=6|Beta=2.699945531619503
|
||||
@@ -268,6 +266,7 @@ Symbol=SWBI|AnalysisDate=3/17/2026 12:00:00 AM|EPSSlope=0.025000005960464478|P
|
||||
Symbol=CIEN|AnalysisDate=3/18/2026 12:00:00 AM|EPSSlope=0.36000001430511475|ProfitMarginSlope=1.2882728576660156|PriceSlope=0.007582980684246792|Volatility=24.035886764526367|Volume=0|Violation=False|Slope=0.007582980684246792|Score=6.501273736145921|AnnualizedReturn=6.759244560670877|SharpeRatio=0.5901117810784703|RSquared=0.9618343703635203|BetaMonths=6|Beta=7.993479874840696
|
||||
Symbol=TSEM|AnalysisDate=3/19/2026 12:00:00 AM|EPSSlope=0.10500001907348633|ProfitMarginSlope=2.6034116744995117|PriceSlope=0.0065731793015904455|Volatility=14.174382209777832|Volume=0|Violation=False|Slope=0.0065731793015904455|Score=4.996953081541132|AnnualizedReturn=5.240627190431675|SharpeRatio=0.5548234088860783|RSquared=0.9535028728363958|BetaMonths=6|Beta=0.7064967512039374
|
||||
Symbol=CVE|AnalysisDate=3/19/2026 12:00:00 AM|EPSSlope=0.1549999713897705|ProfitMarginSlope=2.869175910949707|PriceSlope=0.002312376621316258|Volatility=0.6727309823036194|Volume=0|Violation=False|Slope=0.002312376621316258|Score=1.5367416145249861|AnnualizedReturn=1.7909011135482098|SharpeRatio=0.18893082259378852|RSquared=0.8580828963137601|BetaMonths=6|Beta=0.20756669551103663
|
||||
Symbol=TEN|AnalysisDate=3/23/2026 12:00:00 AM|EPSSlope=0.6399998664855957|ProfitMarginSlope=3.995054244995117|PriceSlope=0.0027014932112798236|Volatility=1.125|Volume=0|Violation=False|Slope=0.0027014932112798236|Score=1.707568207357409|AnnualizedReturn=1.9754106271879768|SharpeRatio=0.34197304914931037|RSquared=0.8644117753826985|BetaMonths=6|Beta=2.2588945700644185
|
||||
TotalStopLimits=213
|
||||
Symbol=CDNS|AnalysisDate=9/2/2020 12:00:00 AM|PreviousStop=97.9088|NewStop=109.599856939316|CurrentPriceLow=113.59|CurrentPriceClose=117.09|PriceTrendIndicatorSlope=0.310654103755951|StopLimitId=
|
||||
Symbol=LULU|AnalysisDate=9/2/2020 12:00:00 AM|PreviousStop=332.1824|NewStop=372.562428512573|CurrentPriceLow=387.08|CurrentPriceClose=398.29|PriceTrendIndicatorSlope=2.77707505226135|StopLimitId=
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
MGSHSESSIONv2.00
|
||||
LastUpdated=3/20/2026 7:51:34 PM
|
||||
TradeDate=3/23/2026
|
||||
LastUpdated=3/23/2026 9:19:00 PM
|
||||
TradeDate=3/24/2026
|
||||
StartDate=3/31/2025
|
||||
AnalysisDate=3/20/2026
|
||||
AnalysisDate=3/23/2026
|
||||
Cycle=12
|
||||
CashBalance=5326.200000000001
|
||||
NonTradeableCash=0
|
||||
HedgeCashBalance=3000
|
||||
Verbose=True|KeepSlotPositions=True|BenchmarkMode=False|BenchmarkModeSymbol=SPY|HoldingPeriod=3|MaxPositions=3|NoTradeSymbols=OSB,IBDRY,GBTC,YOKU,PNY,RFMD,ASAZY|NoTradeFinancialSymbols=U.S. Private Equity,U.S. Financials,U.S. Financial Services,U.S. Banking and Investment Services,Trading-Miscellaneous,Trading--Miscellaneous,Trading--Leveraged Equity,Trading--Leveraged Debt,Trading--Leveraged Commodities,Trading--Inverse Equity,Trading--Inverse Commodities,Tactical Allocation,Specialty Finance,Japan Financials,Savings & Cooperative Banks,Option Writing,Insurance Brokers,Insurance - Specialty,Insurance - Reinsurance,Insurance - Property & Casualty,Insurance - Life,Insurance - Diversified,Global Private Equity,Global Financials,Financial Services,Financial Exchanges,Financial,China Financials,Banks - Regional - US,Banks - Regional - Latin America,Banks - Global,Asset Management,Credit Services|Benchmark=SPY|MarketCapLowerLimit=1000000000|UsePEScreen=False|UseEBITDAScreen=True|UseRevenuePerShareScreen=True|UseLowSlopeBetaCheck=True|LowSlopeBetaDays=15|LowSlopeBetaThreshhold=1|UseMACD=True|MACDSetup=(12,26,9)|MACDSignalDays=12|MACDRejectStrongSellSignals=False|MACDRejectWeakSellSignals=True|UseStochastics=True|StochasticsSignalDays=3|StochasticsRejectStrongSells=True|StochasticsRejectWeakSells=True|UseFallbackCandidate=True|FallbackCandidate=SHV|FallbackCandidateBestOf=SHV,NEAR,BIL,GSY,AGG,ACWX,GSY,SCHF,IXUS,DBEF,IEFA,TLT|UseMaxPEScreen=True|MaxPE=40|StrictMaxPE=False|QualityIndicatorType=IDINDICATOR|IncludeTradeMasterForSymbolsHeld=True|UseStopLimits=True|StopLimitRiskPercentDecimal=0.2|StopLimitScalingVolatilityDays=30|MinDaysBetweenInitialStopAdjustment=30|MinDaysBetweenStopAdjustments=30|StopLimitPriceTrendDays=20|StopLimitATRMultiplier=3|UseHedging=True|HedgeBenchmarkSymbol=SPY|HedgeShortSymbol=SH|HedgeRiskPercentDecimal=0.12|HedgeMinDaysBetweenStopAdjustments=1|HedgeInitialCash=3000|HedgeCloseAboveSMANDays=10|HedgeBandBreakCheckDays=3|HedgeATRMultiplier=1|MaxPricingExceptions=3|UseBetaGenerator=True|UseBetaGeneratorMonths=24
|
||||
TotalActivePositions=4
|
||||
Slot=1|Symbol=MDT|PurchaseDate=1/30/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=14|PurchasePrice=102.85|CurrentPrice=86.16|Volume=6046285|Return1D=0|CumReturn252=0|IDIndicator=-10.35856573705179|Score=0.518428403011861|Velocity=0.8652931854199681|PE=26.67|Beta=0.37428296833055014|InitialStopLimit=82.28|TrailingStopLimit=82.28|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=20.592|Comment=Price changed on 2/2/2026 from $102.96 to $102.85
|
||||
Slot=2|Symbol=NFG|PurchaseDate=11/28/2025 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=12|PurchasePrice=82.45|CurrentPrice=91.7|Volume=236813|Return1D=0|CumReturn252=0|IDIndicator=-9.561752988047807|Score=1.4787437525170677|Velocity=0.6585998271391531|PE=31.63|Beta=0.04430253825297578|InitialStopLimit=65.96000000000001|TrailingStopLimit=85.48514305591583|LastStopAdjustment=3/2/2026 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=16.490000000000002|Comment=
|
||||
Slot=2|Symbol=NWN|PurchaseDate=2/27/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=18|PurchasePrice=53|CurrentPrice=51.42|Volume=468654|Return1D=0|CumReturn252=0|IDIndicator=-17.13147410358566|Score=0.6615960312468072|Velocity=1.0000000000000002|PE=20.04|Beta=-0.020855636842840336|InitialStopLimit=42.4|TrailingStopLimit=42.4|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=10.608|Comment=Price changed on 3/2/2026 from $53.04 to $53.00
|
||||
Slot=2|Symbol=ALLE|PurchaseDate=2/27/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=6|PurchasePrice=160.87|CurrentPrice=142.49|Volume=483322|Return1D=0|CumReturn252=0|IDIndicator=-7.5697211155378525|Score=1.0921592452357611|Velocity=0.6599496221662469|PE=24.3|Beta=0.32621889255450337|InitialStopLimit=128.7|TrailingStopLimit=128.7|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=32.230000000000004|Comment=Price changed on 3/2/2026 from $161.15 to $160.87
|
||||
Slot=1|Symbol=MDT|PurchaseDate=1/30/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=14|PurchasePrice=102.85|CurrentPrice=87.17|Volume=6046285|Return1D=0|CumReturn252=0|IDIndicator=-10.35856573705179|Score=0.518428403011861|Velocity=0.8652931854199681|PE=26.67|Beta=0.37428296833055014|InitialStopLimit=82.28|TrailingStopLimit=82.28|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=20.592|Comment=Price changed on 2/2/2026 from $102.96 to $102.85
|
||||
Slot=2|Symbol=NFG|PurchaseDate=11/28/2025 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=12|PurchasePrice=82.45|CurrentPrice=93.06|Volume=236813|Return1D=0|CumReturn252=0|IDIndicator=-9.561752988047807|Score=1.4787437525170677|Velocity=0.6585998271391531|PE=31.63|Beta=0.04430253825297578|InitialStopLimit=65.96000000000001|TrailingStopLimit=85.48514305591583|LastStopAdjustment=3/2/2026 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=16.490000000000002|Comment=
|
||||
Slot=2|Symbol=NWN|PurchaseDate=2/27/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=18|PurchasePrice=53|CurrentPrice=52.15|Volume=468654|Return1D=0|CumReturn252=0|IDIndicator=-17.13147410358566|Score=0.6615960312468072|Velocity=1.0000000000000002|PE=20.04|Beta=-0.020855636842840336|InitialStopLimit=42.4|TrailingStopLimit=42.4|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=10.608|Comment=Price changed on 3/2/2026 from $53.04 to $53.00
|
||||
Slot=2|Symbol=ALLE|PurchaseDate=2/27/2026 12:00:00 AM|SellDate=1/1/0001 12:00:00 AM|Shares=6|PurchasePrice=160.87|CurrentPrice=143.63|Volume=483322|Return1D=0|CumReturn252=0|IDIndicator=-7.5697211155378525|Score=1.0921592452357611|Velocity=0.6599496221662469|PE=24.3|Beta=0.32621889255450337|InitialStopLimit=128.7|TrailingStopLimit=128.7|LastStopAdjustment=1/1/0001 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=32.230000000000004|Comment=Price changed on 3/2/2026 from $161.15 to $160.87
|
||||
TotalPositions=22
|
||||
Symbol=MO|PurchaseDate=3/31/2025 12:00:00 AM|SellDate=5/14/2025 12:00:00 AM|Shares=18|PurchasePrice=59.91|CurrentPrice=56.15|Volume=17335180|Return1D=0|CumReturn252=0|IDIndicator=-15.9362549800797|Score=1.14749269300042|Velocity=0.967136150234742|PE=9|Beta=0.572465642401382|InitialStopLimit=47.93|TrailingStopLimit=56.15650033473968|LastStopAdjustment=5/7/2025 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=12.004|Comment=Closed due to trailing stop.
|
||||
Symbol=EXC|PurchaseDate=3/31/2025 12:00:00 AM|SellDate=5/14/2025 12:00:00 AM|Shares=24|PurchasePrice=45.76|CurrentPrice=42.6|Volume=14993121|Return1D=0|CumReturn252=0|IDIndicator=-8.76494023904382|Score=0.405636492837393|Velocity=1|PE=18.02|Beta=0.248374476251328|InitialStopLimit=36.61|TrailingStopLimit=42.7107857322693|LastStopAdjustment=4/30/2025 12:00:00 AM|PositionRiskPercentDecimal=0.2|R=9.216|Comment=Closed due to trailing stop.
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace MarketData.DataAccess
|
||||
private HeadlinesDA()
|
||||
{
|
||||
}
|
||||
|
||||
public static DateTime GetMaxHeadlineDate()
|
||||
{
|
||||
MySqlConnection sqlConnection = null;
|
||||
@@ -45,6 +46,7 @@ namespace MarketData.DataAccess
|
||||
if (null != sqlConnection) sqlConnection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> GetHeadlineDates()
|
||||
{
|
||||
MySqlConnection sqlConnection = null;
|
||||
@@ -80,6 +82,7 @@ namespace MarketData.DataAccess
|
||||
if (null != sqlConnection) sqlConnection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static Headlines GetHeadlines(String symbol)
|
||||
{
|
||||
MySqlConnection sqlConnection = null;
|
||||
@@ -123,6 +126,7 @@ namespace MarketData.DataAccess
|
||||
if (null != sqlConnection) sqlConnection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static Headlines GetHeadlines()
|
||||
{
|
||||
MySqlConnection sqlConnection = null;
|
||||
@@ -166,6 +170,7 @@ namespace MarketData.DataAccess
|
||||
if (null != sqlConnection) sqlConnection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
// This was authored for mobile app. It wants the sorting to match the WPF app.
|
||||
public static Headlines GetLatestHeadlines()
|
||||
{
|
||||
@@ -308,7 +313,6 @@ namespace MarketData.DataAccess
|
||||
/// <returns></returns>
|
||||
public static bool InsertHeadlines(Headlines headlines)
|
||||
{
|
||||
const int batchSize = 1000;
|
||||
MySqlConnection sqlConnection=null;
|
||||
MySqlTransaction sqlTransaction=null;
|
||||
|
||||
@@ -318,9 +322,9 @@ namespace MarketData.DataAccess
|
||||
sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
|
||||
sqlTransaction = sqlConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
|
||||
headlines=new Headlines(headlines.Distinct(new HeadlinesEqualityComparer()).ToList());
|
||||
foreach (IEnumerable<Headline> batch in headlines.Chunk(batchSize))
|
||||
foreach (Headline headline in headlines)
|
||||
{
|
||||
SafeInsertBatch(batch.ToList(), sqlConnection, sqlTransaction);
|
||||
if(!HeadlineExists(headline,sqlConnection,sqlTransaction))InsertHeadline(headline,sqlConnection,sqlTransaction);
|
||||
}
|
||||
sqlTransaction.Commit();
|
||||
return true;
|
||||
@@ -338,76 +342,6 @@ namespace MarketData.DataAccess
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SafeInsertBatch - This recursive approach allows us to catch exceptions and recursively call SafeInsertBatch continually dividing the
|
||||
/// batch until we find the offensive row.
|
||||
/// </summary>
|
||||
/// <param name="batch"></param>
|
||||
/// <param name="sqlConnection"></param>
|
||||
/// <param name="sqlTransaction"></param>
|
||||
private static void SafeInsertBatch(List<Headline> batch, MySqlConnection sqlConnection, MySqlTransaction sqlTransaction)
|
||||
{
|
||||
try
|
||||
{
|
||||
InsertBatch(batch, sqlConnection, sqlTransaction);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// If only one row, it's the offender
|
||||
if (batch.Count == 1)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, ex);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, $"Bad row: Symbol={batch[0].Symbol}, Headline={batch[0].Entry}");
|
||||
return;
|
||||
}
|
||||
// Split batch and retry
|
||||
int mid = batch.Count / 2;
|
||||
List<Headline> firstHalf = batch.Take(mid).ToList();
|
||||
List<Headline> secondHalf = batch.Skip(mid).ToList();
|
||||
SafeInsertBatch(firstHalf, sqlConnection, sqlTransaction);
|
||||
SafeInsertBatch(secondHalf, sqlConnection, sqlTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a batch of headlines
|
||||
/// </summary>
|
||||
/// <param name="batch"></param>
|
||||
/// <param name="sqlConnection"></param>
|
||||
/// <param name="sqlTransaction"></param>
|
||||
private static void InsertBatch(IEnumerable<Headline> batch, MySqlConnection sqlConnection, MySqlTransaction sqlTransaction)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
using MySqlCommand sqlCommand = new MySqlCommand();
|
||||
sqlCommand.Connection = sqlConnection;
|
||||
sqlCommand.Transaction = sqlTransaction;
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
sb.Append("INSERT IGNORE INTO Headlines (symbol, asof, headline, source, modified) VALUES ");
|
||||
int index = 0;
|
||||
foreach (Headline headline in batch)
|
||||
{
|
||||
if (index > 0) sb.Append(",");
|
||||
sb.Append($"(@symbol{index}, @asof{index}, @headline{index}, @source{index}, @modified{index})");
|
||||
sqlCommand.Parameters.AddWithValue($"@symbol{index}", headline.Symbol);
|
||||
sqlCommand.Parameters.AddWithValue($"@asof{index}", headline.Date);
|
||||
sqlCommand.Parameters.AddWithValue($"@headline{index}", headline.Entry);
|
||||
sqlCommand.Parameters.AddWithValue($"@source{index}", headline.Source);
|
||||
DateTime modified = Utility.IsEpoch(headline.Modified) ? now : headline.Modified;
|
||||
sqlCommand.Parameters.AddWithValue($"@modified{index}", modified);
|
||||
index++;
|
||||
}
|
||||
sqlCommand.CommandText = sb.ToString();
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InsertHeadline - This is now parameterized. The MySql driver should handle all escaping etc.,
|
||||
/// </summary>
|
||||
/// <param name="headline"></param>
|
||||
/// <param name="sqlConnection"></param>
|
||||
/// <param name="sqlTransaction"></param>
|
||||
/// <returns></returns>
|
||||
private static bool InsertHeadline(Headline headline,MySqlConnection sqlConnection,MySqlTransaction sqlTransaction)
|
||||
{
|
||||
MySqlCommand sqlCommand=null;
|
||||
@@ -416,14 +350,17 @@ namespace MarketData.DataAccess
|
||||
try
|
||||
{
|
||||
if (null == headline || null == headline.Symbol || null==headline.Entry) return false;
|
||||
strQuery = @"INSERT INTO Headlines (symbol, asof, headline, source, modified) VALUES (@symbol, @asof, @headline, @source, @modified)";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("insert into Headlines(symbol,asof,headline,source,modified) values(");
|
||||
sb.Append(SqlUtils.AddQuotes(headline.Symbol)).Append(",");
|
||||
sb.Append(SqlUtils.AddQuotes(SqlUtils.SqlDate(headline.Date))).Append(",");
|
||||
sb.Append(SqlUtils.AddQuotes(SqlUtils.SqlString(headline.Entry))).Append(",");
|
||||
sb.Append(SqlUtils.AddQuotes(SqlUtils.SqlString(headline.Source))).Append(",");
|
||||
if(Utility.IsEpoch(headline.Modified))sb.Append(SqlUtils.AddQuotes(SqlUtils.ToSqlDateTime(DateTime.Now)));
|
||||
else sb.Append(SqlUtils.AddQuotes(SqlUtils.ToSqlDateTime(headline.Modified)));
|
||||
sb.Append(")");
|
||||
strQuery = sb.ToString();
|
||||
sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction);
|
||||
sqlCommand.Parameters.AddWithValue("@symbol", headline.Symbol);
|
||||
sqlCommand.Parameters.AddWithValue("@asof", headline.Date);
|
||||
sqlCommand.Parameters.AddWithValue("@headline", headline.Entry);
|
||||
sqlCommand.Parameters.AddWithValue("@source", headline.Source);
|
||||
DateTime modified = Utility.IsEpoch(headline.Modified) ? DateTime.Now : headline.Modified;
|
||||
sqlCommand.Parameters.AddWithValue("@modified", modified);
|
||||
sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
return true;
|
||||
@@ -431,7 +368,7 @@ namespace MarketData.DataAccess
|
||||
catch (Exception exception)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,exception);
|
||||
SqlUtils.LogCommandParameters(strQuery, sqlCommand);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Query was '{0}'",strQuery));
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
@@ -440,31 +377,36 @@ namespace MarketData.DataAccess
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HeadlineExists - The now uses parameterized arguments now. The driver will handle escaping etc.,
|
||||
/// </summary>
|
||||
/// <param name="headline"></param>
|
||||
/// <param name="sqlConnection"></param>
|
||||
/// <param name="sqlTransaction"></param>
|
||||
/// <returns></returns>
|
||||
private static bool HeadlineExists(Headline headline,MySqlConnection sqlConnection,MySqlTransaction sqlTransaction)
|
||||
{
|
||||
MySqlDataReader sqlDataReader=null;
|
||||
MySqlCommand sqlCommand=null;
|
||||
String strQuery = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (null == headline || null == headline.Symbol) return false;
|
||||
string strQuery = @"SELECT count(*) FROM headlines WHERE asof = @asof AND headline = @headline";
|
||||
using MySqlCommand sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction);
|
||||
sqlCommand.Parameters.AddWithValue("@asof", headline.Date);
|
||||
sqlCommand.Parameters.AddWithValue("@headline", headline.Entry); // This will handle proper escaping of characters etc.,
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select count(*) from headlines where ");
|
||||
sb.Append(" asof=").Append(SqlUtils.AddQuotes(SqlUtils.SqlDate(headline.Date))).Append(" and ");
|
||||
sb.Append(" headline=").Append(SqlUtils.AddQuotes(SqlUtils.SqlString(headline.Entry)));
|
||||
strQuery = sb.ToString();
|
||||
sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction);
|
||||
sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
|
||||
int result = Convert.ToInt32(sqlCommand.ExecuteScalar());
|
||||
return 0!=result;
|
||||
sqlDataReader=sqlCommand.ExecuteReader();
|
||||
if(!sqlDataReader.Read())return false;
|
||||
return 0==sqlDataReader.GetInt32(0)?false:true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,exception);
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(null!=sqlCommand)sqlCommand.Dispose();
|
||||
if(null!=sqlDataReader){sqlDataReader.Close();sqlDataReader.Dispose();}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1601,39 +1601,46 @@ namespace MarketData.Helper
|
||||
/// <returns></returns>
|
||||
public static string ExtractLongBusinessSummary(string html)
|
||||
{
|
||||
if(string.IsNullOrEmpty(html))return null;
|
||||
// locate the script containing the assetProfile API response
|
||||
int start = html.IndexOf("modules=assetProfile");
|
||||
if (start < 0) return null;
|
||||
try
|
||||
{
|
||||
if(string.IsNullOrEmpty(html))return null;
|
||||
// locate the script containing the assetProfile API response
|
||||
int start = html.IndexOf("modules=assetProfile");
|
||||
if (start < 0) return null;
|
||||
|
||||
// move back to start of script tag
|
||||
start = html.LastIndexOf("<script", start);
|
||||
if (start < 0) return null;
|
||||
// move back to start of script tag
|
||||
start = html.LastIndexOf("<script", start);
|
||||
if (start < 0) return null;
|
||||
|
||||
int jsonStart = html.IndexOf(">", start);
|
||||
if (jsonStart < 0) return null;
|
||||
jsonStart++;
|
||||
int jsonStart = html.IndexOf(">", start);
|
||||
if (jsonStart < 0) return null;
|
||||
jsonStart++;
|
||||
|
||||
int jsonEnd = html.IndexOf("</script>", jsonStart);
|
||||
if (jsonEnd < 0) return null;
|
||||
int jsonEnd = html.IndexOf("</script>", jsonStart);
|
||||
if (jsonEnd < 0) return null;
|
||||
|
||||
string outerJson = html.Substring(jsonStart, jsonEnd - jsonStart);
|
||||
string outerJson = html.Substring(jsonStart, jsonEnd - jsonStart);
|
||||
|
||||
// parse outer JSON
|
||||
JObject outer = Newtonsoft.Json.Linq.JObject.Parse(outerJson);
|
||||
// parse outer JSON
|
||||
JObject outer = Newtonsoft.Json.Linq.JObject.Parse(outerJson);
|
||||
|
||||
// body is escaped JSON
|
||||
string bodyJson = outer["body"]?.ToString();
|
||||
if (bodyJson == null) return null;
|
||||
// body is escaped JSON
|
||||
string bodyJson = outer["body"]?.ToString();
|
||||
if (bodyJson == null) return null;
|
||||
|
||||
// parse inner JSON
|
||||
JObject inner = Newtonsoft.Json.Linq.JObject.Parse(bodyJson);
|
||||
JToken resultToken = inner["quoteSummary"]?["result"]; // Ensure result is an array with at least one element
|
||||
if (resultToken is not JArray resultArray || resultArray.Count == 0)
|
||||
// parse inner JSON
|
||||
JObject inner = Newtonsoft.Json.Linq.JObject.Parse(bodyJson);
|
||||
JToken resultToken = inner["quoteSummary"]?["result"]; // Ensure result is an array with at least one element
|
||||
if (resultToken is not JArray resultArray || resultArray.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return resultArray[0]?["assetProfile"]?["longBusinessSummary"]?.ToString();
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return resultArray[0]?["assetProfile"]?["longBusinessSummary"]?.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user