Encuentre el mejor período para invertir en un fondo índice S & P500

8

Estos son los rendimientos anuales de un hipotético fondo de índice de acciones S&P 500 para cada año calendario de 1928 a 2017, expresado como un multiplicador. Entonces, en 1928, podría decir "el índice subió un 37.88%", que he representado aquí por 1.3788.

1.3788, 0.8809, 0.7152, 0.5293, 0.8485, 1.4659, 0.9406, 1.4137, 1.2792, 0.6141,  1.2521, 0.9455, 0.8471, 0.8214, 1.1243,  1.1945, 1.138, 1.3072, 0.8813, 1,  0.9935, 1.1026, 1.2178, 1.1646, 1.1178,  0.9338, 1.4502, 1.264, 1.0262, 0.8569,  1.3806, 1.0848, 0.9703, 1.2313, 0.8819,  1.1889, 1.1297, 1.0906, 0.8691, 1.2009,  1.0766, 0.8864, 1.001, 1.1079, 1.1563,  0.8263, 0.7028, 1.3155, 1.1915, 0.885,  1.0106, 1.1231, 1.2577, 0.9027, 1.1476,  1.1727, 1.014, 1.2633, 1.1462, 1.0203,  1.124, 1.2725, 0.9344, 1.2631, 1.0446,  1.0706, 0.9846, 1.3411, 1.2026, 1.3101,  1.2667, 1.1953, 0.8986, 0.8696, 0.7663,  1.2638, 1.0899, 1.03, 1.1362, 1.0353,  0.6151, 1.2345, 1.1278, 1, 1.1341,  1.296, 1.1139, 0.9927, 1.0954, 1.1942

Fuente: https://www.macrotrends.net/2526/sp-500-historical-annual-returns

Desafío

Dado como entradas:

  • el conjunto de rendimientos anuales (pero vea la Regla 2. a continuación)
  • una matriz de números positivos (las cantidades a invertir en cada año del período de inversión)X1K90

escriba un programa o función que genere lo que habría sido el "mejor" período consecutivo de para haber invertido las cantidades en , donde:KX

  • cada cantidad se invierte al comienzo de un año.
  • todo lo que queda después de cada año se reinvierte al comienzo de cada año posterior.
  • "mejor" significa la cantidad más grande al final del período de años.K

Reglas

  1. Este es el , por lo que gana la menor cantidad de bytes en cada idioma. Aplican reglas estándar. Explicaciones alentadas.

  2. Si no le gusta la forma en que he representado el conjunto de rendimientos anuales, puede cambiarlos a cualquier otro conjunto de 90 números que prefiera.

  3. Puede generar el mejor período de años de cualquier manera coherente (p. Ej., Indexado 0 o indexado, el primer y / o último año que invirtió, etc.) pero necesita decir qué representa su producción si no es t obvio.K

  4. En caso de empate, envíe cualquiera o todas las respuestas correctas.

Ejemplo de cálculo

Supongamos que .X=[10000,20000,30000]

Si hubiera invertido estos montos en 1928, 1929 y 1930 (los índices 1 1, 2 y 3), habría terminado con 42743.10. Triste.

Pero si hubiera invertido esos montos en 2014, 2015 y 2016 (los índices 1 87, 88 y 89) habría terminado con 66722.66. Un poco mejor.

Resulta que el mejor período de tres años para haber invertido estas cantidades habría sido 1995, 1996 y 1997 (1-índices 68, 69 y 70), lo que resulta en 91942.91. Agradable.

Casos de prueba

1 índice, primer año de período óptimo

[ 1, 2, 3 ]                          ->  68
[ 1 ]                                ->   6
* any array of length 90 *           ->   1
[ 1, 1 ]                             ->  27
[ 1, 2 ]                             ->   8
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]  ->  62
[ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]        ->  64
* 1 repeated 20 times *              ->  53
ngm
fuente
La regla 2 dice que podemos reemplazarlos con cualquier otra matriz de 90 números. Supongo que no es válido reemplazarlo con una matriz que es 1 seguida de 89 0s, por lo que 1 es siempre la respuesta correcta. ¿O quiso decir "tomar cualquier entrada que desee, pero el número que obtiene la salida tiene que coincidir con los casos de prueba"?
Kamil Drakari
1
@KamilDrakari puedes hacer cualquier transformación 1-1 que quieras. Sin embargo, debe terminar con la respuesta correcta real. La idea es que alguien prefiera los retornos acumulativos, o esos retornos menos 1. Está ahí para la flexibilidad. Pero si también hay alguna oportunidad de golf escondida, que así sea.
ngm
@ngm está bien, así que es "puedes codificar esta entrada de la forma que quieras" en lugar de "tu respuesta solo necesita trabajar para un valor específico para esta entrada, y puedes elegir qué es"
Kamil Drakari
@KamilDrakari sí, aunque no del modo que desee , todavía está limitado a una matriz con 90 elementos.
ngm
"Entonces en 1927 se podría decir ..." - Creo que te refieres a 1928.
Jonathan Allan

