Vela → pametna predmemorija za vremenske serije i više

U fintechu često moramo obraditi prilično velike količine podataka o valutnom tečaju. Podatke dobivamo iz različitih izvora, a svaki od njih ima svoju ideju o tome kako ekstrapolirati tečajeve za sutra, prekosutra, sljedeći mjesec pa čak i sljedeće tri godine. Kad bi samo netko mogao predvidjeti stope ispravno, bilo bi vrijeme da zatvorite posao i samo glupo mijenjate novac naprijed-natrag. Neki izvori su pouzdaniji, neki daju potpuno smeće, s rijetkim uključcima gotovo točnih vrijednosti, ali za egzotične parove. Naš je posao probrati te desetke tisuća vrijednosti u sekundi i odrediti što točno pokazati kupcima. Moramo filtrirati jednu ispravnu vrijednost iz tona prljavštine i mulja, baš kao što flamingosi rade za ručkom.

Vela → pametna predmemorija za vremenske serije i više

Posebno obilježje flaminga je njihov masivni prema dolje zakrivljeni kljun, kojim filtriraju hranu iz vode ili blata.
 - Vicki

Tako je nastala knjižnica Vela, koji pohranjuje predmemoriju stanja za više vrijednosti u određenim vremenskim intervalima. Ispod haube filtrira loše i zastarjele podatke u hodu, a također omogućuje pristup najnovijim N potvrđene vrijednosti za svaki ključ (valutni parovi, u našem slučaju).

Recimo da prikupljamo tečajeve za tri valutna para. Najjednostavnija definicija Vela za pohranjivanje trenutnog stanja izgledat će otprilike ovako:

defmodule Pairs do
  use Vela,
    eurusd: [sorter: &Kernel.<=/2],
    eurgbp: [limit: 3, errors: 1],
    eurcad: [validator: Pairs]

  @behaviour Vela.Validator

  @impl Vela.Validator
  def valid?(:eurcad, rate), do: rate > 0
end

Ažuriranje vrijednosti

Vela.put/3 Funkcija će učiniti sljedeće redom:

  • će uzrokovati validator na vrijednost, ako je definirana (vidi poglavlje Validacija ispod);
  • će dodati vrijednost ili u red dobrih vrijednosti ako je provjera valjanosti bila uspješna, ili u red usluge :__errors__ inače;
  • uzrokovat će sortiranje ako sorter definirano za dati ključ ili će jednostavno staviti vrijednost na početak popisa (LIFO, vidi poglavlje sortiranje ispod);
  • obrezat će red prema parametru :limit prešao na stvaranje;
  • vratit će ažuriranu strukturu Vela.

iex|1 > pairs = %Pairs{}
iex|2 > Vela.put(pairs, :eurcad, 1.0)
#⇒ %Pairs{..., eurcad: [1.0], ...}
iex|3 > Vela.put(pairs, :eurcad, -1.0)
#⇒ %Pairs{__errors__: [eurcad: -1.0], ...}
iex|4 > pairs |> Vela.put(:eurusd, 2.0) |> Vela.put(:eurusd, 1.0)
#⇒ %Pairs{... eurusd: [1.0, 2.0]}

Također Vela oruđa Access, tako da možete koristiti bilo koju od standardnih funkcija za duboko ažuriranje struktura iz arsenala za ažuriranje vrijednosti Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2i Kernel.get_and_update_in/3.

Validacija

Validator se može definirati kao:

  • vanjska funkcija s jednim argumentom (&MyMod.my_fun/1), dobit će samo vrijednost za provjeru valjanosti;
  • vanjska funkcija s dva argumenta, &MyMod.my_fun/2, dobit će par serie, value za validaciju;
  • implementacija modula Vela.Validator;
  • konfiguracijski parametar threshold, i - izborno - compare_by, vidi poglavlje usporedba u nastavku.

Ako je provjera valjanosti uspješna, vrijednost se dodaje na popis pod odgovarajućim ključem; u suprotnom, tuple {serie, value} Ide na :__errors_.

usporedba

Vrijednosti pohranjene u ovim redovima mogu biti bilo što. Naučiti Vela za njihovu usporedbu potrebno je prenijeti compare_by parametar u definiciji serije (osim ako se vrijednosti ne mogu usporediti sa standardom Kernel.</2); ovaj parametar mora biti tipa (Vela.value() -> number()). Standardno je jednostavno & &1.

Također, možete proslijediti parametar definiciji reda comparator za izračunavanje delta vrijednosti (min/max); primjerice odašiljanjem Date.diff/2 kao komparator, možete dobiti točne delte za datume.

Još jedan prikladan način rada je prosljeđivanje parametra threshold, koji definira najveći dopušteni omjer nove vrijednosti prema {min, max} interval. Budući da je naveden kao postotak, ček se ne koristi comparatorali i dalje koristi compare_by. Na primjer, da biste odredili vrijednost praga za vrijeme datuma, morate navesti compare_by: &DateTime.to_unix/1 (da dobijete cjelobrojnu vrijednost) i threshold: 1, zbog čega su nove vrijednosti dopuštene samo ako su unutar ±band interval od trenutnih vrijednosti.

Konačno, možete koristiti Vela.equal?/2 za usporedbu dvaju predmemorija. Ako vrijednosti definiraju funkciju equal?/2 ili compare/2, tada će se te funkcije koristiti za usporedbu, inače ćemo glupo koristiti ==/2.

Dobivanje vrijednosti

Obrada trenutnog stanja obično počinje pozivom Vela.purge/1, koji uklanja zastarjele vrijednosti (ako validator vezan za timestamps). Tada možete nazvati Vela.slice/1koji će se vratiti keyword s imenima redaka kao ključevima i prvim, stvarnim vrijednostima.

Također možete koristiti get_in/2/pop_in/2 za pristup niske razine vrijednostima u svakom retku.

primjena

Vela može biti iznimno koristan kao predmemorija vremenske serije u stanju procesa kao što je GenServer/Agent. Ne želimo nikada koristiti zastarjele vrijednosti tečaja, a da bismo to učinili, jednostavno održavamo proces s obrađenim stanjem Vela, s validatorom prikazanim u nastavku.

@impl Vela.Validator
def valid?(_key, %Rate{} = rate),
  do: Rate.age(rate) < @death_age

и Vela.purge/1 tiho uklanja sve zastarjele vrijednosti svaki put kada su nam potrebni podaci. Za pristup stvarnim vrijednostima jednostavno pozivamo Vela.slice/1, a kada je potrebna mala povijest tečaja (cijele serije), jednostavno je vraćamo - već sortiranu - s potvrđenim vrijednostima.

Sretno predmemoriranje vremenskih serija!

Izvor: www.habr.com

Dodajte komentar