Menstrual Health Tracking

Author

Marena Marzari, Federica Negron, Diego Farah, Tomas Hache, Sabina Pereira

Published

December 7, 2025

Abstract

This study evaluates consumer preferences for Cycle Sense, a wearable device concept designed to improve menstrual-cycle and fertility tracking through continuous physiological monitoring. Using a discrete choice experiment, we examined how users trade off key design attributes, including device type (patch, ring, wrist strap), price, weight, battery life, prediction window, accuracy, and comfort. The results show that device type and accuracy are the strongest drivers of choice, with respondents expressing a clear preference for the ring form factor over both the patch (baseline) and wrist strap. Higher accuracy and longer battery life significantly increase willingness to choose a device, while higher price and added weight reduce it. Based on these findings, we recommend that Cycle Sense prioritize high-accuracy sensing, multi-day battery performance, and potentially explore a ring-based design if the goal is market adoption.

Introduction

Cycle Sense is a fertility and menstrual-cycle tracking device concept designed to offer a more accurate and effortless experience than traditional methods such as basal thermometers, calendar apps, or hormone test strips. Many existing tools require daily manual input and struggle to deliver precise ovulation predictions, especially for women with irregular cycles. While wrist wearables like the Apple Watch or Oura Ring provide partial insight through temperature or heart-rate measurements, they are not optimized specifically for fertility tracking and often lack the consistency and signal quality needed for dependable predictions.

The original Cycle Sense concept proposed a thin, skin-safe patch capable of continuously monitoring biomarkers such as skin temperature, heart-rate variability, and skin conductance. These inputs would be analyzed through an app that translates physiological signals into personalized fertility forecasts. To evaluate how consumers perceive this concept, we conducted a discrete choice experiment focusing on the product attributes most likely to influence adoption. These included:

  • Device Type: Patch, Ring, or Wrist Strap
  • Price
  • Weight
  • Battery Life
  • Prediction Window
  • Accuracy
  • Comfort

By systematically varying these attributes, we aimed to understand which features consumers value most when choosing a fertility-tracking device. The addition of alternative form factors (ring and wrist strap) allowed us to test whether the patch design was truly preferred or whether users gravitated toward more familiar wearable formats.

Survey Design

Eligibility Requirements

To ensure that the survey responses reflected the preferences of people who would realistically use menstrual-health tracking technologies, we applied two eligibility criteria. First, respondents had to be 18 years of age or older, as indicated by the consent questions. Second, respondents had to currently menstruate, which was asked explicitly in the screening question: “Do you currently menstruate?”. Respondents who answered “No” to either requirement were screened out and redirected to an end page. These requirements ensured that the sample was composed of adults with personal experience relevant to menstrual-cycle tracking and the purchase of such devices.

Respondants Data

In addition to the choice questions, the survey collected several types of information to better understand respondent behavior, needs, and backgrounds. Early questions asked whether participants were currently trying or planning to become pregnant, whether they owned a smartphone and felt comfortable using tracking apps, and whether they already used any menstrual or fertility tracking tools. Respondents were also asked how important menstrual tracking is in their daily lives and which features they find most valuable in a tracking device. Two open-ended questions allowed participants to describe the challenges they face when tracking their cycles and to suggest improvements or features they would like to see in new products. At the end of the survey, demographic information was collected, including age group, education level, geographic region, occupation, and personal comfort with technology.

Educational Material

Before completing the conjoint portion, respondents were shown a short educational section explaining the purpose of menstrual cycle tracking devices and introducing the three wearable types used in the study: a Ring, a Wrist Strap, and a Patch. Images of each device were presented side by side to ensure clarity and prevent misinterpretation. The text also clarified that the ring and wrist strap are reusable devices containing built-in tracking technology, while the patch is a disposable option provided as a pack of single-use patches.

Each product attribute in the choice tasks (price, weight, battery life, prediction window, accuracy, and comfort) was described in simple language, allowing respondents to understand what each feature represented and how to interpret the tradeoffs. This educational content ensured that all respondents began the choice tasks with a consistent understanding of the device types and attributes.

Attributes and Levels Used in the Conjoint Design

