Um vetor é uma lista de números com regras
Um vetor é uma lista ordenada de números de comprimento fixo, como os pesos de uma carteira [0.5, 0.3, 0.2] ou os retornos de um dia de três ativos [0.02, -0.01, 0.03]. Em Python, uma lista de floats serve. Vetores podem ser somados, escalados e combinados posição a posição, por isso grande parte das finanças quantitativas é escrita na linguagem deles. Dois vetores só podem ser combinados se tiverem o mesmo comprimento; misturar comprimentos é um bug que você quer notar com clareza.
weights = [0.5, 0.3, 0.2]
returns = [0.02, -0.01, 0.03]
# Position by position: zip pairs the elements
products = [w * r for w, r in zip(weights, returns)]
print([round(p, 4) for p in products]) # [0.01, -0.003, 0.006]
# Scaling and adding vectors
print([2 * w for w in weights]) # [1.0, 0.6, 0.4]
print([a + b for a, b in zip(weights, returns)]) # [0.52, 0.29, 0.23]O produto escalar
O produto escalar multiplica dois vetores posição a posição e soma os resultados: a1*b1 + a2*b2 + ... + an*bn. Devolve um único número. É o retorno da carteira quando a tem os pesos e b os retornos: 0.5*0.02 + 0.3*(-0.01) + 0.2*0.03 = 0.013. É também o valor de uma lista de posições (quantidades vezes preços) e o bloco básico de uma regressão. Em Python: sum(x * y for x, y in zip(a, b)), depois de checar que len(a) == len(b), pois zip para em silêncio na lista mais curta.
def dot(a, b):
if len(a) != len(b):
raise ValueError("vectors must have the same length")
return sum(x * y for x, y in zip(a, b))
print(dot([1, 2, 3], [4, 5, 6])) # 32
print(round(dot([0.5, 0.3, 0.2], [0.02, -0.01, 0.03]), 6)) # 0.013 (portfolio return)
try:
dot([1, 2], [1, 2, 3])
except ValueError as error:
print(error) # vectors must have the same lengthComprimento, direção e similaridade
Um vetor multiplicado escalarmente por si mesmo dá seu comprimento ao quadrado, então a norma (comprimento) é math.sqrt(dot(a, a)): para [3, 4] é 5.0. Dividir um vetor por sua norma dá um vetor unitário de comprimento 1 que mantém só a direção (mas um vetor nulo não tem direção, recuse-o com ValueError). A similaridade do cosseno dot(a, b) / (norm(a) * norm(b)) mede o alinhamento de dois vetores, de -1 (opostos) passando por 0 (sem relação, em ângulo reto) até 1 (mesma direção, qualquer que seja a escala). Aplicada a séries de retornos centradas, é a correlação, uma grandeza central do risco de carteira.
import math
def dot(a, b):
return sum(x * y for x, y in zip(a, b))
def norm(a):
return math.sqrt(dot(a, a))
print(norm([3, 4])) # 5.0
def normalize(a):
length = norm(a)
if length == 0:
raise ValueError("a zero vector has no direction")
return [x / length for x in a]
print(normalize([3, 4])) # [0.6, 0.8]
def cosine_similarity(a, b):
return dot(a, b) / (norm(a) * norm(b))
print(round(cosine_similarity([1, 2], [2, 4]), 6)) # 1.0 (same direction)
print(cosine_similarity([1, 0], [0, 1])) # 0.0 (perpendicular)
print(round(cosine_similarity([1, 2], [-1, -2]), 6)) # -1.0 (opposite)import math
def dot(a, b):
return sum(x * y for x, y in zip(a, b))
def mean(values):
return sum(values) / len(values)
# Correlation is the cosine of the demeaned series
a = [0.01, 0.02, -0.01, 0.03]
b = [0.02, 0.04, -0.02, 0.06] # always twice a
da = [x - mean(a) for x in a]
db = [x - mean(b) for x in b]
corr = dot(da, db) / math.sqrt(dot(da, da) * dot(db, db))
print(round(corr, 6)) # 1.0
# Value of a book: quantities dot prices
quantities = [100, -50, 20]
prices = [184.0, 410.0, 171.0]
print(dot(quantities, prices)) # 1320.0zip, ou você perderá dados em silêncio. E nunca teste resultados float com ==: o cosseno de duas direções idênticas pode sair 0.9999999999999999. Compare com math.isclose(...), como fazem os testes do lab. Na prática você logo usará o NumPy, cujos np.dot e np.linalg.norm fazem tudo isso rápido; saber o que calculam permite conferi-los.- Produto escalar: multiplique posição a posição e some; confira antes os comprimentos.
- Norma
sqrt(dot(a, a)); vetor unitárioa / norm(a)(recuse o vetor nulo). - Similaridade do cosseno
dot(a, b) / (norm(a) * norm(b))de -1 a 1; compare floats comisclose.
A seguir: matrizes e sistemas lineares, tabelas de números que agem sobre vetores e resolvem muitas equações de uma vez.
Lab: o que é avaliado
- Combinar pesos e retornos com
dot25 pts - Medir o comprimento de um vetor com
norm25 pts - Comparar direções com
cosine_similarity25 pts - Levar um vetor ao comprimento 1 com
normalize25 pts