1 votos

Almacenamiento de series temporales de opciones EOD en ficheros planos

He comprado datos para liquidaciones EOD de precios de opciones para futuros USA para uso personal. No necesito acceso de múltiples usuarios ni acceso en tiempo real. No soy un programador experto pero uso C# y R con bastante regularidad. Cada futuro (digamos SPX) tendrá varias "cadenas" de opciones cada día. Si una sola fecha de la serie temporal fuera el 25 de mayo de 2016, podríamos tener 3 cadenas cotizando . Por ejemplo, SPM16 (vencimiento de junio), SPU16 (septiembre), SPZ16 (diciembre) Cada cadena constará de muchos precios de ejercicio asociados. Digamos 50 precios de ejercicio por cadena (yo los llamo StrikeRecords). Cada precio de ejercicio tendrá una opción de compra y de venta asociada. A estos registros individuales de compra y venta los llamo SettlementRecords.

Iba a intentar utilizar un método de sistema de archivos que drobertson había sugerido en este hilo:

Creación desde cero de una base de datos de series temporales de datos financieros

Me ha parecido muy útil, ya que no estoy demasiado familiarizado con las bases de datos y creo que acabaré dedicando más tiempo a aprender PostgreSQL que a estudiar los datos.

Mencionó una estructura de archivos para datos de acciones EOD algo en el espacio de futuros que podría parecerse a esto:

\FutureEOD {YYYY}{Inicial}_symbol.json

Los datos del SPX para 2016 serían

\FutureEOD\2016\S_SPX.json

Algo como esta estructura de sistema de archivos podría funcionar, pero tendría muchas opciones de símbolos / huelgas contenidas dentro de este único archivo 2016 para SPX.

Me preguntaba si este sistema de archivos sería mejor sin /{YYYY} y dividido en símbolos de opciones. Un archivo separado para cada cadena ordenados por liquidación DateTime? Algo así como

\FutureEOD\S\SPX_SPM16.csv

\FutureEOD\S\SPX_SPU16.csv

\FutureEOD\S\SPX_SPZ16.csv

Cada uno de estos archivos contendría todas las huelgas de cada cadena durante todos los días de existencia del contrato (~2 años). Yo iba a utilizar un SortedList para manejar los datos en la memoria y para obtener ordenados de nuevo en el TimeSeries ordenados.

¿Voy por mal camino?

Además, ¿tiene sentido tratar de almacenar en archivos planos como CSV en lugar de JSON? ¿Alguna otra estructura de archivos mejor para la velocidad de lectura con C#?

¿Alguien ha intentado almacenar los datos de las opciones EOD en el sistema de archivos? Cualquier consejo es muy apreciado.

Gracias

1voto

Craigy Puntos 111

Base de datos de series temporales Axibase es una alternativa no relacional con un esquema integrado para datos de tick, EOD y de referencia. La consulta de estadísticas en ATSD por criterios comunes, como símbolo, intervalo de fechas, precio de ejercicio, etc., debería ser mucho más rápida que la lectura de los ficheros de entrada, ya que el orden de los registros en los ficheros no está garantizado y, por lo general, es necesario leer todo el fichero para comprobar la coincidencia de todos los registros.

ATSD es gratuito para la producción en un solo nodo.

Utilización del CBOE EOD como ejemplo:

underlying_symbol,quote_date,root,expiration,strike,option_type,open,high,low,close,trade_volume,bid_size_1545,bid_1545,ask_size_1545,ask_1545,underlying_bid_1545,underlying_ask_1545,bid_size_eod,bid_eod,ask_size_eod,ask_eod,underlying_bid_eod,underlying_ask_eod,vwap,open_interest,delivery_code
^VIX,2016-06-01,VIX,2016-11-16,65.000,P,0.0000,0.0000,0.0000,0.0000,0,6003,45.1000,7831,45.4000,14.2400,14.2400,572,45.1000,3340,45.3000,14.2000,14.2000,0.0000,0,

Ejecutar un script python para analizar y cargar las estadísticas EOD en atsd_session_summary mesa:

import csv
from dateutil.parser import parse
from decimal import Decimal
from atsd_client import connect
from dateutil.tz import gettz