The attributes for the choice experiment were selected to reflect the main decisions someone would face when designing a menstrual-tracking device. We included the device type to see whether people prefer familiar wearables like rings and wrist straps, or a disposable patch worn on the skin. Price was added to understand how much people are willing to pay and how sensitive they are to cost differences. Weight was included because heavier devices can feel uncomfortable and may be harder to wear all day. Battery life was used to measure how important charging frequency is, since longer battery life makes reusable devices easier to use. The prediction window showed how far in advance the device could forecast the next menstrual or ovulation phase, which can matter for planning. Accuracy was included because reliable predictions are essential for both general tracking and fertility purposes.

Table

This are our attributes with their definitions.

Show code
library(tibble)
library(knitr)
attribute_table <- tibble(
  Attribute = c(
    "Device Type",
    "Price (USD)",
    "Weight (grams)",
    "Battery Life (days)",
    "Prediction Window (days ahead)",
    "Accuracy (%)",
    "Comfort"
  ),
  Levels = c(
    "Ring, Wrist Strap, Patch",
    "Varied across realistic device prices",
    "Varied (light to heavier options)",
    "Varied (short to long battery life for reusable devices)",
    "Varied (shorter to longer predictions)",
    "Varied (moderate to high accuracy levels)",
    "Varied (lower to higher comfort ratings)"
  )
)

attribute_table
#> # A tibble: 7 × 2
#>   Attribute                      Levels                                         
#>   <chr>                          <chr>                                          
#> 1 Device Type                    Ring, Wrist Strap, Patch                       
#> 2 Price (USD)                    Varied across realistic device prices          
#> 3 Weight (grams)                 Varied (light to heavier options)              
#> 4 Battery Life (days)            Varied (short to long battery life for reusabl…
#> 5 Prediction Window (days ahead) Varied (shorter to longer predictions)         
#> 6 Accuracy (%)                   Varied (moderate to high accuracy levels)      
#> 7 Comfort                        Varied (lower to higher comfort ratings)

Changes in surveys

We made a few small but helpful adjustments after running the pilot survey. We changed the order of the demographic questions so the survey would flow more naturally and feel easier to complete. We also added two open-ended questions to help identify and remove bot responses, since genuine participants typically provide thoughtful text answers. Finally, we made minor adjustments to the transitions between pages to improve the overall survey experience. These updates improved clarity and data quality without changing the core design of the experiment.

Example of our conjoint questions.

This is an example of our conjoint questions.

Data Analysis

Sample Description

The final dataset contains:

  • Total number of respondents: 185

  • Total number of choice-question responses: 1110

  • Number of choice questions per respondent: 6

  • Number of alternatives per question: 3

Across the full sample, respondents varied in their menstrual-tracking behaviors and personal characteristics:

  • Some respondents were trying or planning to become pregnant, while others were not.

  • Most participants owned smartphones and felt comfortable using tracking apps.

  • A portion of respondents already used menstrual or fertility tracking tools.

  • Respondents differed in how important they considered menstrual-cycle tracking in their daily lives.

  • Technology comfort ranged from low to very comfortable.

These differences help explain variation in preferences and provide context for interpreting the conjoint results.

Show code
library(dplyr)
library(knitr)
library(here)
library(gridExtra)

data <- read_csv(here("data", "data_raw.csv"))

demographic_table <- data %>%
  distinct(respID, age_group, education, region, occupation, tech_comfort) %>%
  group_by(age_group, education, region, occupation, tech_comfort) %>%
  summarise(n = n(), .groups = "drop")

table1 <- kable(
  demographic_table,
  caption = "Demographic Breakdown of Survey Respondents"
)

demo <- data %>%
  distinct(respID, age_group, education, region, occupation, tech_comfort) 

p_age <- demo %>%
  filter(!is.na(age_group)) %>%
  ggplot(aes(x = age_group)) +
  geom_bar() +
  labs(title = "Age group", x = NULL, y = "Count") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

p_region <- demo %>%
  filter(!is.na(region)) %>%
  ggplot(aes(x = region)) +
  geom_bar() +
  labs(title = "Region", x = NULL, y = "Count") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

p_edu <- demo %>%
  filter(!is.na(education)) %>%
  ggplot(aes(x = education)) +
  geom_bar() +
  labs(title = "Education", x = NULL, y = "Count") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

