diff --git a/.github/workflows/rebalance.yml b/.github/workflows/rebalance.yml new file mode 100644 index 0000000..cbe2858 --- /dev/null +++ b/.github/workflows/rebalance.yml @@ -0,0 +1,29 @@ +name: Weekly Portfolio Rebalance + +on: + # 1. Запуск по расписанию (каждый понедельник в 10:30 МСК) + schedule: + - cron: '30 7 * * 1' # Время в UTC (7:30 UTC = 10:30 МСК) + + # 2. Возможность запустить вручную кнопкой в интерфейсе GitHub + workflow_dispatch: + +jobs: + rebalance: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v3 + + - name: Set up Python + run: uv python install 3.13 + + - name: Run Rebalance Bot + env: + # Передаем секреты в переменные окружения скрипта + TINVEST_TOKEN: ${{ secrets.TINVEST_TOKEN }} + run: uv run main.py # Замени на имя своего главного файла \ No newline at end of file diff --git a/app/config.py b/app/config.py index f454de6..6d37dfa 100644 --- a/app/config.py +++ b/app/config.py @@ -17,4 +17,4 @@ TARGET_WEIGHTS = { "ROSN": Decimal("0.05"), } -CORRIDOR = Decimal("0.02") # 3% коридор отклонения от целевой доли +CORRIDOR = Decimal("0.02") # 2% коридор отклонения от целевой доли diff --git a/app/load_config.py b/app/load_config.py new file mode 100644 index 0000000..cc9610a --- /dev/null +++ b/app/load_config.py @@ -0,0 +1,21 @@ +import yaml +from decimal import Decimal + + +def load_config(config_path: str) -> dict: + with open(config_path, "r") as file: + data = yaml.safe_load(file) + + target_weights = { + ticker: Decimal(str(weight)) for ticker, weight in data["portfolio"].items + } + + config = { + "account_id": data["account"]["id"], + "is_sandbox": data["account"]["is_sandbox"], + "corridor": Decimal(str(data["settings"]["corridor"])), + "dry_run": data["settings"]["dry_run"], + "target_weights": target_weights, + } + + return config diff --git a/app/main.py b/app/main.py index aa40693..34288df 100644 --- a/app/main.py +++ b/app/main.py @@ -10,10 +10,10 @@ load_dotenv() def main(): - with SandboxClient(token=os.getenv("TINVEST_TOKEN")) as client: # type: ignore + with Client(token=os.getenv("TINVEST_TOKEN")) as client: # type: ignore bot = RebalanceBot( client=client, - account_id="bb29bb79-8cf1-42ba-843f-47ef76c5b7c0", + account_id="2235046505", target_weights=TARGET_WEIGHTS, corridor=CORRIDOR, dry_run=True, @@ -30,3 +30,5 @@ def main(): if __name__ == "__main__": main() + # with Client(token=os.getenv("TINVEST_TOKEN")) as client: + # print(client.users.get_accounts()) diff --git a/app/rebalance.py b/app/rebalance.py index f3d8fdd..f52315b 100644 --- a/app/rebalance.py +++ b/app/rebalance.py @@ -71,6 +71,7 @@ class RebalanceBot: if lots != 0: plan.append( { + "figi": pos.figi, "ticker": ticker, "uid": uid, "action": "BUY" if lots > 0 else "SELL",