Respuestas:

6

Jalea , 9 bytes

PÐƤ⁹L¤ƤḋM

Un enlace diádico que produce una lista de todos los índices iniciales máximos basados ​​en 1.

Pruébalo en línea!

(o ṡL}PÐƤ€ḋM)

¿Cómo?

PÐƤ⁹L¤ƤḋM - Link: list of returns, list of nominal investments
      Ƥ   - for infixes of (the returns)...
          - ...of length:
     ¤    -               nilad followed by links as a nilad:
   ⁹      -                 chain's right argument (nominals)
    L     -                 length
          - ...do:
 ÐƤ       -        for post-fixes:
P         -          product
       ḋ  - dot-product (each) with (the nominals)
        M - maximal indices
Jonathan Allan
fuente
3

Japt , 25 bytes

ãVl)míV ®rÈ+YÌ *Yg}0
bUrw

Pruébalo en línea!

Salida indexada a 0.

Explicación, con Ula lista de retornos y Vla lista de inversiones:

ã                       :Get subsections of U
 Vl)                    : with the same length as V
    m                   :For each of those sections
     í                  : pair each element with
      V                 : the corresponding element from V
        ®          0    :Calculate the investment results of each by:
         r        }     : for each year:
          È+            :  add the result of the previous year
            YÌ          :  to this year's investment
               *Yg      :  and multiply by this year's return

b                       :Get the index of
 Urw                    : the maximum

Respuesta de trampa extra:

Japt , 13 bytes

OvUÎò3 ®n dÃq

Pruébalo en línea!

Toma la lista de retornos como esta matriz , que es una matriz de 90 cadenas donde cada cadena contiene un entero de base 10 rellenado con 1929 dígitos; Creo que esto técnicamente cumple con los requisitos. El enlace "Pruébelo" solo tiene el primer elemento de la lista de "devoluciones" porque el elemento completo rompió el generador de enlaces permanentes, pero ese es el único que se utiliza. Puede pegar todo desde pastebin si lo desea.

Explicación:

Como se mencionó, en realidad solo se usa el primer elemento de la matriz de "retornos"; todos los demás elementos son 0 en el pastebin e ignorados por el programa. El primer elemento es generada por este , que lleva la representación de cadena de un programa Japt, convierte cada carácter en un número de 3 dígitos, y se une a esos números en una nueva cadena de dígitos solo. El código que se codifica es este , que es básicamente mi respuesta principal ajustada para codificar los retornos. Entonces el programa de "respuesta" es simplemente:

  UÎ             :Get the first element
    ò3           :Cut it into slices of length 3
       ®n        :Convert those strings to numbers
          dà    :Convert those numbers to characters
            q    :Join all the characters into one string
Ov               :Execute it as Japt
Kamil Drakari
fuente
No estoy seguro de si la versión de 13 bytes sigue las reglas predeterminadas (codificar el código real en entradas flexibles parece una laguna ), ¡pero me gusta de todos modos!
ngm
@ngm quiero decir, lo llamé una respuesta trampa y lo añadí a una respuesta real por una razón. Principalmente solo estaba tratando de estirar los límites de "cualquier otra matriz de 90 números que prefiera".
Kamil Drakari
2

JavaScript (ES6), 73 bytes

Toma entrada como (annual_returns)(X). El resultado está indexado a 0.

a=>x=>a.map((_,i)=>x.map((c,j)=>(t=(t+c)*a[i+j])>m&&(r=i,m=t),t=0),m=0)|r

Pruébalo en línea!

Arnauld
fuente
2

J, 48 bytes