p_tech <- demo %>%
  filter(!is.na(tech_comfort)) %>%
  ggplot(aes(x = tech_comfort)) +
  geom_bar() +
  labs(title = "Tech comfort", x = NULL, y = "Count") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

# 2×2 grid
gridExtra::grid.arrange(p_age, p_region, p_edu, p_tech, ncol = 2)

Data Cleaning

For data cleaning, we removed all responses that were missing answers to any of the six choice questions in the CBC experiment, since incomplete choice sets cannot be used in the analysis. We kept only respondents who completed the consent questions and reached the end of the survey. After filtering, we reshaped the data into long format, merged it with the experimental design file, and recoded the choice variable to clearly indicate which alternative each respondent selected. We also created consistent respondent and observation IDs to prepare the dataset for modeling. The rejected responses were those with missing CBC answers, while the final sample includes only participants who completed all required questions. This process ensured that the final dataset contained only high-quality and fully usable responses.

Modeling

Baseline Logit Model

We estimated a multinomial logit (MNL) model to analyze participants’ choices across the six conjoint choice tasks. The model assumes that each respondent i selects the device alternative j in choice set t that provides the highest utility:

Uijt​=β1​(Ring)+β2​(Patch)+β3​(Comfort)+β4​(Accuracy)+β5​(DataPrivacy)+β6​(Integration)+εijt​

Each 𝛽 represents the part-worth utility (preference weight) for a given attribute level. Higher coefficients indicate greater preference for that feature.

Utility Coefficient Estimates with Standard Errors

With the patch being the baseline.

Show code
library(logitr)
library(tidyverse)
library(janitor)
library(here)

data <- read_csv(here("data", "choice_data.csv")) %>% 
    select(ends_with("ID"), choice, type:comfort) 

# Estimate MNL model
model <- logitr(
    data = data,
    outcome = "choice",
    obsID = "obsID",
    pars = c("price","type", "weight","battery","prediction","accuracy", "comfort")
) 

# View summary of results
summary(model)
#> =================================================
#> 
#> Model estimated on: Tue Dec 09 06:42:03 2025 
#> 
#> Using logitr version: 1.1.3 
#> 
#> Call:
#> logitr(data = data, outcome = "choice", obsID = "obsID", pars = c("price", 
#>     "type", "weight", "battery", "prediction", "accuracy", "comfort"))
#> 
#> Frequencies of alternatives:
#>       1       2       3 
#> 0.35045 0.31982 0.32973 
#> 
#> Exit Status: 3, Optimization stopped because ftol_rel or ftol_abs was reached.
#>                                 
#> Model Type:    Multinomial Logit
#> Model Space:          Preference
#> Model Run:                1 of 1
#> Iterations:                   12
#> Elapsed Time:        0h:0m:0.05s
#> Algorithm:        NLOPT_LD_LBFGS
#> Weights Used?:             FALSE
#> Robust?                    FALSE
#> 
#> Model Coefficients: 
#>                    Estimate  Std. Error  z-value  Pr(>|z|)    
#> price           -0.00644015  0.00056649 -11.3684 < 2.2e-16 ***
#> typeRing         1.32892395  0.10940442  12.1469 < 2.2e-16 ***
#> typeWrist Strap  0.82641732  0.11072668   7.4636 8.415e-14 ***
#> weight          -0.09412655  0.05106798  -1.8432  0.065305 .  
#> battery          0.03048773  0.01088721   2.8003  0.005105 ** 
#> prediction       0.02241846  0.02598839   0.8626  0.388339    
#> accuracy         0.13648005  0.00846597  16.1210 < 2.2e-16 ***
#> comfort          0.05093642  0.05121409   0.9946  0.319941    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>                                      
#> Log-Likelihood:          -920.4556798
#> Null Log-Likelihood:    -1219.4596404
#> AIC:                     1856.9113597
#> BIC:                     1897.0083000
#> McFadden R2:                0.2451938
#> Adj McFadden R2:            0.2386335
#> Number of Observations:  1110.0000000

Results

WTP Plot