def to_option_symbol(root_symbol, expiration_date, option_type, strike):
    nd = expiration_date.replace("-", "")
    return root_symbol + nd + option_type + "{:09.3f}".format(Decimal(strike)).replace(".", "")

def norm(d):
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

def to_summary(row, columns):
    dt = parse(row['quote_date'] + ' 16:00:00 ET', tzinfos={"ET": gettz("US/Eastern")})
    res = 'CBOE,XCBO,' + to_option_symbol(row['root'], row['expiration'], row['option_type'], row['strike'])
    res += ',' + dt.isoformat()
    res += ',Day,C'
    for c in columns:
        res += ',' + str(norm(Decimal(row[c])))
    return res

fields_eod =  ['open', 'high', 'low', 'close', 'trade_volume', 
    'bid_size_1545', 'bid_1545', 'ask_size_1545', 'ask_1545', 'underlying_bid_1545', 'underlying_ask_1545', 
    'bid_size_eod', 'bid_eod', 'ask_size_eod', 'ask_eod', 'underlying_bid_eod', 'underlying_ask_eod', 'vwap', 'open_interest']
fields_sum =  ['open', 'high', 'low', 'closeprice', 'voltoday', 
    'custom_num_01', 'custom_num_02', 'custom_num_03', 'custom_num_04', 'custom_num_05', 'custom_num_06',
    'biddepth', 'bid', 'offerdepth', 'offer', 'underlying_bid', 'underlying_offer', 'vwap', 'numcontracts']

lines = set()
file = 'UnderlyingOptionsEODQuotes_2016-06-01.csv'
csvfile = open(file, 'r')
reader = csv.DictReader(csvfile, delimiter=',')
for row in reader:
    lines.add(to_summary(row, fields_eod))

hdr = "exchange,class,symbol,datetime,type,stage"
for h in fields_sum:
    hdr += ',' + h

conn = connect('./connection.properties')
conn.post_plain_text('/api/v1/trade-session-summary/import?add_new_instruments=true', hdr + "\n" + "\n".join(lines))

Una vez que los registros están en la base de datos, puede consultar las estadísticas con SQL:

SELECT exchange, class, symbol, datetime, open, high, low, closeprice AS close, voltoday AS trade_volume,
  bid, biddepth, offer, offerdepth, underlying_bid, underlying_offer, vwap, numcontracts AS opencontracts,
  custom_num_01 AS bid_size_1545, custom_num_02 AS bid_1545, custom_num_03 AS offer_size_1545, custom_num_04 AS offer_1545,
  CAST(CONCAT(SUBSTR(symbol, LENGTH(symbol)-7, 5), '.', SUBSTR(symbol, LENGTH(symbol)-2, 3))AS number) AS strike
FROM atsd_session_summary WHERE symbol LIKE 'VIX%'
  AND datetime BETWEEN '2016-06-01' AND '2016-06-02'
  AND strike BETWEEN underlying_bid*1.00 AND underlying_offer*1.05
ORDER BY entity.tags.symbol, datetime

Query results CBOE option end-of-day data

Ayuda a almacenar también en la base de datos datos datos de referencia como precios de ejercicio, fechas de vencimiento, símbolos subyacentes y root, ISIN, CUSIP, CIK, etc., para poder filtrar las estadísticas utilizando campos de referencia cercanos a los datos, lo que acelera la recuperación de datos.

  WHERE CAST(entity.tags.strike AS number) BETWEEN 10 and 15

(Descargo de responsabilidad: trabajo para Axibase)

0voto

BigCanOfTuna Puntos 210

Lo que le convenga dependerá mucho de sus necesidades, como la rapidez que debe tener el db, y el tipo de su análisis, por ejemplo, si le importa más la sección transversal o las series temporales.

Almaceno regularmente los precios de las opciones EOD en archivos CSV (un archivo por serie temporal de opciones), y luego los agrego según necesario. Para ello he escrito un pequeño paquete en R ( https://github.com/enricoschumann/tsdb ). Si quieres probarlo y la velocidad es un problema, hay un script de prueba en https://github.com/enricoschumann/tsdb/blob/master/inst/tests/write_read.R .

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X