name: Qualitative Sell Strategy (Read-Only, SQLite Canonical) on: schedule: - cron: "0 10 * * 1-5" # KST 19:00-ish daily post-close batch window (UTC 10:00) workflow_dispatch: jobs: evaluate-qualitative-sell: runs-on: self-hosted steps: - name: Checkout Code run: | if [ -d .git ]; then git remote set-url origin http://x-access-token:${{ secrets.GITHUB_TOKEN }}@192.168.123.100:8418/KimJaeHyun/myfinance.git else git init git remote add origin http://x-access-token:${{ secrets.GITHUB_TOKEN }}@192.168.123.100:8418/KimJaeHyun/myfinance.git fi TARGET_REF="${GITHUB_REF_NAME:-main}" git fetch origin "$TARGET_REF" --depth=1 git reset --hard FETCH_HEAD - name: Prepare Raw Seed Snapshot run: | if [ -f GatherTradingData.json ]; then echo "GatherTradingData.json present" exit 0 fi if [ -f GatherTradingData.xlsx ]; then echo "GatherTradingData.json missing; regenerating from GatherTradingData.xlsx" python3 tools/convert_xlsx_to_json.py \ --xlsx GatherTradingData.xlsx \ --out GatherTradingData.json if [ -f GatherTradingData.json ]; then echo "GatherTradingData.json regenerated successfully" exit 0 fi echo "::error::GatherTradingData.xlsx is present but JSON regeneration failed." echo "::error::Check tools/convert_xlsx_to_json.py and workbook sheet integrity." exit 1 fi if [ -f .clasprc.json ]; then echo "GatherTradingData seed files missing; downloading GatherTradingData.xlsx from Google Drive via .clasprc.json" python3 tools/download_trading_data.py if [ -f GatherTradingData.xlsx ]; then echo "GatherTradingData.xlsx downloaded successfully; regenerating GatherTradingData.json" python3 tools/convert_xlsx_to_json.py \ --xlsx GatherTradingData.xlsx \ --out GatherTradingData.json if [ -f GatherTradingData.json ]; then echo "GatherTradingData.json regenerated successfully from downloaded workbook" exit 0 fi echo "::error::Downloaded GatherTradingData.xlsx but JSON regeneration failed." echo "::error::Check workbook integrity and tools/convert_xlsx_to_json.py." exit 1 fi echo "::error::.clasprc.json exists but GatherTradingData.xlsx was not downloaded." echo "::error::Check Google Drive access and tools/download_trading_data.py." exit 1 fi echo "::error::Neither GatherTradingData.json nor GatherTradingData.xlsx exists in the checked-out tree." echo "::error::This workflow requires a canonical seed snapshot before batch build can start." echo "::error::Fix options:" echo "::error:: 1) Commit GatherTradingData.json to the repository tree." echo "::error:: 2) Commit GatherTradingData.xlsx so the workflow can regenerate the JSON." echo "::error:: 3) Provide .clasprc.json so the workflow can download GatherTradingData.xlsx from Google Drive and regenerate the JSON." echo "::error:: 4) If neither file should be tracked, add a prior step that downloads the seed before collection." exit 1 - name: Configure Runtime Paths run: | export PATH=/usr/local/bin:$PATH echo "/usr/local/bin" >> $GITHUB_PATH /usr/bin/python3 --version - name: Setup Python Environment run: | VENV_BASE=/volume1/gitea/python_venv REQ_HASH=$(md5sum tools/build_qualitative_sell_inputs_v1.py 2>/dev/null | cut -d' ' -f1 || echo "qual-default") VENV="$VENV_BASE/$REQ_HASH" if [ ! -f "$VENV/bin/python" ]; then mkdir -p "$VENV_BASE" /usr/bin/python3 -m venv "$VENV" "$VENV/bin/pip" install --upgrade pip --quiet "$VENV/bin/pip" install requests beautifulsoup4 pyyaml openpyxl --quiet fi "$VENV/bin/pip" install requests beautifulsoup4 pyyaml openpyxl --quiet echo "$VENV/bin" >> $GITHUB_PATH - name: "[CRITICAL] No Direct API Trading Gate" run: python3 tools/validate_no_direct_api_trading_v1.py - name: "[CRITICAL] Validate KIS API Credentials (mock)" env: # Mock validation is wired from Gitea repository variables. KIS_APP_Key_TEST: ${{ vars.KIS_APP_KEY_TEST }} KIS_APP_Secret_TEST: ${{ vars.KIS_APP_SECRET_TEST }} run: | if [ -z "${KIS_APP_Key_TEST:-}" ]; then echo "::error::Gitea variable KIS_APP_KEY_TEST is missing or empty" exit 1 fi if [ -z "${KIS_APP_Secret_TEST:-}" ]; then echo "::error::Gitea variable KIS_APP_SECRET_TEST is missing or empty" exit 1 fi python3 tools/validate_kis_api_credentials_v1.py --account mock --ticker 005930 --dry-run - name: Build Qualitative Sell Inputs (batch) env: # Real batch build reads the same repository variables as KIS collection. KIS_APP_Key: ${{ vars.KIS_APP_KEY }} KIS_APP_Secret: ${{ vars.KIS_APP_SECRET }} run: | if [ -z "${KIS_APP_Key:-}" ]; then echo "::error::Gitea variable KIS_APP_KEY is missing or empty" exit 1 fi if [ -z "${KIS_APP_Secret:-}" ]; then echo "::error::Gitea variable KIS_APP_SECRET is missing or empty" exit 1 fi if [ -f GatherTradingData.xlsx ]; then python3 tools/build_qualitative_sell_inputs_v1.py \ --batch \ --workbook GatherTradingData.xlsx \ --kis-account real \ --apply else echo "GatherTradingData.xlsx missing -> skip batch build" fi - name: Build Satellite Recommendations run: | if [ -f GatherTradingData.xlsx ]; then python3 tools/build_satellite_candidate_recommendations_v1.py \ --workbook GatherTradingData.xlsx \ --apply else echo "GatherTradingData.xlsx missing -> skip satellite build" fi - name: Evaluate Qualitative Sell Accuracy run: | if [ -f outputs/qualitative_sell_strategy/qualitative_sell_strategy.db ]; then python3 tools/evaluate_qualitative_sell_strategy_accuracy_v1.py \ --sqlite-db outputs/qualitative_sell_strategy/qualitative_sell_strategy.db else echo "qualitative_sell_strategy.db missing -> skip accuracy evaluation" fi