เจตเจฟเจธเจผเจพ-เจธเฉเจเฉ
-
เจญเจพเจ 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 เจตเจฟเฉฑเจ เจ
เจฒเจซเจพเจตเจพเจเจเฉเจ เจเฉเจเจจ เจจเฉเฉฐ เจเฉเฉเจจเจพ เจจเจพ เจญเฉเฉฑเจฒเฉ, เจเจพเจ เจตเจพเจคเจพเจตเจฐเจฃ เจตเฉเจฐเฉเจเจฌเจฒ เจจเฉเฉฐ เจจเจฟเจฐเจฏเจพเจค เจเจฐเฉเฅค 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
เจเจธ เจฒเจ, เจชเจนเจฟเจฒเจพเจ เจ เจธเฉเจ เจซเจพเจธเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจเจฌเจเฉเจเจ เจชเฉเจฐเจพเจชเจค เจเจฐเจฆเฉ เจนเจพเจ - เจเจน เจเจพเจซเจผเฉ เจธเจงเจพเจฐเจจ เจนเฉเฅค เจ เฉฑเจเฉ, เจ เจธเฉเจ เจธเจชเฉฑเจธเจผเจ เจคเฉเจฐ 'เจคเฉ เจธเจพเจกเฉ เจเจเฉฐเจ เจฒเจ เจเฉฑเจ เจตเจฟเจธเจผเจพ เจเฉเจธเจผเจฟเจค เจเจฐเจฆเฉ เจนเจพเจ... เจเฉฑเจฅเฉ เจเจน เจตเจฐเจฃเจจ เจฏเฉเจ เจนเฉ เจเจฟ เจเจน เจเฉ เจนเฉ, เจ เฉฐเจฆเจฐเฉเจจเฉ เจฎเจพเจชเจฆเฉฐเจก เจเฉ เจนเฉ เจ เจคเฉ เจเจธเจจเฉเฉฐ เจตเฉฑเจเจฐเฉ เจขเฉฐเจ เจจเจพเจฒ เจเจฟเจตเฉเจ เจตเจฟเจตเจธเจฅเจฟเจค เจเฉเจคเจพ เจเจพ เจธเจเจฆเจพ เจนเฉเฅค
-
เจเจพเจซเจเจพ เจตเจฟเฉฑเจ เจตเจฟเจธเจผเฉ, เจเฉเจเจฐ เจ เจธเฉเจ เจธเจนเฉ เจชเจฐเจฟเจญเจพเจธเจผเจพ เจเจพเจฃเจจเจพ เจเจพเจนเฉเฉฐเจฆเฉ เจนเจพเจ, เจคเจพเจ เจชเฉเฉเจนเจจเจพ เจฌเจฟเจนเจคเจฐ เจนเฉ
เจฌเฉฐเจฆ เจฆเจธเจคเจพเจตเฉเจเจผ , เจเจพเจ เจคเฉเจธเฉเจ เจชเฉเฉเจน เจธเจเจฆเฉ เจนเฉเจธเฉฐเจเฉเจฐเจนเจฟ เจฐเฉเจธเฉ เจตเจฟเฉฑเจ เจนเฉเจฌเจฐเฉ 'เจคเฉ, เจเจฟเฉฑเจฅเฉ เจนเจฐ เจเฉเจเจผ เจฌเจฟเจฒเจเฉเจฒ เจธเจนเฉ เจฐเฉเจช เจตเจฟเฉฑเจ เจชเฉเจฐเจคเฉเจฌเจฟเฉฐเจฌเจฟเจค เจนเฉเฉฐเจฆเฉ เจนเฉ :) -
เจ เฉฐเจฆเจฐเฉเจจเฉ เจชเฉเจฐเจพเจฎเฉเจเจฐ , faust doc เจตเจฟเฉฑเจ เจฌเจนเฉเจค เจตเจงเฉเจ เจขเฉฐเจ เจจเจพเจฒ เจตเจฐเจฃเจจ เจเฉเจคเจพ เจเจฟเจ เจนเฉ, เจธเจพเจจเฉเฉฐ เจเฉเจก เจตเจฟเฉฑเจ เจธเจฟเฉฑเจงเฉ เจตเจฟเจธเจผเฉ เจจเฉเฉฐ เจเฉเจเจซเจฟเจเจฐ เจเจฐเจจ เจฆเฉ เจเจเจพเจเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉ, เจฌเฉเจธเจผเจ, เจเจธเจฆเจพ เจฎเจคเจฒเจฌ เจนเฉ เจซเฉเจธเจ เจกเจฟเจตเฉเจฒเจชเจฐเจพเจ เจฆเฉเจเจฐเจพ เจชเฉเจฐเจฆเจพเจจ เจเฉเจคเฉ เจเจ เจฎเจพเจชเจฆเฉฐเจก, เจเจฆเจพเจนเจฐเจจ เจฒเจ: เจงเจพเจฐเจจ, เจงเจพเจฐเจจ เจจเฉเจคเฉ (เจกเจฟเจซเฉเจฒเจ เจฎเจฟเจเจพเจ, เจชเจฐ เจคเฉเจธเฉเจ เจธเฉเฉฑเจ เจเจฐ เจธเจเจฆเฉ เจนเฉเจธเฉฐเจเฉเจช เจชเฉเจฐเจคเฉ เจตเจฟเจธเจผเจพ เจญเจพเจเจพเจ เจฆเฉ เจเจฟเจฃเจคเฉ (เจญเจพเจ เจเจฐเจจ เจฒเจ, เจเจฆเจพเจนเจฐเจจ เจฒเจ, เจเฉฑเจเจเจฒเฉเจฌเจฒ เจฎเจนเฉฑเจคเจคเจพ เจเจชเจฒเฉเจเฉเจธเจผเจจ 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
PS เจตเจฟเจธเจผเฉเจธเจผเจคเจพเจตเจพเจ
เจธเจพเจกเฉ เจฒเจพเจเจ เจเจฎเจพเจเจก เจตเจฟเฉฑเจ, เจ เจธเฉเจ เจเจพเจฃเจเจพเจฐเฉ เจฒเฉเจ เจเจเจเจชเฉเฉฑเจ เจชเฉฑเจงเจฐ เจฆเฉ เจจเจพเจฒ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจเจฌเจเฉเจเจ เจจเฉเฉฐ เจเจฟเฉฑเจฅเฉ เจฒเฉฑเจญเจฃเจพ เจนเฉ เจ เจคเฉ เจเจธ เจจเจพเจฒ เจเฉ เจเจฐเจจเจพ เจนเฉ (เจเฉฑเจ เจตเจฐเจเจฐ เจจเฉเฉฐ เจธเจผเฉเจฐเฉ เจเจฐเจจเจพ เจนเฉ) เจฌเจพเจฐเฉ เจฆเฉฑเจธเจฟเจ เจนเฉเฅค เจธเจพเจจเฉเฉฐ เจนเฉเจ เจฆเจฟเฉฑเจคเฉ เจเจเจเจชเฉเฉฑเจ เจฎเจฟเจฒเจฆเฉ เจนเฉ:
เจธเจชเฉเจเจฒเจฐ
โฦ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:
...
เจเจฟเจเจเจเจฟ เจเจน เจเจเฉฐเจ เจเฉฑเจ เจเจพเจธ เจธเฉเจฐเฉฑเจเจฟเจ เจฌเจพเจฐเฉ เจเจพเจฃเจเจพเจฐเฉ เจฆเฉ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจเจฐเฉเจเจพ, เจธเจพเจจเฉเฉฐ เจธเฉฐเจฆเฉเจธเจผ เจตเจฟเฉฑเจ เจเจธ เจธเฉเจฐเฉฑเจเจฟเจ เจฆเฉ เจเจฟเจเจฐ (เจชเฉเจฐเจคเฉเจ) เจจเฉเฉฐ เจฆเจฐเจธเจพเจเจฃ เจฆเฉ เจฒเฉเฉ เจนเฉเฅค faust เจตเจฟเฉฑเจ เจเจธ เจฎเจเจธเจฆ เจฒเจ เจนเจจ
เจเจธ เจฎเจพเจฎเจฒเฉ เจตเจฟเฉฑเจ, เจเจ เจเจพเจฃเฉเจ
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 เจเฉเฉฐเจเฉ เจจเฉเฉฐ เจจเจฟเจฐเจงเจพเจฐเจค เจเฉเจคเจพ เจเจพเจเจฆเจพ เจนเฉ
เจตเจฟเจ เจเจฒเจพเจจเฉ เจเจเฉฐเจเจพเจ เจคเฉเจ เจฌเจพเจ
เจฆ
@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
เจ เฉฑเจเฉ เจเฉ เจนเฉเจตเฉเจเจพ?
เจ เจเจฒเฉ เจนเจฟเฉฑเจธเฉ เจตเจฟเฉฑเจ, เจเฉฑเจ เจเจฆเจพเจนเจฐเจจ เจฆเฉ เจคเฉเจฐ 'เจคเฉ เจฌเจพเจเฉ เจฌเจเฉ เจเจเฉฐเจเจพเจ เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจนเฉเจ, เจ เจธเฉเจ เจธเจพเจฒ เจฒเจ เจตเจชเจพเจฐ เจฆเฉเจเจ เจธเจฎเจพเจชเจคเฉ เจเฉเจฎเจคเจพเจ เจ เจคเฉ เจเจเฉฐเจเจพเจ เจฆเฉ เจเจฐเฉเจจ เจฒเจพเจเจ เจตเจฟเฉฑเจ เจ เจคเจฟเจ เฉฐเจคเจคเจพ เจฆเฉ เจเฉเจ เจฒเจ เจธเจฟเฉฐเจ เจตเจฟเจงเฉ เจจเฉเฉฐ เจฆเฉเจเจพเจเจเฉเฅค
เจเจน เจธเจญ เจ เฉฑเจ เจฒเจ เจนเฉ! เจชเฉเฉเจนเจจ เจฒเจ เจงเฉฐเจจเจตเจพเจฆ :)
PS เจชเจฟเจเจฒเฉ เจญเจพเจ เจฆเฉ เจคเจนเจฟเจค เจฎเฉเจจเฉเฉฐ เจซเฉเจธเจ เจ
เจคเฉ เจเฉฐเจซเจฒเฉเจเจเจ เจเจพเจซเจเจพ เจฌเจพเจฐเฉ เจชเฉเฉฑเจเจฟเจ เจเจฟเจ เจธเฉ (
เจธเจฐเฉเจค: www.habr.com