RAPTOR v18.4: Исправлена отчетность, активированы выходные
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
"""
|
||||
This code is an example of applying Trading Strategy for several Tickers.
|
||||
The strategy in this code is for demonstration only purposes
|
||||
- it outputs OHLCV values.
|
||||
Author: Oleg Shpagin, my github: https://github.com/WISEPLAT
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from datetime import timedelta
|
||||
from typing import List, Optional
|
||||
|
||||
from t_tech.invest import AioRequestError, AsyncClient, CandleInterval, HistoricCandle
|
||||
from t_tech.invest.async_services import AsyncServices
|
||||
from t_tech.invest.utils import now
|
||||
|
||||
TOKEN = os.environ["INVEST_TOKEN"]
|
||||
|
||||
logging.basicConfig(format="%(asctime)s %(levelname)s:%(message)s", level=logging.DEBUG)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LogOnlyCandlesStrategy:
|
||||
"""This class is responsible for a strategy. You can put here
|
||||
your methods for your strategy."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
figi: str,
|
||||
timeframe: CandleInterval,
|
||||
days_back: int,
|
||||
check_interval: int,
|
||||
client: Optional[AsyncServices],
|
||||
):
|
||||
self.account_id = None
|
||||
self.figi = figi
|
||||
self.timeframe = timeframe
|
||||
self.days_back = days_back
|
||||
self.check_interval = check_interval
|
||||
self.client = client
|
||||
self.candles: List[HistoricCandle] = []
|
||||
|
||||
async def get_historical_data(self):
|
||||
"""
|
||||
Gets historical data for the instrument. Returns list of candles.
|
||||
Requests all the candles of timeframe from days_back to now.
|
||||
|
||||
:return: list of HistoricCandle
|
||||
"""
|
||||
logger.debug(
|
||||
"Start getting historical data for %s days back from now. figi=%s",
|
||||
self.days_back,
|
||||
self.figi,
|
||||
)
|
||||
async for candle in self.client.get_all_candles(
|
||||
figi=self.figi,
|
||||
from_=now() - timedelta(days=self.days_back),
|
||||
to=now(),
|
||||
interval=self.timeframe,
|
||||
):
|
||||
if candle not in self.candles:
|
||||
if candle.is_complete:
|
||||
self.candles.append(candle)
|
||||
logger.debug("Found %s - figi=%s", candle, self.figi)
|
||||
|
||||
async def ensure_market_open(self):
|
||||
"""
|
||||
Ensure that the market is open. Loop until the instrument is available.
|
||||
:return: when instrument is available for trading
|
||||
"""
|
||||
trading_status = await self.client.market_data.get_trading_status(
|
||||
figi=self.figi
|
||||
)
|
||||
while not (
|
||||
trading_status.market_order_available_flag
|
||||
and trading_status.api_trade_available_flag
|
||||
):
|
||||
logger.debug("Waiting for the market to open. figi=%s", self.figi)
|
||||
await asyncio.sleep(60)
|
||||
trading_status = await self.client.market_data.get_trading_status(
|
||||
figi=self.figi
|
||||
)
|
||||
|
||||
async def main_cycle(self):
|
||||
"""Main cycle for live strategy."""
|
||||
while True:
|
||||
try:
|
||||
await self.ensure_market_open()
|
||||
await self.get_historical_data()
|
||||
|
||||
# put your strategy code here for live
|
||||
# to generate signals for buying or selling tickers
|
||||
logger.debug(
|
||||
"- live mode: run some strategy code to buy or sell - figi=%s",
|
||||
self.figi,
|
||||
)
|
||||
|
||||
except AioRequestError as are:
|
||||
logger.error("Client error %s", are)
|
||||
|
||||
await asyncio.sleep(self.check_interval)
|
||||
|
||||
async def start(self):
|
||||
"""Strategy starts from this function."""
|
||||
if self.account_id is None:
|
||||
try:
|
||||
self.account_id = (
|
||||
(await self.client.users.get_accounts()).accounts.pop().id
|
||||
)
|
||||
except AioRequestError as are:
|
||||
logger.error("Error taking account id. Stopping strategy. %s", are)
|
||||
return
|
||||
await self.main_cycle()
|
||||
|
||||
|
||||
async def run_strategy(portfolio, timeframe, days_back, check_interval):
|
||||
"""From this function we are starting
|
||||
strategy for every ticker from portfolio.
|
||||
"""
|
||||
async with AsyncClient(token=TOKEN, app_name="TinkoffApp") as client:
|
||||
strategy_tasks = []
|
||||
for instrument in portfolio:
|
||||
strategy = LogOnlyCandlesStrategy(
|
||||
figi=instrument,
|
||||
timeframe=timeframe,
|
||||
days_back=days_back,
|
||||
check_interval=check_interval,
|
||||
client=client,
|
||||
)
|
||||
strategy_tasks.append(asyncio.create_task(strategy.start()))
|
||||
await asyncio.gather(*strategy_tasks)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sber_figi = "BBG004730N88"
|
||||
vtbr_figi = "BBG004730ZJ9"
|
||||
portfolio = {sber_figi, vtbr_figi}
|
||||
timeframe = CandleInterval.CANDLE_INTERVAL_1_MIN
|
||||
days_back = 1
|
||||
check_interval = 10 # seconds to check interval for new completed candle
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
task = loop.create_task(
|
||||
run_strategy(
|
||||
portfolio=portfolio,
|
||||
timeframe=timeframe,
|
||||
days_back=days_back,
|
||||
check_interval=check_interval,
|
||||
)
|
||||
)
|
||||
loop.run_until_complete(task)
|
||||
Reference in New Issue
Block a user