āĻŦāĻŋāώāϝāĻŧāĻŦāϏā§āϤ⧠āϏā§āĻāĻŋ
āĻĒāĻžāϰā§āĻ II: āĻāĻā§āύā§āĻ āĻāĻŦāĻ āĻĻāϞ
āĻāĻŽāϰāĻž āĻāĻāĻžāύ⧠āĻāĻŋ āĻāϰāĻāĻŋ?
āϏā§āϤāϰāĻžāĻ, āϤāĻžāĻ, āĻĻā§āĻŦāĻŋāϤā§āϝāĻŧ āĻ āĻāĻļ. āϝā§āĻŽāύāĻāĻŋ āĻāĻā§ āϞā§āĻāĻž āĻšāϝāĻŧā§āĻā§, āĻāϤ⧠āĻāĻŽāϰāĻž āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤāĻā§āϞāĻŋ āĻāϰāĻŦ:
āĻāĻŽāĻžāĻĻā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύā§āϝāĻŧ āĻļā§āώ āĻĒāϝāĻŧā§āύā§āĻāĻā§āϞāĻŋāϰ āĻāύā§āϝ āĻ āύā§āϰā§āϧ āϏāĻš aiohttp-āĻ alphavantage-āĻāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āϞāĻŋāĻāĻŋāĨ¤
āĻāϏā§āύ āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻ āϤā§āϰāĻŋ āĻāϰāĻŋ āϝāĻžāϰāĻž āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻ āĻāĻŦāĻ āϤāĻžāĻĻā§āϰ āĻāĻĒāϰ āĻŽā§āĻāĻž āϤāĻĨā§āϝ āϏāĻāĻā§āϰāĻš āĻāϰāĻŦā§āĨ¤
āĻāĻŋāύā§āϤā§, āĻāĻŽāϰāĻž āĻāĻ āĻĒā§āϰāĻāϞā§āĻĒā§āϰ āĻāύā§āϝāĻ āĻāĻāĻŋ āĻāϰāĻŦ, āĻāĻŦāĻ āĻĢāĻžāϏā§āĻ āĻāĻŦā§āώāĻŖāĻžāϰ āĻĒāϰāĻŋāĻĒā§āϰā§āĻā§āώāĻŋāϤā§, āĻāĻŽāϰāĻž āĻļāĻŋāĻāĻŦ āĻā§āĻāĻžāĻŦā§ āĻāĻā§āύā§āĻ āϞāĻŋāĻāϤ⧠āĻšāϝāĻŧ āϝāĻž āĻāĻžāĻĢāĻāĻž āĻĨā§āĻā§ āĻāĻā§āύā§āĻāĻā§āϞāĻŋ āĻĒā§āϰāϏā§āϏ āĻāϰā§, āϏā§āĻāϏāĻžāĻĨā§ āĻā§āĻāĻžāĻŦā§ āĻāĻŽāĻžāύā§āĻĄ āϞāĻŋāĻāϤ⧠āĻšāϝāĻŧ (āĻā§āϞāĻŋāĻ āϰā§āϝāĻžāĻĒāĻžāϰ), āĻāĻŽāĻžāĻĻā§āϰ āĻā§āώā§āϤā§āϰ⧠- āĻāĻā§āύā§āĻ āϝ⧠āĻŦāĻŋāώāϝāĻŧā§ āύāĻāϰāĻĻāĻžāϰāĻŋ āĻāϰāĻā§ āϏā§āĻ āĻŦāĻŋāώāϝāĻŧā§ āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞ āĻĒā§āĻļ āĻŦāĻžāϰā§āϤāĻžāϰ āĻāύā§āϝāĨ¤
āĻĒā§āϰāĻļāĻŋāĻā§āώāĻŖ
āĻāϞāĻĢāĻžāĻā§āϝāĻžāύā§āĻā§āĻ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ
āĻĒā§āϰāĻĨāĻŽā§, āĻ ā§āϝāĻžāϞāĻĢāĻžāĻāĻžāύā§āĻā§āĻā§āϰ āĻ āύā§āϰā§āϧā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻā§āĻ aiohttp āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āϞāĻŋāĻāĻŋāĨ¤
āĻāĻā§āώāĻ
import urllib.parse as urlparse
from io import StringIO
from typing import Any, Dict, List, Union
import aiohttp
import pandas as pd
import stringcase
from loguru import logger
from horton.config import API_ENDPOINT
class AlphaVantageClient:
def __init__(
self,
session: aiohttp.ClientSession,
api_key: str,
api_endpoint: str = API_ENDPOINT,
):
self._query_params = {"datatype": "json", "apikey": api_key}
self._api_endpoint = api_endpoint
self._session = session
@logger.catch
def _format_fields(self, data: Dict[str, Any]) -> Dict[str, Any]:
formatted_data = {}
for field, item in data.items():
formatted_data[stringcase.snakecase(field)] = item
return formatted_data
@logger.catch
async def _construct_query(
self, function: str, to_json: bool = True, **kwargs
) -> Union[Dict[str, Any], str]:
path = "query/"
async with self._session.get(
urlparse.urljoin(self._api_endpoint, path),
params={"function": function, **kwargs, **self._query_params},
) as response:
data = (await response.json()) if to_json else (await response.text())
if to_json:
data = self._format_fields(data)
return data
@logger.catch
async def get_securities(self, state: str = "active") -> List[Dict[str, str]]:
data = await self._construct_query("LISTING_STATUS", state=state, to_json=False)
data = pd.read_csv(StringIO(data))
securities = data.to_dict("records")
for index, security in enumerate(securities):
security = self._format_fields(security)
security["_type"] = "physical"
securities[index] = security
return securities
@logger.catch
async def get_security_overview(self, symbol: str) -> Dict[str, str]:
return await self._construct_query("OVERVIEW", symbol=symbol)
@logger.catch
async def get_historical_data(self, symbol: str) -> Dict[str, Any]:
return await self._construct_query(
"TIME_SERIES_DAILY_ADJUSTED", symbol=symbol, outputsize="full"
)
@logger.catch
async def get_last_price_data(self, symbol: str) -> Dict[str, Any]:
return await self._construct_query("GLOBAL_QUOTE", symbol=symbol)
@logger.catch
async def get_indicator_data(
self, symbol: str, indicator: str, **indicator_options
) -> Dict[str, Any]:
return await self._construct_query(
indicator, symbol=symbol, **indicator_options
)
āĻĒā§āϰāĻā§āϤāĻĒāĻā§āώā§, āĻāĻāĻŋ āĻĨā§āĻā§ āϏāĻŦāĻāĻŋāĻā§ āĻĒāϰāĻŋāώā§āĻāĻžāϰ:
AlphaVantage API āĻŦā§āĻļ āϏāĻšāĻ āĻāĻŦāĻ āϏā§āύā§āĻĻāϰāĻāĻžāĻŦā§ āĻĄāĻŋāĻāĻžāĻāύ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, āϤāĻžāĻ āĻāĻŽāĻŋ āĻĒāĻĻā§āϧāϤāĻŋāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āϏāĻŽāϏā§āϤ āĻ āύā§āϰā§āϧ āĻāϰāĻžāϰ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āύāĻŋāϝāĻŧā§āĻāĻŋ
construct_queryāϝā§āĻāĻžāύ⧠āĻā§āϰ⧠āĻāĻāĻāĻŋ http āĻāϞ āĻāĻā§āĨ¤āĻāĻŽāĻŋ āϏāĻŦ āĻā§āώā§āϤā§āϰ āĻāύāĻž
snake_caseāĻāϰāĻžāĻŽā§āϰ āĻāύā§āϝāĻāĻžāϞ, āϏā§āύā§āĻĻāϰ āĻāĻŦāĻ āϤāĻĨā§āϝāĻĒā§āϰā§āĻŖ āĻā§āϰā§āϏāĻŦā§āϝāĻžāĻ āĻāĻāĻāĻĒā§āĻ āĻāύā§āϝ logger.catch āϏāĻā§āĻāĻž.
PS config.yml-āĻ āϏā§āĻĨāĻžāύā§āϝāĻŧāĻāĻžāĻŦā§ alphavantage āĻā§āĻā§āύ āϝā§āĻ āĻāϰāϤ⧠āĻā§āϞāĻŦā§āύ āύāĻž, āĻ
āĻĨāĻŦāĻž āĻāύāĻāĻžāϝāĻŧāϰāύāĻŽā§āύā§āĻ āĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞ āĻāĻā§āϏāĻĒā§āϰā§āĻ āĻāϰāϤ⧠āĻā§āϞāĻŦā§āύ āύāĻž HORTON_SERVICE_APIKEY. āĻāĻŽāϰāĻž āĻāĻāĻāĻŋ āĻā§āĻā§āύ āĻā§āϰāĻšāĻŖ āĻāϰāĻŋ .
CRUD āĻā§āϞāĻžāϏ
āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻŽā§āĻāĻž āϤāĻĨā§āϝ āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻāĻāĻŋ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻ āϏāĻāĻā§āϰāĻš āĻĨāĻžāĻāĻŦā§āĨ¤
āĻāĻŽāĻžāϰ āĻŽāϤā§, āĻāĻāĻžāύ⧠āĻāĻŋāĻā§ āĻŦā§āϝāĻžāĻā§āϝāĻž āĻāϰāĻžāϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āύā§āĻ, āĻāĻŦāĻ āĻŦā§āϏ āĻā§āϞāĻžāϏ āύāĻŋāĻā§āĻ āĻŦā§āĻļ āϏāĻšāĻāĨ¤
āĻ ā§āϝāĻžāĻĒ āĻāĻŋ āύāĻŋāύ()
āĻāĻāĻāĻŋ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻŦāϏā§āϤ⧠āϤā§āϰāĻŋ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻĢāĻžāĻāĻļāύ āϝā§āĻ āĻāϰāĻž āϝāĻžāĻ
āĻāĻā§āώāĻ
import faust
from horton.config import KAFKA_BROKERS
def get_app():
return faust.App("horton", broker=KAFKA_BROKERS)
āĻāĻĒāĻžāϤāϤ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻžāĻā§ āϏāĻšāĻāϤāĻŽ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āϤā§āϰāĻŋ āĻšāĻŦā§, āĻāĻāĻā§ āĻĒāϰ⧠āĻāĻŽāϰāĻž āĻāĻāĻŋāĻā§ āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻāϰāĻŦ, āϤāĻŦā§, āĻāĻĒāύāĻžāĻā§ āĻ āĻĒā§āĻā§āώāĻž āύāĻž āĻāϰāĻžāϰ āĻāύā§āϝ, āĻāĻāĻžāύ⧠āĻ ā§āϝāĻžāĻĒ-āĻā§āϞāĻžāϏā§āĨ¤ āĻāĻŽāĻŋ āĻāĻĒāύāĻžāĻā§ āϏā§āĻāĻŋāĻāϏ āĻā§āϞāĻžāϏāĻāĻŋ āĻāĻāĻŦāĻžāϰ āĻĻā§āĻāĻžāϰ āĻĒāϰāĻžāĻŽāϰā§āĻļ āĻĻāĻŋāĻā§āĻāĻŋ, āϝā§āĻšā§āϤ⧠āĻāĻāĻŋ āĻŦā§āĻļāĻŋāϰāĻāĻžāĻ āϏā§āĻāĻŋāĻāϏā§āϰ āĻāύā§āϝ āĻĻāĻžāϝāĻŧā§āĨ¤
āĻĒā§āϰāϧāĻžāύ āĻ āĻāĻļ
āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻā§āϰ āϤāĻžāϞāĻŋāĻāĻž āϏāĻāĻā§āϰāĻš āĻ āϰāĻā§āώāĻŖāĻžāĻŦā§āĻā§āώāĻŖā§āϰ āĻāύā§āϝ āĻāĻā§āύā§āĻ
app = get_app()
collect_securities_topic = app.topic("collect_securities", internal=True)
@app.agent(collect_securities_topic)
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
passāϏā§āϤāϰāĻžāĻ, āĻĒā§āϰāĻĨāĻŽā§ āĻāĻŽāϰāĻž āĻĢāĻžāϏā§āĻ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻ āĻŦāĻā§āĻā§āĻāĻāĻŋ āĻĒāĻžāĻ - āĻāĻāĻŋ āĻŦā§āĻļ āϏāĻšāĻāĨ¤ āĻāϰ āĻĒāϰā§, āĻāĻŽāϰāĻž āϏā§āĻĒāώā§āĻāĻāĻžāĻŦā§ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻā§āύā§āĻā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻŦāĻŋāώāϝāĻŧ āĻā§āώāĻŖāĻž āĻāϰāĻŋ... āĻāĻāĻžāύ⧠āĻāĻāĻŋ āĻā§, āĻ āĻā§āϝāύā§āϤāϰā§āĻŖ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ āĻā§ āĻāĻŦāĻ āĻāĻāĻŋāĻā§ āĻā§āĻāĻžāĻŦā§ āĻāϞāĻžāĻĻāĻžāĻāĻžāĻŦā§ āϏāĻžāĻāĻžāύ⧠āϝā§āϤ⧠āĻĒāĻžāϰ⧠āϤāĻž āĻāϞā§āϞā§āĻ āĻāϰāĻžāϰ āĻŽāϤā§āĨ¤
āĻāĻžāĻĢāĻāĻžāϰ āĻāĻĒāĻŋāĻāϏ, āϝāĻĻāĻŋ āĻāĻŽāϰāĻž āϏāĻ āĻŋāĻ āϏāĻāĻā§āĻāĻž āĻāĻžāύāϤ⧠āĻāĻžāĻ, āϤāĻžāĻšāϞ⧠āĻĒāĻĄāĻŧāĻž āĻāĻžāϞ⧠, āĻ āĻĨāĻŦāĻž āĻāĻĒāύāĻŋ āĻĒāĻĄāĻŧāϤ⧠āĻĒāĻžāϰā§āύ āϰāĻžāĻļāĻŋāϝāĻŧāĻžāύ āĻāĻžāώāĻžāϝāĻŧ āĻšāĻžāĻŦā§āϰā§āϤā§, āϝā§āĻāĻžāύ⧠āϏāĻŦāĻāĻŋāĻā§ āĻŦā§āĻļ āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āĻĒā§āϰāϤāĻŋāĻĢāϞāĻŋāϤ āĻšāϝāĻŧ :)
, faust āĻĄāĻ-āĻ āĻŦā§āĻļ āĻāĻžāϞāĻāĻžāĻŦā§ āĻŦāϰā§āĻŖāύāĻž āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, āĻāĻŽāĻžāĻĻā§āϰāĻā§ āĻā§āĻĄā§ āϏāϰāĻžāϏāϰāĻŋ āĻŦāĻŋāώāϝāĻŧ āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰāϤ⧠āĻĻā§āϝāĻŧ, āĻ āĻŦāĻļā§āϝāĻ, āĻāϰ āĻ āϰā§āĻĨ āĻĢāĻžāϏā§āĻ āĻĄā§āĻā§āϞāĻĒāĻžāϰāĻĻā§āϰ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāĻĻāϤā§āϤ āĻĒāϰāĻžāĻŽāĻŋāϤāĻŋāĻā§āϞāĻŋ, āĻāĻĻāĻžāĻšāϰāĻŖāϏā§āĻŦāϰā§āĻĒ: āϧāĻžāϰāĻŖ, āϧāĻžāϰāĻŖ āύā§āϤāĻŋ (āĻĄāĻŋāĻĢāϞā§āĻāϰā§āĻĒā§ āĻŽā§āĻā§ āĻĢā§āϞā§āύ, āϤāĻŦā§ āĻāĻĒāύāĻŋ āϏā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ ), āĻŦāĻŋāώāϝāĻŧ āĻĒā§āϰāϤāĻŋ āĻĒāĻžāϰā§āĻāĻŋāĻļāύā§āϰ āϏāĻāĻā§āϝāĻž (āĻāϰāϤā§, āĻāĻĻāĻžāĻšāϰāĻŖāϏā§āĻŦāϰā§āĻĒ, āĻāϰ āĻā§āϝāĻŧā§ āĻāĻŽ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻĢāĻžāϏā§āĻ)āĨ¤
āϏāĻžāϧāĻžāϰāĻŖāĻāĻžāĻŦā§, āĻāĻā§āύā§āĻ āĻŦāĻŋāĻļā§āĻŦāĻŦā§āϝāĻžāĻĒā§ āĻŽāĻžāύ āϏāĻš āĻāĻāĻāĻŋ āĻĒāϰāĻŋāĻāĻžāϞāĻŋāϤ āĻŦāĻŋāώāϝāĻŧ āϤā§āϰāĻŋ āĻāϰāϤ⧠āĻĒāĻžāϰā§, āϤāĻŦā§, āĻāĻŽāĻŋ āϏā§āĻĒāώā§āĻāĻāĻžāĻŦā§ āϏāĻŦāĻāĻŋāĻā§ āĻā§āώāĻŖāĻž āĻāϰāϤ⧠āĻāĻžāĻāĨ¤ āĻāĻĒāϰāύā§āϤā§, āĻāĻā§āύā§āĻ āĻŦāĻŋāĻā§āĻāĻžāĻĒāύ⧠āĻŦāĻŋāώāϝāĻŧā§āϰ āĻāĻŋāĻā§ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ (āĻāĻĻāĻžāĻšāϰāĻŖāϏā§āĻŦāϰā§āĻĒ, āĻĒāĻžāϰā§āĻāĻŋāĻļāύā§āϰ āϏāĻāĻā§āϝāĻž āĻŦāĻž āϧāϰ⧠āϰāĻžāĻāĻžāϰ āύā§āϤāĻŋ) āĻāύāĻĢāĻŋāĻāĻžāϰ āĻāϰāĻž āϝāĻžāĻŦā§ āύāĻžāĨ¤
āĻŽā§āϝāĻžāύā§āϝāĻŧāĻžāϞāĻŋ āĻŦāĻŋāώāϝāĻŧāĻāĻŋ āϏāĻāĻā§āĻāĻžāϝāĻŧāĻŋāϤ āύāĻž āĻāϰ⧠āĻāĻāĻŋ āĻĻā§āĻāϤ⧠āĻā§āĻŽāύ āĻšāϤ⧠āĻĒāĻžāϰ⧠āϤāĻž āĻāĻāĻžāύā§:
app = get_app()
@app.agent()
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
passāĻāĻā§āĻāĻž, āĻāĻāύ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻā§āύā§āĻ āĻā§ āĻāϰāĻŦā§ āϤāĻž āĻŦāϰā§āĻŖāύāĻž āĻāϰāĻŋ :)
app = get_app()
collect_securities_topic = app.topic("collect_securities", internal=True)
@app.agent(collect_securities_topic)
async def collect_securities(stream: StreamT[None]) -> AsyncIterable[bool]:
async with aiohttp.ClientSession() as session:
async for _ in stream:
logger.info("Start collect securities")
client = AlphaVantageClient(session, API_KEY)
securities = await client.get_securities()
for security in securities:
await SecurityCRUD.update_one(
{"symbol": security["symbol"], "exchange": security["exchange"]}, security, upsert=True
)
yield True
āϏā§āϤāϰāĻžāĻ, āĻāĻā§āύā§āĻā§āϰ āĻļā§āϰā§āϤā§, āĻāĻŽāϰāĻž āĻāĻŽāĻžāĻĻā§āϰ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻ āύā§āϰā§āϧā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ aiohttp āϏā§āĻļāύ āĻā§āϞāĻŋāĨ¤ āĻāĻāĻāĻžāĻŦā§, āĻāĻāĻāύ āĻāϰā§āĻŽā§ āĻļā§āϰ⧠āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ, āϝāĻāύ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻā§āύā§āĻ āĻāĻžāϞ⧠āĻāϰāĻž āĻšāϝāĻŧ, āϤāĻāύāĻ āĻāĻāĻāĻŋ āϏā§āĻļāύ āĻā§āϞāĻž āĻšāĻŦā§ - āĻāĻ, āĻĒā§āϰ⧠āϏāĻŽāϝāĻŧ āĻāϰā§āĻŽā§ āĻāϞāĻā§ (āĻ āĻĨāĻŦāĻž āĻāĻāĻžāϧāĻŋāĻ, āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§āύ) āĻāĻāĻāĻŋ āĻĄāĻŋāĻĢāϞā§āĻ āĻāĻāύāĻŋāĻ āϏāĻš āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻ āĻĨā§āĻā§)āĨ¤
āĻāϰāĻĒāϰā§, āĻāĻŽāϰāĻž āϏā§āĻā§āϰā§āĻŽ āĻ
āύā§āϏāϰāĻŖ āĻāϰāĻŋ (āĻāĻŽāϰāĻž āĻŦāĻžāϰā§āϤāĻžāĻāĻŋ āϰāĻžāĻāĻŋ _, āϝā§āĻšā§āϤ⧠āĻāĻŽāϰāĻž, āĻāĻ āĻāĻā§āύā§āĻā§, āĻāĻŽāĻžāĻĻā§āϰ āĻŦāĻŋāώāϝāĻŧ āĻĨā§āĻā§ āĻŦāĻžāϰā§āϤāĻžāĻā§āϞāĻŋāϰ āĻŦāĻŋāώāϝāĻŧāĻŦāϏā§āϤ⧠āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāĻŋāύā§āϤāĻž āĻāϰāĻŋ āύāĻž, āϝāĻĻāĻŋ āϏā§āĻā§āϞāĻŋ āĻŦāϰā§āϤāĻŽāĻžāύ āĻ
āĻĢāϏā§āĻā§ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĨāĻžāĻā§, āĻ
āύā§āϝāĻĨāĻžāϝāĻŧ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻā§āϰ āϤāĻžāĻĻā§āϰ āĻāĻāĻŽāύā§āϰ āĻāύā§āϝ āĻ
āĻĒā§āĻā§āώāĻž āĻāϰāĻŦā§āĨ¤ āĻ āĻŋāĻ āĻāĻā§, āĻāĻŽāĻžāĻĻā§āϰ āϞā§āĻĒā§āϰ āĻāĻŋāϤāϰā§, āĻāĻŽāϰāĻž āĻŦāĻžāϰā§āϤāĻžāϰ āϰāϏāĻŋāĻĻ āϞāĻ āĻāϰāĻŋ, āϏāĻā§āϰāĻŋāϝāĻŧā§āϰ āĻāĻāĻāĻŋ āϤāĻžāϞāĻŋāĻāĻž āĻĒāĻžāĻ (get_securities āĻļā§āϧā§āĻŽāĻžāϤā§āϰ āĻĄāĻŋāĻĢāϞā§āĻāϰā§āĻĒā§ āϏāĻā§āϰāĻŋāϝāĻŧ āĻšāϝāĻŧ, āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āĻā§āĻĄ āĻĻā§āĻā§āύ) āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻ āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āϏāĻāϰāĻā§āώāĻŖ āĻāϰāĻŋ, āĻāĻāĻ āĻāĻŋāĻāĻžāϰā§āϰ āϏāĻžāĻĨā§ āĻāĻāĻāĻŋ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āĻāĻā§ āĻāĻŋāύāĻž āϤāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰ⧠āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āĻŦāĻŋāύāĻŋāĻŽāϝāĻŧ, āϝāĻĻāĻŋ āĻĨāĻžāĻā§, āϤāĻŦā§ āĻāĻāĻŋ (āĻāĻžāĻāĻ) āĻā§āĻŦāϞ āĻāĻĒāĻĄā§āĻ āĻāϰāĻž āĻšāĻŦā§āĨ¤
āĻāĻŽāĻžāĻĻā§āϰ āϏā§āώā§āĻāĻŋ āĻāĻžāϞ⧠āĻāϰāĻž āϝāĻžāĻ!
> docker-compose up -d
... ĐаĐŋŅŅĐē ĐēĐžĐŊŅĐĩĐšĐŊĐĩŅОв ...
> faust -A horton.agents worker --without-web -l infoāĻĒāĻŋāĻāϏ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ āĻāĻŽāĻŋ āύāĻŋāĻŦāύā§āϧāĻā§āϞāĻŋāϤ⧠āĻĢāĻžāϏā§āĻ āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰāĻŦ āύāĻž, āϤāĻžāĻ āĻāĻŽāϰāĻž āĻāĻĒāϝā§āĻā§āϤ āĻĒāϤāĻžāĻāĻž āϏā§āĻ āĻāϰā§āĻāĻŋāĨ¤
āĻāĻŽāĻžāĻĻā§āϰ āϞāĻā§āĻ āĻāĻŽāĻžāύā§āĻĄā§, āĻāĻŽāϰāĻž āϤāĻĨā§āϝ āϞāĻ āĻāĻāĻāĻĒā§āĻ āϏā§āϤāϰā§āϰ āϏāĻžāĻĨā§ āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻ āĻŦāĻā§āĻā§āĻāĻāĻŋ āĻā§āĻĨāĻžāϝāĻŧ āĻā§āĻāĻāϤ⧠āĻšāĻŦā§ āĻāĻŦāĻ āĻāĻāĻŋāϰ āϏāĻžāĻĨā§ āĻā§ āĻāϰāϤ⧠āĻšāĻŦā§ (āĻāĻāĻāύ āĻāϰā§āĻŽā§ āϞāĻā§āĻ āĻāϰā§āύ) āĻŦāϞā§āĻāĻŋāϞāĻžāĻŽāĨ¤ āĻāĻŽāϰāĻž āύāĻŋāĻŽā§āύāϞāĻŋāĻāĻŋāϤ āĻāĻāĻāĻĒā§āĻ āĻĒā§āϤā§:
āĻāĻā§āώāĻ
âÆaÂĩSâ v1.10.4âŦââââââââââââââââââââââââââââââââââââââââââââââââââââ
â id â horton â
â transport â [URL('kafka://localhost:9092')] â
â store â memory: â
â log â -stderr- (info) â
â pid â 1271262 â
â hostname â host-name â
â platform â CPython 3.8.2 (Linux x86_64) â
â drivers â â
â transport â aiokafka=1.1.6 â
â web â aiohttp=3.6.2 â
â datadir â /path/to/project/horton-data â
â appdir â /path/to/project/horton-data/v1 â
âââââââââââââââ´ââââââââââââââââââââââââââââââââââââââââââââââââââââ
... ĐģĐžĐŗĐ¸, ĐģĐžĐŗĐ¸, ĐģĐžĐŗĐ¸ ...
âTopic Partition SetââââââââââŦâââââââââââââ
â topic â partitions â
ââââââââââââââââââââââââââââââŧâââââââââââââ¤
â collect_securities â {0-7} â
â horton-__assignor-__leader â {0} â
ââââââââââââââââââââââââââââââ´âââââââââââââ āĻāĻāĻž āĻā§āĻŦāĻŋāϤ!!!
āĻāϏā§āύ āĻĒāĻžāϰā§āĻāĻŋāĻļāύ āϏā§āĻāĻāĻŋ āĻĻā§āĻāĻŋāĨ¤ āĻāĻŽāϰāĻž āĻĻā§āĻāϤ⧠āĻĒāĻžāĻā§āĻāĻŋ, āĻāĻāĻāĻŋ āĻŦāĻŋāώāϝāĻŧ āϤā§āϰāĻŋ āĻāϰāĻž āĻšāϝāĻŧā§āĻāĻŋāϞ āϝ⧠āύāĻžāĻŽāĻāĻŋ āĻāĻŽāϰāĻž āĻā§āĻĄā§ āĻŽāύā§āύā§āϤ āĻāϰā§āĻāĻŋ, āĻĒāĻžāϰā§āĻāĻŋāĻļāύā§āϰ āĻĄāĻŋāĻĢāϞā§āĻ āϏāĻāĻā§āϝāĻž (8, āĻĨā§āĻā§ āύā§āĻāϝāĻŧāĻž - āĻ ā§āϝāĻžāĻĒā§āϞāĻŋāĻā§āĻļāύ āĻ āĻŦāĻā§āĻā§āĻ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ), āϝā§āĻšā§āϤ⧠āĻāĻŽāϰāĻž āĻāĻŽāĻžāĻĻā§āϰ āĻŦāĻŋāώāϝāĻŧā§āϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻĒā§āĻĨāĻ āĻŽāĻžāύ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻāϰāĻŋāύāĻŋ (āĻĒāĻžāϰā§āĻāĻŋāĻļāύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§)āĨ¤ āĻāϝāĻŧāĻžāϰā§āĻāĻžāϰ⧠āϞāĻā§āĻ āĻāϰāĻž āĻāĻā§āύā§āĻāĻā§ āϏāĻŽāϏā§āϤ 8āĻāĻŋ āĻĒāĻžāϰā§āĻāĻŋāĻļāύ āĻŦāϰāĻžāĻĻā§āĻĻ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, āϝā§āĻšā§āϤ⧠āĻāĻāĻŋ āĻāĻāĻŽāĻžāϤā§āϰ, āϤāĻŦā§ āĻāĻāĻŋ āĻā§āϞāĻžāϏā§āĻāĻžāϰāĻŋāĻ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻ āĻāĻļā§ āĻāϰāĻ āĻŦāĻŋāĻļāĻĻā§ āĻāϞā§āĻāύāĻž āĻāϰāĻž āĻšāĻŦā§āĨ¤
āĻ āĻŋāĻ āĻāĻā§, āĻāĻāύ āĻāĻŽāϰāĻž āĻ āύā§āϝ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻāĻāύā§āĻĄā§āϤ⧠āϝā§āϤ⧠āĻĒāĻžāϰāĻŋ āĻāĻŦāĻ āĻāĻŽāĻžāĻĻā§āϰ āĻŦāĻŋāώāϝāĻŧā§ āĻāĻāĻāĻŋ āĻāĻžāϞāĻŋ āĻŦāĻžāϰā§āϤāĻž āĻĒāĻžāĻ āĻžāϤ⧠āĻĒāĻžāϰāĻŋ:
> faust -A horton.agents send @collect_securities
{"topic": "collect_securities", "partition": 6, "topic_partition": ["collect_securities", 6], "offset": 0, "timestamp": ..., "timestamp_type": 0}āĻĒāĻŋāĻāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠@ āĻāĻŽāϰāĻž āĻĻā§āĻāĻžāĻ āϝ⧠āĻāĻŽāϰāĻž "collect_securities" āύāĻžāĻŽā§āϰ āĻāĻāĻāĻŋ āĻŦāĻŋāώāϝāĻŧā§ āĻāĻāĻāĻŋ āĻŦāĻžāϰā§āϤāĻž āĻĒāĻžāĻ āĻžāĻā§āĻāĻŋāĨ¤
āĻāĻ āĻā§āώā§āϤā§āϰā§, āĻŦāĻžāϰā§āϤāĻžāĻāĻŋ āĻĒāĻžāϰā§āĻāĻŋāĻļāύ 6-āĻ āĻāĻŋāϝāĻŧā§āĻāĻŋāϞ - āĻāĻĒāύāĻŋ āĻā§āϝāĻžāĻĢāĻĄā§āϰāĻĒ āĻ
āύ-āĻ āĻāĻŋāϝāĻŧā§ āĻāĻāĻŋ āĻĒāϰā§āĻā§āώāĻž āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ localhost:9000
āĻāĻŽāĻžāĻĻā§āϰ āĻāϰā§āĻŽā§āϰ āϏāĻžāĻĨā§ āĻāĻžāϰā§āĻŽāĻŋāύāĻžāϞ āĻāĻāύā§āĻĄā§āϤ⧠āĻāĻŋāϝāĻŧā§, āĻāĻŽāϰāĻž loguru āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĒāĻžāĻ āĻžāύ⧠āĻāĻāĻāĻŋ āĻā§āĻļāĻŋāϰ āĻŦāĻžāϰā§āϤāĻž āĻĻā§āĻāϤ⧠āĻĒāĻžāĻŦ:
2020-09-23 00:26:37.304 | INFO | horton.agents:collect_securities:40 - Start collect securitiesāĻāĻŽāϰāĻž āĻŽāĻā§āĻā§ (Robo3T āĻŦāĻž Studio3T āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§) āĻĻā§āĻāϤ⧠āĻĒāĻžāϰāĻŋ āĻāĻŦāĻ āĻĻā§āĻāϤ⧠āĻĒāĻžāϰāĻŋ āϝ⧠āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻā§āϞāĻŋ āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āϰāϝāĻŧā§āĻā§:
āĻāĻŽāĻŋ āĻŦāĻŋāϞāĻŋāϝāĻŧāύā§āϝāĻŧāĻžāϰ āύāĻ, āĻāĻŦāĻ āϤāĻžāĻ āĻāĻŽāϰāĻž āĻĒā§āϰāĻĨāĻŽ āĻĻā§āĻāĻžāϰ āĻŦāĻŋāĻāϞā§āĻĒā§ āϏāύā§āϤā§āώā§āĻāĨ¤
āϏā§āĻ āĻāĻŦāĻ āĻāύāύā§āĻĻ - āĻĒā§āϰāĻĨāĻŽ āĻāĻā§āύā§āĻ āĻĒā§āϰāϏā§āϤā§āϤ :)
āĻāĻā§āύā§āĻ āĻĒā§āϰāϏā§āϤā§āϤ, āύāϤā§āύ āĻāĻā§āύā§āĻ āĻĻā§āϰā§āĻāĻā§āĻŦā§ āĻšā§āĻ!
āĻšā§āϝāĻžāĻ, āĻāĻĻā§āϰāϞā§āĻ, āĻāĻŽāϰāĻž āĻāĻ āύāĻŋāĻŦāύā§āϧāĻāĻŋ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāϏā§āϤā§āϤ āĻĒāĻĨā§āϰ āĻŽāĻžāϤā§āϰ 1/3 āĻ āĻāĻļ āĻāĻāĻžāϰ āĻāϰā§āĻāĻŋ, āϤāĻŦā§ āύāĻŋāϰā§ā§āϏāĻžāĻšāĻŋāϤ āĻšāĻŦā§āύ āύāĻž, āĻāĻžāϰāĻŖ āĻāĻāύ āĻāĻāĻŋ āĻāϰāĻ āϏāĻšāĻ āĻšāĻŦā§āĨ¤
āϏā§āϤāϰāĻžāĻ āĻāĻāύ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻŽāύ āĻāĻāĻāύ āĻāĻā§āύā§āĻā§āϰ āĻĒā§āϰāϝāĻŧā§āĻāύ āϝāĻž āĻŽā§āĻāĻž āϤāĻĨā§āϝ āϏāĻāĻā§āϰāĻš āĻāϰ⧠āĻāĻŦāĻ āĻāĻāĻāĻŋ āϏāĻāĻā§āϰāĻš āύāĻĨāĻŋāϤ⧠āϰāĻžāĻā§:
collect_security_overview_topic = app.topic("collect_security_overview", internal=True)
@app.agent(collect_security_overview_topic)
async def collect_security_overview(
stream: StreamT[?],
) -> AsyncIterable[bool]:
async with aiohttp.ClientSession() as session:
async for event in stream:
...āϝā§āĻšā§āϤ⧠āĻāĻ āĻāĻā§āύā§āĻ āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻž āϏāĻŽā§āĻĒāϰā§āĻā§ āϤāĻĨā§āϝ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻāϰāĻŦā§, āϤāĻžāĻ āĻāĻŽāĻžāĻĻā§āϰ āĻŦāĻžāϰā§āϤāĻžāϝāĻŧ āĻāĻ āύāĻŋāϰāĻžāĻĒāϤā§āϤāĻžāϰ āĻāĻŋāĻāĻžāϰ (āĻĒā§āϰāϤā§āĻ) āύāĻŋāϰā§āĻĻā§āĻļ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤ āĻāĻ āĻāĻĻā§āĻĻā§āĻļā§āϝ⧠āĻĢāĻžāĻāϏā§āĻā§ āĻāĻā§ â āĻā§āϞāĻžāϏ āϝā§āĻā§āϞāĻŋ āĻāĻā§āύā§āĻ āĻŦāĻŋāώāϝāĻŧā§ āĻŦāĻžāϰā§āϤāĻž āϏā§āĻāĻŋāĻŽ āĻā§āώāĻŖāĻž āĻāϰā§āĨ¤
āĻāĻ āĻā§āώā§āϤā§āϰā§, āĻāϰ āϝāĻžāύ āĻāĻŦāĻ āĻāĻ āĻŦāĻŋāώāϝāĻŧā§āϰ āĻŦāĻžāϰā§āϤāĻžāĻāĻŋ āĻā§āĻŽāύ āĻšāĻāϝāĻŧāĻž āĻāĻāĻŋāϤ āϤāĻž āĻŦāϰā§āĻŖāύāĻž āĻāϰā§āύ:
import faust
class CollectSecurityOverview(faust.Record):
symbol: str
exchange: str
āĻāĻĒāύāĻŋ āĻ āύā§āĻŽāĻžāύ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ, faust āĻŦāĻžāϰā§āϤāĻž āϏā§āĻāĻŋāĻŽāĻž āĻŦāϰā§āĻŖāύāĻž āĻāϰāϤ⧠āĻĒāĻžāĻāĻĨāύ āĻāĻžāĻāĻĒ āĻā§āĻāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āϝāĻžāϰ āĻāĻžāϰāĻŖā§ āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋ āĻĻā§āĻŦāĻžāϰāĻž āϏāĻŽāϰā§āĻĨāĻŋāϤ āϏāϰā§āĻŦāύāĻŋāĻŽā§āύ āϏāĻāϏā§āĻāϰāĻŖ .
āĻāϏā§āύ āĻāĻā§āύā§āĻā§ āĻĢāĻŋāϰ⧠āϝāĻžāĻ, āĻĒā§āϰāĻāĻžāϰāĻā§āϞāĻŋ āϏā§āĻ āĻāϰā§āύ āĻāĻŦāĻ āĻāĻāĻŋ āϝā§āĻ āĻāϰā§āύ:
collect_security_overview_topic = app.topic(
"collect_security_overview", internal=True, value_type=CollectSecurityOverview
)
@app.agent(collect_security_overview_topic)
async def collect_security_overview(
stream: StreamT[CollectSecurityOverview],
) -> AsyncIterable[bool]:
async with aiohttp.ClientSession() as session:
async for event in stream:
logger.info(
"Start collect security [{symbol}] overview", symbol=event.symbol
)
client = AlphaVantageClient(session, API_KEY)
security_overview = await client.get_security_overview(event.symbol)
await SecurityCRUD.update_one({"symbol": event.symbol, "exchange": event.exchange}, security_overview)
yield True
āĻāĻĒāύāĻŋ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻā§āĻā§āύ, āĻāĻŽāϰāĻž āĻāĻĒāĻŋāĻ āĻĒā§āϰāĻžāϰāĻŽā§āĻāĻŋāĻ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧠āĻāĻāĻāĻŋ āϏā§āĻāĻŋāĻŽ āϏāĻš āĻāĻāĻāĻŋ āύāϤā§āύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāĻāĻžāϰ āĻĒāĻžāϏ āĻāϰāĻŋ - value_typeāĨ¤ āĻāϰāĻ, āϏāĻŦāĻāĻŋāĻā§ āĻāĻāĻ āϏā§āĻāĻŋāĻŽ āĻ āύā§āϏāϰāĻŖ āĻāϰā§, āϤāĻžāĻ āĻāĻŽāĻŋ āĻ āύā§āϝ āĻāĻŋāĻā§āϤ⧠āĻĨāĻžāĻāĻžāϰ āĻā§āύ āĻŦāĻŋāύā§āĻĻā§ āĻĻā§āĻāϤ⧠āĻĒāĻžāĻā§āĻāĻŋ āύāĻžāĨ¤
āĻ āĻŋāĻ āĻāĻā§, āĻā§āĻĄāĻŧāĻžāύā§āϤ āϏā§āĻĒāϰā§āĻļ āĻšāϞ āĻŽā§āĻāĻž āϤāĻĨā§āϝ āϏāĻāĻā§āϰāĻšāĻāĻžāϰ⧠āĻāĻā§āύā§āĻāĻā§ collect_securitites āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻāϞ āϝā§āĻ āĻāϰāĻž:
....
for security in securities:
await SecurityCRUD.update_one({
"symbol": security["symbol"],
"exchange": security["exchange"]
},
security,
upsert = True,
)
await collect_security_overview.cast(
CollectSecurityOverview(symbol = security["symbol"], exchange = security["exchange"])
)
....āĻāĻŽāϰāĻž āĻŦāĻžāϰā§āϤāĻžāϰ āĻāύā§āϝ āĻĒā§āϰā§āĻŦā§ āĻā§āώāĻŋāϤ āϏā§āĻāĻŋāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŋāĨ¤ āĻāĻ āĻā§āώā§āϤā§āϰā§, āĻāĻŽāĻŋ .cast āĻĒāĻĻā§āϧāϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āĻāĻŋ āϝā§āĻšā§āϤ⧠āĻāĻŽāĻžāĻĻā§āϰ āĻāĻā§āύā§āĻā§āϰ āĻĢāϞāĻžāĻĢāϞā§āϰ āĻāύā§āϝ āĻ āĻĒā§āĻā§āώāĻž āĻāϰāϤ⧠āĻšāĻŦā§ āύāĻž, āϤāĻŦā§ āĻāĻāĻŋ āĻāϞā§āϞā§āĻ āĻāϰāĻžāϰ āĻŽāϤ⧠āĻŦāĻŋāώāϝāĻŧā§ āĻāĻāĻāĻŋ āĻŦāĻžāϰā§āϤāĻž āĻĒāĻžāĻ āĻžāύ:
cast - āĻŦā§āϞāĻ āĻāϰ⧠āύāĻž āĻāĻžāϰāĻŖ āĻāĻāĻŋ āĻĢāϞāĻžāĻĢāϞ āĻāĻļāĻž āĻāϰ⧠āύāĻžāĨ¤ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ āĻŦāĻžāϰā§āϤāĻž āĻšāĻŋāϏāĻžāĻŦā§ āĻ āύā§āϝ āĻŦāĻŋāώāϝāĻŧā§ āĻĢāϞāĻžāĻĢāϞ āĻĒāĻžāĻ āĻžāϤ⧠āĻĒāĻžāϰāĻŦā§āύ āύāĻž.
send - āĻŦā§āϞāĻ āĻāϰ⧠āύāĻž āĻāĻžāϰāĻŖ āĻāĻāĻŋ āĻĢāϞāĻžāĻĢāϞ āĻāĻļāĻž āĻāϰ⧠āύāĻžāĨ¤ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻ āĻāϞā§āϞā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ āϝ⧠āĻŦāĻŋāώāϝāĻŧā§ āĻĢāϞāĻžāĻĢāϞ āϝāĻžāĻŦā§āĨ¤
āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰā§āύ - āĻĢāϞāĻžāĻĢāϞā§āϰ āĻāύā§āϝ āĻ āĻĒā§āĻā§āώāĻž āĻāϰā§āύāĨ¤ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ āĻāĻā§āύā§āĻ āĻāϞā§āϞā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύ āϝ⧠āĻŦāĻŋāώāϝāĻŧā§ āĻĢāϞāĻžāĻĢāϞ āϝāĻžāĻŦā§āĨ¤
āϏā§āϤāϰāĻžāĻ, āĻāĻāĻā§āϰ āĻāύā§āϝ āĻāĻā§āύā§āĻāĻĻā§āϰ āϏāĻžāĻĨā§ āϝ⧠āϏāĻŦ!
āϏā§āĻŦāĻĒā§āύā§āϰ āĻĻāϞ
āĻļā§āώ āĻāĻŋāύāĻŋāϏāĻāĻŋ āĻāĻŽāĻŋ āĻāĻ āĻ āĻāĻļā§ āϞāĻŋāĻāϤ⧠āĻĒā§āϰāϤāĻŋāĻļā§āϰā§āϤāĻŋ āĻĻāĻŋāϝāĻŧā§āĻāĻŋ āϤāĻž āĻšāϞ āĻāĻŽāĻžāύā§āĻĄāĨ¤ āĻāĻā§āĻ āĻāϞā§āϞā§āĻ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§, faust-āĻ āĻāĻŽāĻžāύā§āĻĄāĻā§āϞāĻŋ āĻā§āϞāĻŋāĻā§āϰ āĻāĻžāϰāĻĒāĻžāĻļā§ āĻāĻāĻāĻŋ āĻŽā§āĻĄāĻŧāĻāĨ¤ āĻāϏāϞā§, faust -A āĻā§ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻžāϏā§āĻāĻŽ āĻāĻŽāĻžāύā§āĻĄāĻā§ āĻāϰ āĻāύā§āĻāĻžāϰāĻĢā§āϏ⧠āϏāĻāϝā§āĻā§āϤ āĻāϰā§
āĻā§āώāĻŋāϤ āĻāĻā§āύā§āĻāĻĻā§āϰ āĻĒāϰ⧠āĻĄā§āĻā§āϰā§āĻāϰā§āϰ āϏāĻžāĻĨā§ āĻāĻāĻāĻŋ āĻĢāĻžāĻāĻļāύ āϝā§āĻ āĻāϰā§āύ app.commandāĻĒāĻĻā§āϧāϤāĻŋ āĻāϞāĻŋāĻ āύāĻŋāĻā§āώā§āĻĒ Ņ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāϏ āϏāĻāĻā§āϰāĻš āĻāϰā§āύ:
@app.command()
async def start_collect_securities():
"""Collect securities and overview."""
await collect_securities.cast()
āϏā§āϤāϰāĻžāĻ, āϝāĻĻāĻŋ āĻāĻŽāϰāĻž āĻāĻŽāĻžāύā§āĻĄā§āϰ āϤāĻžāϞāĻŋāĻāĻž āĻāϞ āĻāϰāĻŋ, āĻāĻŽāĻžāĻĻā§āϰ āύāϤā§āύ āĻāĻŽāĻžāύā§āĻĄ āĻāϤ⧠āĻĨāĻžāĻāĻŦā§:
> faust -A horton.agents --help
....
Commands:
agents List agents.
clean-versions Delete old version directories.
completion Output shell completion to be evaluated by the...
livecheck Manage LiveCheck instances.
model Show model detail.
models List all available models as a tabulated list.
reset Delete local table state.
send Send message to agent/topic.
start-collect-securities Collect securities and overview.
tables List available tables.
worker Start worker instance for given app.
āĻāĻŽāϰāĻž āĻāĻāĻŋāĻā§ āĻ āύā§āϝ āĻāĻžāϰāĻ āĻŽāϤ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŋ, āϤāĻžāĻ āĻāϏā§āύ āĻĢāĻžāϏā§āĻ āĻāϝāĻŧāĻžāϰā§āĻāĻžāϰāĻāĻŋ āĻĒā§āύāϰāĻžāϝāĻŧ āĻāĻžāϞ⧠āĻāϰāĻŋ āĻāĻŦāĻ āϏāĻŋāĻāĻŋāĻāϰāĻŋāĻāĻŋāĻā§āϰ āĻāĻāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āϏāĻāĻā§āϰāĻš āĻļā§āϰ⧠āĻāϰāĻŋ:
> faust -A horton.agents start-collect-securitiesāĻĒāϰāĻŦāϰā§āϤā§āϤ⧠āĻā§ āĻšāĻŦā§?
āĻĒāϰāĻŦāϰā§āϤ⧠āĻ āĻāĻļā§, āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāϰāĻŖ āĻšāĻŋāϏāĻžāĻŦā§ āĻ āĻŦāĻļāĻŋāώā§āĻ āĻāĻā§āύā§āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§, āĻāĻŽāϰāĻž āĻŦāĻāϰā§āϰ āĻā§āϰā§āĻĄāĻŋāĻ āĻāĻŦāĻ āĻā§āϰāύ āϞāĻā§āĻā§āϰ āĻāĻā§āύā§āĻā§āϰ āĻā§āϞā§āĻāĻŋāĻ āĻĒā§āϰāĻžāĻāϏā§āϰ āĻāϰāĻŽāϤāĻž āĻ āύā§āϏāύā§āϧāĻžāύā§āϰ āĻāύā§āϝ āϏāĻŋāĻā§āĻ āĻĒā§āϰāĻā§āϰāĻŋāϝāĻŧāĻž āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰāĻŦāĨ¤
āĻāĻ āϝ⧠āĻāύā§āϝ āϏāĻŦ! āĻĒāĻĄāĻŧāĻžāϰ āĻāύā§āϝ āϧāύā§āϝāĻŦāĻžāĻĻ :)
āĻĒāĻŋāĻāϏ āĻļā§āώ āĻ āĻāĻļā§āϰ āĻ āϧā§āύ⧠āĻāĻŽāĻžāĻā§ āĻĢāĻžāϏā§āĻ āĻāĻŦāĻ āϏāĻā§āĻāĻŽ āĻāĻžāĻĢāĻāĻž āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāĻŋāĻā§āĻāĻžāϏāĻž āĻāϰāĻž āĻšāϝāĻŧā§āĻāĻŋāϞ () āĻĻā§āĻā§ āĻŽāύ⧠āĻšāĻā§āĻā§ āϏāĻā§āĻāĻŽāĻāĻŋ āĻ āύā§āĻ āĻāĻĒāĻžāϝāĻŧā§ āĻāϰāĻ āĻāĻžāϰā§āϝāĻāϰā§, āϤāĻŦā§ āϏāϤā§āϝāĻāĻŋ āĻšāϞ āϝ⧠āĻĢāĻžāϏā§āĻā§āϰ āϏāĻā§āĻāĻŽā§āϰ āĻāύā§āϝ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻā§āϞāĻžāϝāĻŧā§āύā§āĻ āϏāĻŽāϰā§āĻĨāύ āύā§āĻ - āĻāĻāĻŋ āĻ āύā§āϏāϰāĻŖ āĻāϰā§.
āĻāϤā§āϏ: www.habr.com