To understand how much consumers value different product features, we calculated willingness-to-pay (WTP) estimates and simulated 95% confidence intervals. These values convert the model’s utility coefficients into dollar amounts, allowing us to compare the relative importance of each attribute.

The results show that device type is by far the most influential attribute. Consumers are willing to pay about $208 more for a Ring compared to the Patch, and about $129 more for a Wrist Strap. Both estimates have confidence intervals well above zero, meaning these preferences are strong and statistically reliable. Accuracy is also highly valued, with a WTP of about $21 for each percentage-point increase in accuracy. Battery life has a smaller but still meaningful WTP of around $5, indicating that users appreciate longer-lasting devices.

Overall, the key drivers of choice are device type (especially the Ring) and accuracy, while battery life plays a secondary role. The remaining attributes contribute much less to consumer willingness-to-pay.

Show code
load(here("models", "model.RData"))

# Get the model coefficients
coefs <- coef(model)

# Compute WTP estimates
wtp <- coefs / (-1 * coefs['price'])

# Compute WTP with uncertainty:
# Get the model coefficients and covariance matrix
covariance <- vcov(model)

# Take 10,000 draws of the coefficients
coef_draws <- as.data.frame(MASS::mvrnorm(10^4, coefs, covariance))

# Compute WTP for each coefficient draw
wtp_draws = -1 * (coef_draws[, 2:8] / coef_draws[, 1])

# For each coefficient, get the mean and 95% confidence interval of WTP
wtp_ci <- ci(wtp_draws, level = 0.95)

wtp_df <- wtp_ci %>%
  rownames_to_column(var = "attribute") %>%
  as_tibble()

wtp_plot <- ggplot(wtp_df, aes(x = attribute, y = mean)) +
  geom_point(size = 3) +
  geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.2) +
  coord_flip() +
  labs(
    title = "WTP Estimates with 95% Confidence Intervals",
    x = "Attribute",
    y = "Willingness-to-Pay (USD)"
  ) +
  theme_minimal(base_size = 14)

wtp_plot

Market Simulation

To evaluate how our product would perform in a competitive environment, we simulated a hypothetical market that included three menstrual-tracking devices: a Wrist Strap, a Ring, and a Patch (our product). We assigned realistic attribute levels based on typical wearable specifications and the ranges used in our conjoint design. The scenario was designed to compare a lower-priced wrist strap, a mid-priced ring with strong accuracy, and a patch positioned as a high-accuracy but more expensive device. The full set of attributes for each product is shown below.

Show code
library(knitr)

simulation_levels <- tribble(
  ~Attribute,              ~Levels_Used,
  "Device Type",           "Ring, Wrist Strap, Patch",
  "Price (USD)",           "100, 200, 300",
  "Weight (g)",            "2.0, 2.5, 4.0",
  "Battery Life (days)",   "5, 7, 14",
  "Prediction Window",     "2, 4, 6",
  "Accuracy (%)",          "80, 90, 95",
  "Comfort",               "1, 2, 3"
)

kable(simulation_levels,
      caption = "Attribute Levels Used in Simulated Market Scenarios")
Attribute Levels Used in Simulated Market Scenarios
Attribute Levels_Used
Device Type Ring, Wrist Strap, Patch
Price (USD) 100, 200, 300
Weight (g) 2.0, 2.5, 4.0
Battery Life (days) 5, 7, 14
Prediction Window 2, 4, 6
Accuracy (%) 80, 90, 95
Comfort 1, 2, 3

We used the estimated multinomial logit model to compute predicted choice probabilities for each of the three products, along with simulated 95% confidence intervals.

Show code
load(here("models", "model.RData"))

# Create a set of alternatives for which to simulate shares
baseline <- data.frame(
    altID = c(1, 2, 3),
    obsID = c(1, 1, 1),
    type = c('Wrist Strap', 'Ring', "Patch"),
    price = c(100, 200, 300), # USD
    weight = c(2, 2.5, 4), # grams
    battery = c(5, 7, 14), # days
    prediction = c(2, 4, 6), # days ahead
    accuracy = c(80, 90, 95), # %
    comfort = c(1, 2, 3) # mm
)