1+[:(i.>./)[:({:@[*{.@[+*/@])/"2[(|.@,."1)#@[]\]

Pruébalo en línea!

sin golf

1 + [: (i. >./) [: ({:@[ * {.@[ + */@])/"2 [ |.@,."1 #@[ ]\ ]

cómo

Tome la lista de entrada (por ejemplo, 123) a la izquierda, los datos a la derecha.

#@[ ]\ ] Corte los datos en infijos cuya longitud coincida con la entrada:

1.3788 0.8809 0.7152
       0.8809 0.7152 0.5293
              0.7152 0.5293 0.8485

[ ,."1 ahora comprime cada uno de esos grupos de 3 con la lista de entrada

1      2      3
1.3788 0.8809 0.7152
       1      2      3
       0.8809 0.7152 0.5293
              1      2      3
              0.7152 0.5293 0.8485

|.@ y revertirlos:

3      2      1
0.7152 0.8809 1.3788

(verb to insert)/"2 Entre los elementos de cada grupo comprimido de 3, inserte el verbo entre paréntesis.

3             2             1
        VERB          VERB
0.7152        0.8809        1.3788

({:@[ * {.@[ + */@]) es el verbo insertado, que reducirá cada elemento de la lista de grupos de tres comprimidos a un número, que es la cantidad ganada en ese grupo de años:

          2. plus the first      1. */] = product of right args
             (top) item on left
              +-+     +--------+
              |2|  +  |    1   |
              +-+     |    *   |     
                      | 1.3788 |
             *        +--------+

          0.8809  

          3. Multiply that sum by the bottom
             number on the left.

(i. >./) Tome la lista así reducida y encuentre el índice del máximo.

1 + [: Y agrega uno

Jonás
fuente
1

Jalea , 11 bytes

ṡ⁹L¤U×\€UḋM

Pruébalo en línea!

El factor de retorno de un depósito es el producto acumulativo de los factores de retorno en los años hasta el final del Kperíodo del año. Si se nos permite tomar la entrada a la inversa y generar un número de año como 2018- [fecha de finalización], la solución de 10 bytes×\⁹L¤Ƥ×S€M funciona.

ṡ                All overlapping slices of left input of length:
 ⁹L¤               length(right input)
                 Calculate cumulative returns list for each possible year:
    U              Reverse each element of the result
     ×\€           Take the cumulative product
        U          Reverse again
         ḋ      Dot product with the deposits list.
                The final balance when invested in each year.
          M     Get all indices of maximum values
lirtosiast
fuente
ṡL}ahorra un byte ṡ⁹L¤(mi alternativa de 9 bytes, ṡL}PÐƤ€ḋMes efectivamente una versión más golfizada)
Jonathan Allan
@ JonathanAllan Todavía estoy aprendiendo Jelly. ¿Cómo funciona exactamente, }es siempre equivalente a ⁹[monad]¤?
lirtosiast el
1
No, no es exactamente equivalente. El }rápido trata a la mónada a su izquierda como si fuera una díada y usa el argumento derecho como la entrada izquierda a esa díada (sin hacer nada con el argumento izquierdo), como tal, el análisis del código que contiene L}es como si fuera una díada, mientras que el análisis del código que contiene ⁹L¤es como si fuera una nilad: si intenta el reemplazo en el código de Erik, no funcionará ya que la siguiente parte de la cadena es una díada (mientras que la siguiente en la suya es una mónada).
Jonathan Allan
1

Python 2 , 97 bytes

lambda r,v:max(range(len(r)-len(v)+1),key=lambda i:reduce(lambda x,(a,b):(x+a)*b,zip(v,r[i:]),0))

Pruébalo en línea!

Devoluciones 0indexadas

TFeld
fuente
El último elemento de rdebería ser 1.1942. Además, len(r)es 90.
Erik the Outgolfer
@EriktheOutgolfer Corregido
TFeld
1

05AB1E , 21 20 bytes

Œsgùεø0©\vy`s®+*©]Zk

Demasiado tiempo..

0 indexado.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Œ                  # Get all sublists of the (implicit) input-list of stock-changes
 s                 # Swap to take the second (implicit) input-list of investments
  g                # And take its length
   ù               # Only leave sublists of that size
ε                  # Map each to:
 ø                 #  Create pairs with the second (implicit) input-list of investments
  0©               #  Store 0 in the register
    \              #  Discard the 0 from the stack
     vy            #  Loop `y` over the pairs
       `           #   Pop and push both values of the pair to the stack
        s          #   Swap them
         ®+        #   Add the value from the register to the investment amount
           *       #   And multiply it by the current number of the sublist
            ©      #   And then replace the value in the register with this
             ]     # Close both the loop and map
              Z    # Take the max of the mapped sublists (without popping the list)
               k   # Determine the index of that max (and output implicitly)
Kevin Cruijssen
fuente