Validar un producto una vez no es suficiente. Los márgenes de Amazon FBA cambian a medida que los competidores cambian los precios, Amazon ajusta las tarifas y la demanda fluctúa estacionalmente. Una prueba de estrés de ganancias analiza su producto a través de múltiples escenarios utilizando datos de mercado en vivo: ¿qué sucede si el precio promedio cae un 20%? ¿Qué pasa si entran tres nuevos competidores? Este tutorial crea una prueba de estrés automatizada que extrae datos en vivo de Amazon y Google a través de la API de Scavio a $0,005 por búsqueda.
Requisitos previos
- Python 3.9+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Una idea de producto con coste unitario y coste de envío conocidos
Guia paso a paso
Paso 1: Obtenga datos de precios de la competencia en vivo
Busque en Amazon la categoría de su producto y extraiga los precios actuales. Esta es la base para las pruebas de estrés.
import os, requests, re, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def get_market_pricing(product: str) -> dict:
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': f'site:amazon.com {product}', 'country_code': 'us', 'num_results': 10})
results = resp.json().get('organic_results', [])
prices = []
for r in results:
matches = re.findall(r'\$([\d,]+\.\d{2})', r.get('snippet', '') + ' ' + r.get('title', ''))
prices.extend(float(m.replace(',', '')) for m in matches)
if not prices:
return {'avg': 0, 'min': 0, 'max': 0, 'count': 0, 'prices': []}
return {
'avg': sum(prices) / len(prices),
'min': min(prices),
'max': max(prices),
'count': len(prices),
'prices': sorted(prices),
}
pricing = get_market_pricing('yoga mat thick non-slip')
print(f'Market pricing: ${pricing["min"]:.2f} - ${pricing["max"]:.2f}')
print(f'Average: ${pricing["avg"]:.2f} from {pricing["count"]} data points')Paso 2: Definir escenarios de pruebas de resistencia
Cree múltiples escenarios de estrés que simulen cambios realistas en el mercado. Cada escenario modifica los precios, las tarifas o los niveles de competencia.
from dataclasses import dataclass
@dataclass
class Scenario:
name: str
price_modifier: float # Multiply avg price by this
fee_modifier: float # Multiply Amazon fees by this
extra_cost: float # Additional per-unit cost
SCENARIOS = [
Scenario('Base case', 1.0, 1.0, 0),
Scenario('Price war (-20%)', 0.80, 1.0, 0),
Scenario('Price war (-30%)', 0.70, 1.0, 0),
Scenario('Fee increase (+10%)', 1.0, 1.10, 0),
Scenario('Shipping cost spike', 1.0, 1.0, 2.00),
Scenario('Premium positioning (+15%)', 1.15, 1.0, 1.50),
Scenario('Worst case: price war + fees', 0.75, 1.15, 1.00),
]
print(f'Defined {len(SCENARIOS)} stress scenarios:')
for s in SCENARIOS:
print(f' {s.name}: price x{s.price_modifier}, fees x{s.fee_modifier}, +${s.extra_cost} cost')Paso 3: Ejecute la prueba de estrés con datos en vivo
Ejecute cada escenario con los datos del mercado en vivo para calcular los márgenes esperados. La prueba de estrés muestra exactamente dónde se rompe la rentabilidad.
def stress_test(product: str, unit_cost: float, shipping: float = 3.0) -> list:
"""Run all stress scenarios against live market data."""
pricing = get_market_pricing(product)
if pricing['avg'] == 0:
return [{'scenario': 'ERROR', 'reason': 'No pricing data'}]
results = []
for scenario in SCENARIOS:
sell_price = pricing['avg'] * scenario.price_modifier
referral_fee = sell_price * 0.15 * scenario.fee_modifier
fba_fee = 4.50 * scenario.fee_modifier
total_cost = unit_cost + shipping + referral_fee + fba_fee + scenario.extra_cost
profit = sell_price - total_cost
margin = profit / sell_price if sell_price > 0 else 0
results.append({
'scenario': scenario.name,
'sell_price': sell_price,
'total_cost': total_cost,
'profit': profit,
'margin': margin,
'profitable': profit > 0,
'margin_ok': margin >= 0.20,
})
return results
results = stress_test('yoga mat thick non-slip', unit_cost=6.00)
print(f'Stress Test: yoga mat thick non-slip')
print(f'Unit cost: $6.00, Shipping: $3.00')
print('-' * 65)
for r in results:
status = 'OK' if r['margin_ok'] else 'LOW' if r['profitable'] else 'LOSS'
print(f"[{status:4s}] {r['scenario']:30s} "
f"Price: ${r['sell_price']:6.2f} "
f"Profit: ${r['profit']:6.2f} "
f"Margin: {r['margin']:5.0%}")Paso 4: Generar la recomendación de ir/no ir
Analice los resultados de las pruebas de estrés para hacer una recomendación basada en datos. Un producto pasa si sigue siendo rentable en la mayoría de los escenarios.
def recommendation(product: str, unit_cost: float, shipping: float = 3.0) -> dict:
results = stress_test(product, unit_cost, shipping)
profitable_count = sum(1 for r in results if r['profitable'])
good_margin_count = sum(1 for r in results if r['margin_ok'])
total = len(results)
# Calculate break-even price
base = next(r for r in results if r['scenario'] == 'Base case')
# Recommendation logic
if good_margin_count >= total - 1:
verdict = 'STRONG GO'
reason = f'Profitable with good margins in {good_margin_count}/{total} scenarios'
elif profitable_count >= total - 1:
verdict = 'GO'
reason = f'Profitable in {profitable_count}/{total} scenarios but margins tight'
elif profitable_count >= total // 2:
verdict = 'CAUTION'
reason = f'Only profitable in {profitable_count}/{total} scenarios'
else:
verdict = 'NO GO'
reason = f'Unprofitable in {total - profitable_count}/{total} scenarios'
print(f'\nRECOMMENDATION: {verdict}')
print(f'Reason: {reason}')
print(f'Base margin: {base["margin"]:.0%} (${base["profit"]:.2f}/unit)')
print(f'Worst margin: {min(r["margin"] for r in results):.0%}')
print(f'API cost for this analysis: $0.005')
return {'verdict': verdict, 'reason': reason, 'results': results}
rec = recommendation('yoga mat thick non-slip', unit_cost=6.00)Ejemplo en Python
import os, requests, re
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def stress_test(product, unit_cost, shipping=3.0):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': f'site:amazon.com {product}', 'country_code': 'us', 'num_results': 10})
prices = [float(m.replace(',','')) for r in resp.json().get('organic_results', [])
for m in re.findall(r'\$([\d,]+\.\d{2})', r.get('snippet',''))]
avg = sum(prices)/len(prices) if prices else 0
for label, mult in [('Base', 1.0), ('-20%', 0.8), ('-30%', 0.7)]:
price = avg * mult
cost = unit_cost + shipping + price*0.15 + 4.50
profit = price - cost
margin = profit/price if price else 0
print(f'{label:6s} ${price:6.2f} -> ${profit:5.2f} ({margin:.0%})')
stress_test('yoga mat thick', 6.00)Ejemplo en JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function stressTest(product, unitCost, shipping = 3) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: `site:amazon.com ${product}`, country_code: 'us', num_results: 10 })
});
const results = (await resp.json()).organic_results || [];
const prices = results.flatMap(r => ((r.snippet||'').match(/\$([\d,]+\.\d{2})/g) || []).map(p => parseFloat(p.slice(1).replace(',',''))));
const avg = prices.length ? prices.reduce((a,b) => a+b,0) / prices.length : 0;
for (const [label, mult] of [['Base', 1.0], ['-20%', 0.8], ['-30%', 0.7]]) {
const price = avg * mult;
const cost = unitCost + shipping + price*0.15 + 4.50;
const profit = price - cost;
console.log(`${label.padEnd(6)} $${price.toFixed(2)} -> $${profit.toFixed(2)} (${((profit/price)*100).toFixed(0)}%)`);
}
}
stressTest('yoga mat thick', 6.00);Salida esperada
Stress Test: yoga mat thick non-slip
Unit cost: $6.00, Shipping: $3.00
-----------------------------------------------------------------
[OK ] Base case Price: $ 24.99 Profit: $ 7.74 Margin: 31%
[OK ] Price war (-20%) Price: $ 19.99 Profit: $ 3.49 Margin: 17%
[LOW ] Price war (-30%) Price: $ 17.49 Profit: $ 1.37 Margin: 8%
[OK ] Fee increase (+10%) Price: $ 24.99 Profit: $ 6.85 Margin: 27%
[OK ] Shipping cost spike Price: $ 24.99 Profit: $ 5.74 Margin: 23%
[OK ] Premium positioning (+15%) Price: $ 28.74 Profit: $ 10.43 Margin: 36%
[LOW ] Worst case: price war + fees Price: $ 18.74 Profit: $ 0.76 Margin: 4%
RECOMMENDATION: GO
Reason: Profitable in 7/7 scenarios but margins tight