# Use the predict() function to compute the probabilities
sim_mnl <- predict(
    model,
    newdata = baseline,
    obsID = 'obsID',
    level = 0.95,
    interval = 'confidence',
    returnData = TRUE # This returns your data along with predicted values
)

show <- sim_mnl %>% 
    select(type, predicted_prob, predicted_prob_lower, predicted_prob_upper)

show
#>          type predicted_prob predicted_prob_lower predicted_prob_upper
#> 1 Wrist Strap      0.1659329            0.1225193            0.2188401
#> 2        Ring      0.6292701            0.5783206            0.6742826
#> 3       Patch      0.2047970            0.1523354            0.2705167

These results show that the Ring clearly dominates the market under this scenario, capturing an estimated 63% share. The Patch earns about 20%, while the Wrist Strap is the least preferred option at around 17%.

The simulation highlights how strongly consumers favor the Ring relative to both the Wrist Strap and the Patch. Even though the Ring is priced higher than the Wrist Strap and offers only moderate improvements in battery life and comfort, its combination of form factor and accuracy leads to the highest predicted market share.

Show code
load(here("sims", "mnl.RData"))

# Bar plot of probabilities for single market simulation (with 95% CI)
sim_mnl %>%
    mutate(label = c("Wrist Strap", "Ring", "Patch")) %>%
    ggplot(aes(
        x = label,
        y = predicted_prob,
        ymin = predicted_prob_lower,
        ymax = predicted_prob_upper
    )) +
    geom_col(fill = "grey", width = 0.6) +
    geom_errorbar(width = 0.3) +
    scale_y_continuous(limits = c(0, 1), labels = scales::percent) +
    labs(x = 'Alternative', y = 'Market Share',
    title = "Market Share for each device")+
    theme_bw()

The market simulation results point to a clear opportunity for improving our product by changing its form factor. Because device type is the strongest driver of preference (and the ring consistently dominates both in willingness-to-pay and predicted market share) the analysis suggests that consumer demand would be significantly higher if our product were offered as a ring rather than a patch. While accuracy and battery life still matter, they play a secondary role compared to the overwhelming preference for the ring format. Adjusting the physical design of Cycle Sense from a disposable patch to a reusable ring would align the product with the attributes users value most and would likely result in far greater adoption. This design shift, combined with maintaining high accuracy and a competitive price, represents the strongest opportunity to increase market demand.

Sensitivity in Market Demand

To understand which product features most strongly influence demand for our product, we conducted a one-at-a-time sensitivity analysis using the Patch as the baseline design. In this analysis, we held all other product attributes constant and varied one attribute of the Patch at a time between the lowest and highest levels used in the conjoint experiment. For each attribute shift, we used the logit model to predict the Patch’s market share. The difference between the minimum and maximum predicted share reflects how sensitive demand is to that attribute.

Show code
our_type <- "Patch"

# Baseline scenario: all products identical except type
market_base <- tribble(
    ~obsID, ~type,           ~price, ~weight, ~battery, ~prediction, ~accuracy, ~comfort,
    1,     "Ring",            200,     2.5,       7,          4,         90,       2,
    1,     "Wrist Strap",     200,     2.5,       7,          4,         90,       2,
    1,     "Patch",           200,     2.5,       7,          4,         90,       2
)

get_share <- function(market_df, our_type = "Ring") {
    
    probs <- predict(
        model,
        newdata    = market_df,
        obsID      = "obsID",
        type       = "prob",
        returnData = TRUE
    )
    
    probs %>%
        filter(type == our_type) %>%
        summarise(share = mean(predicted_prob)) %>%
        pull(share)
}

levels_list <- list(
    price      = c(100, 300),
    weight     = c(2.0, 4.0),
    battery    = c(5,   14),
    prediction = c(2,    6),
    accuracy   = c(80,  95),
    comfort    = c(1,    3)
)

sensitivity_list <- list()

