เชธเชฎเชพเชตเชฟเชทเซเชเซเชจเซเช เชเซเชทเซเชเช
-
เชญเชพเช II: เชเชเชจเซเชเซ เช เชจเซ เชเซเชฎเซ
เชเชชเชฃเซ เช เชนเซเช เชถเซเช เชเชฐเซ เชฐเชนเซเชฏเชพ เชเซเช?
เชคเซเชฅเซ, เชคเซเชฅเซ, เชฌเซเชเซ เชญเชพเช. เช เชเชพเช เชฒเชเซเชฏเชพ เชฎเซเชเชฌ, เชคเซเชฎเชพเช เชเชชเชฃเซ เชจเซเชเซ เชฎเซเชเชฌ เชเชฐเซเชถเซเช:
-
เชเชพเชฒเซ aiohttp เชชเชฐ เชเชฒเซเชซเชพเชตเซเชจเซเชเซเช เชฎเชพเชเซ เชเช เชจเชพเชจเซ เชเซเชฒเชพเชฏเชเช เชฒเชเซเช เช เชจเซ เชเชชเชฃเชจเซ เชเชฐเซเชฐเซ เชเชจเซเชกเชชเซเชเชจเซเชเชจเซ เชตเชฟเชจเชเชคเซเช เชธเชพเชฅเซ.
-
เชเชพเชฒเซ เชเช เชเชเชจเซเช เชฌเชจเชพเชตเซเช เชเซ เชธเชฟเชเซเชฏเซเชฐเชฟเชเซเช เชชเชฐเชจเซ เชกเซเชเชพ เช เชจเซ เชคเซเชจเชพ เชชเชฐเชจเซ เชฎเซเชเชพ เชฎเชพเชนเชฟเชคเซ เชเชเชคเซเชฐเชฟเชค เชเชฐเชถเซ.
เชชเชฐเชเชคเซ, เช เชฎเซ เช เชชเซเชฐเซเชเซเชเซเช เชฎเชพเชเซ เช เชเชฐเซเชถเซเช, เช เชจเซ เชซเซเชธเซเช เชธเชเชถเซเชงเชจเชจเซ เชฆเซเชฐเชทเซเชเชฟเช, เช เชฎเซ เชเชพเชซเชเชพเชฎเชพเชเชฅเซ เชธเซเชเซเชฐเซเชฎ เชเชตเซเชจเซเชเซเชธ เชชเชฐ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชเชฐเชคเชพ เชเชเชจเซเชเซเชจเซ เชเซเชตเซ เชฐเซเชคเซ เชฒเชเชตเชพ เชคเซ เชถเซเชเซเชถเซเช, เชคเซเชฎเช เช เชฎเชพเชฐเชพ เชเชฟเชธเซเชธเชพเชฎเชพเช เชเชฆเซเชถเซ (เชเซเชฒเชฟเช เชฐเซเชชเชฐ) เชเซเชตเซ เชฐเซเชคเซ เชฒเชเชตเชพ - เชเชเชจเซเช เชฆเซเชตเชพเชฐเชพ เชฆเซเชเชฐเซเช เชฐเชพเชเชคเชพ เชตเชฟเชทเชฏ เชชเชฐ เชฎเซเชจเซเชฏเซเช เชฒ เชชเซเชถ เชธเชเชฆเซเชถเชพเช เชฎเชพเชเซ.
เชคเชพเชฒเซเชฎ
เชเชฒเซเชซเชพเชตเซเชจเซเชเซเช เชเซเชฒเชพเชฏเชเช
เชชเซเชฐเชฅเชฎ, เชเชพเชฒเซ เชเชฒเซเชซเชพเชตเชจเซเชเซเชเชจเซ เชตเชฟเชจเชเชคเซเช เชฎเชพเชเซ เชเช เชจเชพเชจเซ 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 เชถเชฃเชเชพเชฐ.
เชชเซ.เชเชธ. config.yml เชฎเชพเช เชธเซเชฅเชพเชจเชฟเช เชฐเซเชคเซ เชเชฒเซเชซเชพเชตเชจเซเชเซเช เชเซเชเชจ เชเชฎเซเชฐเชตเชพเชจเซเช เชญเซเชฒเชถเซ เชจเชนเซเช, เช
เชฅเชตเชพ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชตเซเชฐเซเชเชฌเชฒเชจเซ เชจเชฟเชเชพเชธ เชเชฐเซ. HORTON_SERVICE_APIKEY
. เช
เชฎเชจเซ เชเซเชเชจ เชฎเชณเซ เชเซ
CRUD เชตเชฐเซเช
เชธเชฟเชเซเชฏเซเชฐเชฟเชเซเช เชตเชฟเชถเซ เชฎเซเชเชพ เชฎเชพเชนเชฟเชคเซ เชธเชเชเซเชฐเชนเชฟเชค เชเชฐเชตเชพ เชฎเชพเชเซ เช เชฎเชพเชฐเซ เชชเชพเชธเซ เชธเชฟเชเซเชฏเซเชฐเชฟเชเซเช เชเชฒเซเชเซเชถเชจ เชนเชถเซ.
เชฎเชพเชฐเชพ เชฎเชคเซ, เช เชนเซเช เชเชเชเชชเชฃ เชธเชฎเชเชพเชตเชตเชพเชจเซ เชเชฐเซเชฐ เชจเชฅเซ, เช เชจเซ เชฌเซเช เชเซเชฒเชพเชธ เชชเซเชคเซ เชเชเชฆเชฎ เชธเชฐเชณ เชเซ.
get_app()
เชฎเชพเช เชเชชเซเชฒเชฟเชเซเชถเชจ เชเชฌเซเชเซเชเซเช เชฌเชจเชพเชตเชตเชพ เชฎเชพเชเซ เชเช เชซเชเชเซเชถเชจ เชเชฎเซเชฐเซเช
เชธเซเชชเซเชเชฒเชฐ
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
เชคเซเชฅเซ, เชชเซเชฐเชฅเชฎ เชเชชเชฃเซ เชซเซเชธเซเช เชเชชเซเชฒเชฟเชเซเชถเชจ เชเชฌเซเชเซเชเซเช เชฎเซเชณเชตเซเช เชเซเช - เชคเซ เชเชเชฆเชฎ เชธเชฐเชณ เชเซ. เชเชเชณ, เช เชฎเซ เช เชฎเชพเชฐเชพ เชเชเชจเซเช เชฎเชพเชเซ เชเช เชตเชฟเชทเชฏ เชธเซเชชเชทเซเชเชชเชฃเซ เชเชพเชนเซเชฐ เชเชฐเซเช เชเซเช... เช เชนเซเช เชคเซ เชถเซเช เชเซ, เชเชเชคเชฐเชฟเช เชชเชฐเชฟเชฎเชพเชฃ เชถเซเช เชเซ เช เชจเซ เชคเซเชจเซ เช เชฒเช เชฐเซเชคเซ เชเซเชตเซ เชฐเซเชคเซ เชเซเช เชตเซ เชถเชเชพเชฏ เชคเซ เชเชฒเซเชฒเซเช เชเชฐเชตเซ เชฏเซเชเซเชฏ เชเซ.
-
เชเชพเชซเชเชพเชจเชพ เชตเชฟเชทเชฏเซ, เชเซ เชเชชเชฃเซ เชเซเชเซเชเชธ เชตเซเชฏเชพเชเซเชฏเชพ เชเชพเชฃเชตเซ เชนเซเชฏ, เชคเซ เชคเซ เชตเชพเชเชเชตเซเช เชตเชงเซ เชธเชพเชฐเซเช เชเซ
เชฌเชเชง. เชฆเชธเซเชคเชพเชตเซเช , เช เชฅเชตเชพ เชคเชฎเซ เชตเชพเชเชเซ เชถเชเซ เชเซเชธเชเชเชฒเชจ เชฐเชถเชฟเชฏเชจเชฎเชพเช เชนเซเชฌเซเชฐเซ เชชเชฐ, เชเซเชฏเชพเช เชฌเชงเซเช เชชเชฃ เชเชเชฆเชฎ เชธเชเซเช เชฐเซเชคเซ เชชเซเชฐเชคเชฟเชฌเชฟเชเชฌเชฟเชค เชฅเชพเชฏ เชเซ :) -
เชเชเชคเชฐเชฟเช เชชเชฐเชฟเชฎเชพเชฃ , เชซเซเชธเซเช เชกเซเชเชฎเชพเช เชเซเชฌ เชธเชพเชฐเซ เชฐเซเชคเซ เชตเชฐเซเชฃเชตเซเชฒ เชเซ, เชเซ เช เชฎเชจเซ เชเซเชกเชฎเชพเช เชธเซเชงเชพ เช เชตเชฟเชทเชฏเชจเซ เชเซเช เชตเชตเชพเชจเซ เชฎเชเชเซเชฐเซ เชเชชเซ เชเซ, เช เชฒเชฌเชคเซเชค, เชเชจเซ เช เชฐเซเชฅ เชซเซเชธเซเช เชกเซเชตเชฒเชชเชฐเซเชธ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเชฆเชพเชจ เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฒเชพ เชชเชฐเชฟเชฎเชพเชฃเซ เชเซ, เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ: เชฐเซเชเซเชจเซเชถเชจ, เชฐเซเชเซเชจเซเชถเชจ เชชเซเชฒเชฟเชธเซ (เชกเชฟเชซเซเชฒเซเช เชฐเซเชชเซ เชเชพเชขเซ เชจเชพเชเซ, เชชเชฐเชเชคเซ เชคเชฎเซ เชธเซเช เชเชฐเซ เชถเชเซ เชเซ.เชเซเชฎเซเชชเซเชเซเช ), เชตเชฟเชทเชฏ เชฆเซเช เชชเชพเชฐเซเชเซเชถเชจเซเชจเซ เชธเชเชเซเชฏเชพ (เชชเชพเชฐเซเชเซเชถเชจเซ เชเชฐเชตเชพ เชฎเชพเชเซ, เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชเชฐเชคเชพเช เชเชเซเชเชตเซเชถเซเชตเชฟเช เชฎเชนเชคเซเชต เชเชชเซเชฒเชฟเชเซเชถเชจเซเชธ เชซเซเชธเซเช). -
เชธเชพเชฎเชพเชจเซเชฏ เชฐเซเชคเซ, เชเชเชจเซเช เชตเซเชถเซเชตเชฟเช เชฎเซเชฒเซเชฏเซ เชธเชพเชฅเซ เชฎเซเชจเซเช เชเชฐเซเชฒ เชตเชฟเชทเชฏ เชฌเชจเชพเชตเซ เชถเชเซ เชเซ, เชเซ เชเซ, เชนเซเช เชฌเชงเซเช เชธเซเชชเชทเซเชเชชเชฃเซ เชเชพเชนเซเชฐ เชเชฐเชตเชพเชจเซเช เชชเชธเชเชฆ เชเชฐเซเช เชเซเช. เชตเชงเซเชฎเชพเช, เชเชเชจเซเชเชจเซ เชเชพเชนเซเชฐเชพเชคเชฎเชพเช เชตเชฟเชทเชฏเชจเชพ เชเซเชเชฒเชพเช เชชเชฐเชฟเชฎเชพเชฃเซ (เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชชเชพเชฐเซเชเซเชถเชจเชจเซ เชธเชเชเซเชฏเชพ เช เชฅเชตเชพ เชฐเซเชเซเชจเซเชถเชจ เชชเซเชฒเชฟเชธเซ) เชเซเช เชตเซ เชถเชเชพเชคเชพ เชจเชฅเซ.
เชตเชฟเชทเชฏเชจเซ เชฎเซเชจเซเชฏเซเช เชฒเซ เชตเซเชฏเชพเชเซเชฏเชพเชฏเชฟเชค เชเชฐเซเชฏเชพ เชตเชฟเชจเชพ เชคเซ เชเซเชตเซ เชฆเซเชเชพเช เชถเชเซ เชเซ เชคเซ เช เชนเซเช เชเซ:
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, เชฎเชพเชเชฅเซ เชฒเซเชตเชพเชฎเชพเช เชเชตเซ เชนเชคเซ.
เชธเชพเชฐเซเช, เชนเชตเซ เชเชชเชฃเซ เชฌเซเชเซ เชเชฐเซเชฎเชฟเชจเชฒ เชตเชฟเชจเซเชกเซ เชชเชฐ เชเช เชถเชเซเช เชเซเช เช เชจเซ เช เชฎเชพเชฐเชพ เชตเชฟเชทเชฏ เชชเชฐ เชเชพเชฒเซ เชธเชเชฆเซเชถ เชฎเซเชเชฒเซ เชถเชเซเช เชเซเช:
> 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 เชชเชฐ เชเชฏเซ เชนเชคเซ - เชคเชฎเซ kafdrop on เชชเชฐ เชเชเชจเซ เช เชคเชชเชพเชธเซ เชถเชเซ เชเซ localhost:9000
เช เชฎเชพเชฐเชพ เชเชพเชฐเซเชฏเชเชฐ เชธเชพเชฅเซ เชเชฐเซเชฎเชฟเชจเชฒ เชตเชฟเชจเซเชกเซ เชชเชฐ เชเชเชจเซ, เช เชฎเซ เชฒเซเชเซเชฐเซเชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เชฎเซเชเชฒเซเชฒ เชเซเชถ เชธเชเชฆเซเชถ เชเซเชถเซเช:
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
เชเซเชฎ เชคเชฎเซ เช
เชจเซเชฎเชพเชจ เชเชฐเซเชฏเซเช เชนเชถเซ, เชซเซเชธเซเช เชฎเซเชธเซเช เชธเซเชเซเชฎเชพเชจเซเช เชตเชฐเซเชฃเชจ เชเชฐเชตเชพ เชฎเชพเชเซ เชชเชพเชฏเชฅเซเชจ เชเชพเชเชช เชเชจเซเชเซเชถเชจเชจเซ เชเชชเชฏเซเช เชเชฐเซ เชเซ, เชคเซเชฅเซ เช เชฒเชพเชเชฌเซเชฐเซเชฐเซ เชฆเซเชตเชพเชฐเชพ เชธเชชเซเชฐเซเชเซเชก เชจเซเชฏเซเชจเชคเชฎ เชธเชเชธเซเชเชฐเชฃ
เชเชพเชฒเซ เชเชเชจเซเช เชชเชฐ เชชเชพเชเชพ เชเชเช, เชชเซเชฐเชเชพเชฐเซ เชธเซเช เชเชฐเซเช เช เชจเซ เชคเซเชจเซ เชเชฎเซเชฐเซเช:
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
เชเซเชฎ เชคเชฎเซ เชเซเช เชถเชเซ เชเซ, เช เชฎเซ เชตเชฟเชทเชฏเชจเซ เชถเชฐเซเชเชคเชจเซ เชชเชฆเซเชงเชคเชฟ - เชฎเซเชฒเซเชฏ_เชชเซเชฐเชเชพเชฐ เชฎเชพเชเซ เชธเซเชเซเชฎ เชธเชพเชฅเซ เชเช เชจเชตเซเช เชชเชฐเชฟเชฎเชพเชฃ เชชเชธเชพเชฐ เชเชฐเซเช เชเซเช. เชเชเชณ, เชฌเชงเซเช เชธเชฎเชพเชจ เชฏเซเชเชจเชพเชจเซ เช เชจเซเชธเชฐเซ เชเซ, เชคเซเชฅเซ เชฎเชจเซ เช เชจเซเชฏ เชเชเชเชชเชฃ เชชเชฐ เชงเซเชฏเชพเชจ เชเชชเชตเชพเชจเซ เชเซเช เชฎเซเชฆเซเชฆเซ เชฆเซเชเชพเชคเซ เชจเชฅเซ.
เช เซเช เชเซ, เช เชเชคเชฟเชฎ เชธเซเชชเชฐเซเชถ เช เชฎเซเชเชพ เชฎเชพเชนเชฟเชคเซ เชธเชเชเซเชฐเชน เชเชเชจเซเชเชจเซ เชเชเชคเซเชฐเชฟเชค_เชธเชฟเชเซเชฏเซเชฐเชฟเชเชพเชเชเซเชธ เชฎเชพเชเซ เชเซเชฒ เชเชฎเซเชฐเชตเชพเชจเซ เชเซ:
....
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 เชชเชฆเซเชงเชคเชฟเชจเซ เชเชชเชฏเซเช เชเชฐเซเชฏเซ เชเชพเชฐเชฃ เชเซ เช
เชฎเชพเชฐเซ เชเชเชจเซเชเชจเชพ เชชเชฐเชฟเชฃเชพเชฎเชจเซ เชฐเชพเชน เชเซเชตเชพเชจเซ เชเชฐเซเชฐ เชจเชฅเซ, เชชเชฐเชเชคเซ เชคเซ เชเชฒเซเชฒเซเชเชจเซเชฏ เชเซ เชเซ
-
เชเชพเชธเซเช - เช เชตเชฐเซเชงเชฟเชค เชเชฐเชคเซเช เชจเชฅเซ เชเชพเชฐเชฃ เชเซ เชคเซ เชชเชฐเชฟเชฃเชพเชฎเชจเซ เช เชชเซเชเซเชทเชพ เชฐเชพเชเชคเซเช เชจเชฅเซ. เชคเชฎเซ เชชเชฐเชฟเชฃเชพเชฎ เชฌเซเชเชพ เชตเชฟเชทเชฏ เชชเชฐ เชธเชเชฆเซเชถ เชคเชฐเซเชเซ เชฎเซเชเชฒเซ เชถเชเชคเชพ เชจเชฅเซ.
-
เชฎเซเชเชฒเซ - เช เชตเชฐเซเชงเชฟเชค เชเชฐเชคเซเช เชจเชฅเซ เชเชพเชฐเชฃ เชเซ เชคเซ เชชเชฐเชฟเชฃเชพเชฎเชจเซ เช เชชเซเชเซเชทเชพ เชฐเชพเชเชคเซเช เชจเชฅเซ. เชคเชฎเซ เชเซ เชตเชฟเชทเชฏ เชชเชฐ เชชเชฐเชฟเชฃเชพเชฎ เชเชตเชถเซ เชคเซเชฎเชพเช เชเชเชจเซเชเชจเซ เชเชฒเซเชฒเซเช เชเชฐเซ เชถเชเซ เชเซ.
-
เชชเซเชเซ - เชชเชฐเชฟเชฃเชพเชฎเชจเซ เชฐเชพเชน เชเซเช เชเซ. เชคเชฎเซ เชเซ เชตเชฟเชทเชฏ เชชเชฐ เชชเชฐเชฟเชฃเชพเชฎ เชเชตเชถเซ เชคเซเชฎเชพเช เชเชเชจเซเชเชจเซ เชเชฒเซเชฒเซเช เชเชฐเซ เชถเชเซ เชเซ.
เชคเซเชฅเซ, เชเชเซ เชฎเชพเชเซ เชเชเชจเซเชเซ เชธเชพเชฅเซ เชเชเชฒเซเช เช เชเซ!
เชกเซเชฐเซเชฎ เชเซเชฎ
เชเซเชฒเซเชฒเซ เชตเชธเซเชคเซ เชเซ เชฎเซเช เช เชญเชพเชเชฎเชพเช เชฒเชเชตเชพเชจเซเช เชตเชเชจ เชเชชเซเชฏเซเช เชนเชคเซเช เชคเซ เชเชฆเซเชถเซ เชเซ. เช เชเชพเช เชเชฒเซเชฒเซเช เชเชฐเซเชฏเซ เชเซ เชคเซเชฎ, เชซเซเชธเซเชเชฎเชพเช เชเชฆเซเชถเซ เชเซเชฒเชฟเชเชจเซ เชเชธเชชเชพเชธ เชเช เชเชตเชฐเชฃ เชเซ. เชตเชพเชธเซเชคเชตเชฎเชพเช, -A เชเซเชจเซ เชเชฒเซเชฒเซเช เชเชฐเชคเซ เชตเชเชคเซ faust เช เชฎเชพเชฐเชพ เชเชธเซเชเชฎ เชเชฆเซเชถเชจเซ เชคเซเชจเชพ เชเชจเซเชเชฐเชซเซเชธ เชธเชพเชฅเซ เชเซเชกเซ เชเซ
เชฎเชพเช เชเชพเชนเซเชฐ เชเชฐเชพเชฏเซเชฒเชพ เชเชเชจเซเชเซ เชชเชเซ
@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