for (att in names(levels_list)) {
    
    market_low  <- market_base
    market_high <- market_base
    
    # Identify the row belonging to OUR PRODUCT (Ring)
    idx_low  <- market_low$type  == our_type
    idx_high <- market_high$type == our_type
    
    # Set low / high levels
    market_low[idx_low,  att]  <- levels_list[[att]][1]
    market_high[idx_high, att] <- levels_list[[att]][2]
    
    # Simulate market share at low / high levels
    share_low  <- get_share(market_low,  our_type = our_type)
    share_high <- get_share(market_high, our_type = our_type)
    
    # Store results
    sensitivity_list[[att]] <- tibble(
        attribute = att,
        min_share = share_low,
        max_share = share_high
    )
}

# Combine results
sensitivity_df <- bind_rows(sensitivity_list) %>%
    mutate(range = max_share - min_share)

sensitivity_df
#> # A tibble: 6 × 4
#>   attribute  min_share max_share   range
#>   <chr>          <dbl>     <dbl>   <dbl>
#> 1 price         0.239     0.0797 -0.159 
#> 2 weight        0.147     0.125  -0.0221
#> 3 battery       0.134     0.170   0.0352
#> 4 prediction    0.136     0.147   0.0109
#> 5 accuracy      0.0404    0.246   0.206 
#> 6 comfort       0.136     0.148   0.0124
Show code
ggplot(sensitivity_df,
       aes(x = reorder(attribute, range), y = range)) +
    geom_bar(stat = "identity", fill = "steelblue") +
    coord_flip() +
    labs(
        title = "Sensitivity of Market Share to Product Attributes",
        x = "Attribute",
        y = "Change in Market Share"
    ) +
    theme_minimal(base_size = 14)

The tornado plot shows that accuracy has the largest positive impact on Patch market share. Increasing accuracy across its range produces the biggest gain in predicted demand, indicating that users place a high value on precise and reliable fertility predictions. This result aligns with our willingness-to-pay estimates, which also showed that accuracy is one of the highest-valued continuous attributes.

Overall, the tornado plot highlights a clear hierarchy of attribute importance. Accuracy and price are the dominant drivers of Patch demand, and improving accuracy or reducing price would yield the greatest gains in market share.

Market Share vs. Price

The market share simulation shows a clear negative relationship between price and demand for the Patch. At $100, the Patch captures about 23–24% market share, but this declines steadily as price increases. By $200, share drops to around 15%, and at $300 it falls below 9%, indicating strong price sensitivity even for the most preferred device type.

These results suggest that the Patch remains competitive only at moderate price levels. A pricing range of roughly $120–$180 appears optimal, balancing higher revenue per unit with enough demand to maintain a strong market position. Prices above $200 lead to substantial reductions in market share, making the product far less competitive.

Show code
our_type <- "Patch"

# Baseline scenario: everything fixed except price (we'll vary it)
market_base <- tribble(
  ~obsID, ~type,           ~price, ~weight, ~battery, ~prediction, ~accuracy, ~comfort,
   1,     "Ring",            200,     2.5,       7,          4,         90,       2,
   1,     "Wrist Strap",     200,     2.5,       7,          4,         90,       2,
   1,     "Patch",           200,     2.5,       7,          4,         90,       2
)

# Helper to get Ring's share for a given market scenario
get_share <- function(market_df, our_type = "Ring") {
  probs <- predict(
    model,
    newdata    = market_df,
    obsID      = "obsID",
    type       = "prob",
    returnData = TRUE
  )
  
  probs %>%
    filter(type == our_type) %>%
    summarise(share = mean(predicted_prob)) %>%
    pull(share)
}

# Range of prices to test (adjust if needed)
price_grid <- seq(100, 300, by = 10)

# For each price, change only the Ring price and recompute share
share_vs_price <- map_dfr(price_grid, function(p) {
  market_p <- market_base
  market_p$price[market_p$type == our_type] <- p
  
  tibble(
    price = p,
    share = get_share(market_p, our_type = our_type)
  )
})


ggplot(share_vs_price, aes(x = price, y = share)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  labs(
    title = "Predicted Market Share of Patch vs. Price",
    x = "Price (USD)",
    y = "Predicted Market Share"
  ) +
  theme_minimal(base_size = 14)

Our sample is small and not fully representative, so results may not generalize to the broader population. Stated survey choices may differ from real-world behavior, and the model excludes external factors like brand trust, clinical evidence, and market competition.

Final Recommendations and Conclusions

Our results show that the Ring version of Cycle Sense is the only design that performs strongly in the market. It takes most of the predicted market share and has the highest willingness-to-pay. The Patch, even with better features, stays far behind. Because of this, Cycle Sense would only be competitive if we shift the product from a Patch to a Ring.

Price matters a lot. The Ring stays competitive mainly between $150–$180. Once the price goes above $200, demand drops quickly. Accuracy is also very important, improving accuracy increases demand more than any other feature besides changing the device type.

There are still uncertainties. Real purchasing behavior could differ from survey choices, and factors like brand trust, clinical proof, or data privacy may affect adoption.

Recommendations:

  • Change the product to a Ring, since that’s what consumers clearly prefer.

  • Set the price around $150–$180 to stay competitive.

  • Focus on accuracy as the main performance feature.

In short: a Ring at a reasonable price with high accuracy gives Cycle Sense the best chance of success.

Limitations

To improve this analysis, the most valuable next step would be to collect real purchase behavior data instead of only survey responses. Testing the product with a larger and more diverse sample would also help make the results more representative. In addition, testing real prototypes would allow us to measure true comfort, usability, and long-term adherence rather than relying on stated preferences. Data on brand trust, clinical validation, and privacy concerns would also strengthen future decisions.

The biggest unknowns that could affect our findings include whether people would actually buy the product at the predicted prices, how much trust and medical credibility matter in real adoption, and how data privacy concerns influence behavior. Manufacturing costs and competition from established brands could also significantly impact real-world profitability.

Appendix

Show code
library(surveydown)

Menstrual cycle tracking devices, such as rings, patches, and wristbands, help monitor hormonal patterns, symptoms, and fertility windows to better understand reproductive health. They provide personalized insights that can support wellness, planning, and early detection of irregularities. You’re taking this survey to share your preferences and feedback, helping improve future menstrual tracking technologies.

Show code
sd_next()

Eligibility

Show code
sd_question(
  type   = "mc",
  id     = "screenout",
  label  = "Do you currently menstruate?",
  option = c(
    "Yes" = "yes",
    "No" = "no"
  )
)
*
Show code
sd_next()

Women Questions

Show code
sd_question(
  type   = "mc",
  id     = "planning_pregnancy",
  label  = "Are you currently trying to become pregnant or planning to within the next 12 months?",
  option = c(
    "Yes" = "yes",
    "No" = "no"
  )
)
*
Show code
sd_question(
  type   = "mc",
  id     = "smartphone_use",
  label  = "Do you own a smartphone and feel comfortable using health or tracking apps?",
  option = c(
    "Yes" = "yes",
    "No" = "no"
  )
)
*
Show code
sd_question(
  type   = "mc",
  id     = "uses_tracking",
  label  = "Do you currently use any fertility or menstrual-cycle tracking tools?",
  option = c(
    "Yes" = "yes",
    "No" = "no"
  )
)
*
Show code
sd_next()

For each one, please select the device you would most prefer to use

Show code
sd_question(
  type   = "mc_buttons",
  id     = "importance_tracking",
  label  = "How important is it for you to track your menstrual cycle?",
  option = c(
    "Not important at all" = "not_important_at_all",
    "Slightly Important" = "slightly_important",
    "Moderately Important" = "moderately_important",
    "Very Important" = "very_important",
    "Extremely Important" = "extremely_important"
  )
)

*
Show code
sd_question(
  type   = "mc_multiple",
  id     = "feature_interest",
  label  = "Which of the following features would you find most useful in a menstrual health tracking device? (Select all that apply)",
  option = c(
    "Cycle prediction & reminders" = "cycle_prediction_reminders",
    "Fertility window tracking" = "fertility_window_tracking",
    "Symptom and mood logging" = "symptom_and_mood_logging",
    "Sleep or energy monitoring" = "sleep_or_energy_monitoring",
    "Stress management & mindfulness alerts" = "stress_management_mindfulness_alerts",
    "Integration with Apple Health or Fitbit" = "integration_with_apple_health_or_fitbit"
  )
)
*
Show code
sd_question(
  type  = "textarea",
  id    = "challenges_tracking",
  label = "What challenges or frustrations do you currently face when tracking your cycle?"
)
*
Show code
sd_question(
  type  = "textarea",
  id    = "improvements_open",
  label = "What improvements or unique features would make this product stand out for you?"
)
*
Show code
sd_next()

In the next section, you’ll see six sets of device options. Each set shows three menstrual health tracking devices with different combinations of features.

We’ll be showing you three types of devices — a Ring, a Wrist Strap, and a Patch — all designed to track menstrual health and ovulation. Below are the product types and their features:

| |

  • Ring and Wrist Strap: Reusable devices that you purchase once. They include both the physical device and the built-in tracking technology that syncs with an app.

  • Patch: A disposable option that comes as a case containing 24 single-use patches, designed to be replaced every month for continued tracking.

Product Features

  • Price (USD): The cost of the device or patch pack.

  • Weight (grams): How heavy the device feels when worn.

  • Battery Life (days): How long the device lasts before needing to be recharged or replaced.(For ring and wrist strap - ignore this feature for ring)

  • Prediction Window (days ahead): How many days in advance the device can predict the next menstrual or ovulation phase.

  • Accuracy (%): How precise the device’s predictions are.

  • Comfort (mm): How comfortable the device feels on the body, based on the material and fit (higher numbers mean greater comfort).

Show code
sd_next()

Conjoint Question 1

Show code
sd_output("cbc_q1", type = "question")
*
Show code
sd_next()

Conjoint Question 2

Show code
sd_output("cbc_q2", type = "question")
*
Show code
sd_next()

Conjoint Question 3

Show code
sd_output("cbc_q3", type = "question")
*
Show code
sd_next()

Conjoint Question 4

Show code
sd_output("cbc_q4", type = "question")
*
Show code
sd_next()

Conjoint Question 5

Show code
sd_output("cbc_q5", type = "question")
*
Show code
sd_next()

Conjoint Question 6

Show code
sd_output("cbc_q6", type = "question")
*
Show code
sd_next()

This is just to know a little more about you.

Show code
sd_question(
  type   = "mc",
  id     = "age_group",
  label  = "What is your age range?",
  option = c(
    "18–24" = "18_24",
    "25–34" = "25_34",
    "35–44" = "35_44",
    "45+" = "45"
  )
)
*
Show code
sd_question(
  type   = "mc",
  id     = "education",
  label  = "What is the highest level of education you have completed?",
  option = c(
    "High school diploma or equivalent" = "high_school_diploma_or_equivalent",
    "Bachelor’s degree" = "bachelor_s_degree",
    "Master’s degree" = "master_s_degree",
    "Doctoral or professional degree" = "doctoral_or_professional_degree"
  )
)
*
Show code
sd_question(
  type   = "mc",
  id     = "region",
  label  = "In which region do you currently reside?",
  option = c(
    "North America" = "north_america",
    "Central America" = "central_america",
    "South America" = "south_america",
    "Europe" = "europe",
    "Asia" = "asia",
    "Africa" = "africa",
    "Oceania" = "oceania",
    "Prefer not to say" = "prefer_not_to_say"
  )
)
*
Show code
sd_next()

Please answer a few final questions about yourself.

Show code
sd_question(
  type   = "mc",
  id     = "occupation",
  label  = "Which best describes your primary occupation or field?",
  option = c(
    "Student" = "student",
    "Healthcare" = "healthcare",
    "Technology / Engineering" = "technology_engineering",
    "Education / Research" = "education_research",
    "Business / Finance" = "business_finance",
    "Other" = "other"
  )
)
*
Show code
sd_question(
  type   = "mc_buttons",
  id     = "tech_comfort",
  label  = "How comfortable are you using technology for personal health tracking?",
  option = c(
    "Not comfortable" = "not_comfortable",
    "Somewhat comfortable" = "somewhat_comfortable",
    "Comfortable" = "comfortable",
    "Very comfortable" = "very_comfortable",
    "Extremely comfortable" = "extremely_comfortable"
  )
)

*
Show code
sd_next()

End Page

The survey is finished. Thank you for your feedback!

Your completion code is:

You may close the window now.

Show code
sd_close()

End Page

Sorry, but you are not qualified to do this survey.

The survey is now finished. You may close the window.

Show code
sd_close()