avatar of ianzeng123 ianzeng123
집중하다 사신
2
집중하다
319
수행원

기존 전략을 더욱 스마트하게 만들기: 워크플로우와 AI를 활용한 실용적인 게임플레이

만든 날짜: 2025-10-16 15:04:55, 업데이트 날짜: 2025-10-28 14:09:42
comments   3
hits   361

기존 전략을 더욱 스마트하게 만들기: 워크플로우와 AI를 활용한 실용적인 게임플레이

오프닝: 워크플로는 무엇을 할 수 있나요?

많은 사람들이 워크플로는 단순한 작업만 자동화할 수 있다고 생각하지만, 생각보다 훨씬 강력합니다. 특히 Inventor Quantitative Platform에서 워크플로는 기존 전략을 실행할 뿐만 아니라 AI를 통해 시장 모니터링, 의사 결정, 전략 실행 과정의 매개변수 조정까지 지원할 수 있습니다.

간단히 말해서:기존 전략은 업무를 담당하는 반면 AI는 사고를 담당합니다.

오늘은 실제 사례를 통해 두 가지를 결합하여 더욱 스마트한 전략을 만드는 방법에 대해 알아보겠습니다.


1. 먼저 기존 전략의 문제점에 대해 이야기해 보겠습니다.

우리는 가장 일반적인 것을 사용합니다양방향 그리드 거래 전략예를 하나 들어보겠습니다.

양방향 그리드 전략이란 무엇입니까?

이는 롱 포지션과 숏 포지션을 동시에 거래하는 그리드 전략입니다.

  • 다중 창고 그리드: 가격이 하락하면 일괄적으로 롱 포지션을 오픈하고, 가격이 다시 상승하면 롱 포지션을 닫아 수익을 냅니다.
  • 빈 창고 그리드: 가격이 상승하면 일괄적으로 단기 포지션을 열고, 가격이 하락하면 단기 포지션을 닫아 수익을 냅니다.
  • 가격 변동에 관계없이 가격 변동을 통해 차액을 벌 수 있습니다.

이 전략은 변동성이 큰 시장에서 안정적인 수익을 가져다주지만 치명적인 문제가 있습니다.매개변수는 고정되어 있습니다

기존 전략을 더욱 스마트하게 만들기: 워크플로우와 AI를 활용한 실용적인 게임플레이

예를 들어

양방향 그리드의 경우 BTC 가격을 40,000달러로 설정하고 단계 크기를 1%, 최대 5단계로 설정한다고 가정해 보겠습니다.

롱 포지션 그리드(가격 하락 범위)

  • 39600 1단계 구매
  • 39200 2단계 구매
  • 38800 3단계 구매
  • 38400 4층 구매
  • 38000 5단계 구매 (풀 포지션)

숏 포지션 그리드(가격 상승 범위)

  • 40400 1단 기어를 엽니다
  • 40800 2단 기어를 엽니다
  • 41200 오픈 3단 기어
  • 41600 오픈 4단 기어
  • 42000 오픈 숏 포지션 5 (풀 포지션)

문제는 여기에 있습니다

만약 BTC가 갑자기 35,000까지 폭락한다면?

  • 5개의 롱 포지션이 모두 오픈되었고, 가격은 계속 하락하고 있습니다.
  • 모든 포지션이 깊이 빠져 있으며, 플로팅 손실은 계속 확대되고 있습니다.
  • 초기가격 40000이 고정되어 있어 그리드 자동조정이 불가능합니다.
  • 가격이 그리드 범위로 돌아오는 데는 오랜 시간이 걸릴 수 있습니다.

아니면 반대로, BTC가 45,000까지 치솟는다면 어떨까요?

  • 5개의 공매도 포지션이 모두 오픈되어 있고, 가격은 계속 상승하고 있습니다.
  • 공매도 포지션은 계속 돈을 잃고 있지만 그리드는 따라잡을 수 없습니다.
  • 전통적인 전략은 기다릴 뿐이고 아무것도 이룰 수 없습니다.

이것이 기존 전략의 한계입니다. 시장 변화에 대해 사전에 생각하지 않습니다.

그렇다면 전략을 더욱 스마트하게 만들 방법이 있을까요? 정답은 워크플로를 사용하여 기존 전략과 AI를 결합하는 것입니다. Inventor 플랫폼의 워크플로를 통해 AI가 중요한 순간에 개입하여 전략을 조정하는 방법을 살펴보겠습니다.


2. 전체 워크플로 아키텍처

기존 전략을 더욱 스마트하게 만들기: 워크플로우와 AI를 활용한 실용적인 게임플레이

노드 흐름도

┌─────────────────────┐
│  K线收盘触发器       │  ← 每60秒触发一次
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│   参数初始化节点      │  ← 首次运行或重置后:初始化网格
│                     │    (包含波动率检查)
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│  网格策略源码节点     │  ← 执行开平仓逻辑
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│   触发判断节点       │  ← 监控持仓+判断是否触发AI
│                     │    (冷却期)
└──────────┬──────────┘
           ↓
┌─────────────────────┐
│    分支判断节点      │  ← 根据触发条件分流
└────┬─────────┬──────┘
     │         │
  false       true
     │         │
     ↓         ↓
┌────────┐  ┌─────────────────────┐
│无操作  │  │ 情绪新闻获取(MCP)    │  ← Alpha Vantage API
└────────┘  └──────────┬──────────┘
                       ↓
            ┌─────────────────────┐
            │   结果整理节点       │  ← 整合新闻+持仓数据
            └──────────┬──────────┘
                       ↓
            ┌─────────────────────┐
            │  AI参数分析节点      │  ← 情感分析节点判断Yes/No
            │  (Sentiment)        │    
            └────┬─────────┬──────┘
                 │         │
               Yes        No
                 │         │
                 ↓         ↓
        ┌────────────┐  ┌────────┐
        │ 重置策略   │  │AI冷却  │  ← 记录lastAItime
        │ ·平掉所有仓│  └────────┘
        │ ·清除grid  │
        │ ·清除price │
        │ ·记录时间  │
        └────────────┘
                 │
                 ↓
        (下个周期重新初始化)

전역 변수 구성

시작하기 전에 n8n 워크플로에서 다음 변수를 구성해야 합니다.

$vars.contract = "BTC_USDT.swap"  // 交易对
$vars.maxPositions = 5             // 最大档位数
$vars.stepPercent = 0.01           // 网格步长(1%)
$vars.lotSize = 0.001              // 每手交易量

3. 각 노드의 상세 코드

노드 1: K-라인 클로징 트리거

노드 이름: K-라인 클로징 트리거 1
노드 유형: klineCloseTrigger

기능 설명

  • 이는 전체 워크플로의 핵심이며 60초마다 자동으로 실행됩니다.
  • 트리거되면 최신 500 K-라인 데이터가 추출됩니다.
  • 트리거 후 프로세스는 자동으로 다음 노드로 들어갑니다.

노드 2: 매개변수 초기화

노드 이름: 매개변수 초기화
노드 유형: Code

전체 코드

let grid = _G('grid');
let initPrice = _G('initPrice');
let initEquity = _G('initEquity');

// ========== 从 n8n 变量读取配置参数 ==========
let maxPositions = $vars.maxPositions;      // 最大档位数
let stepPercent = $vars.stepPercent;        // 网格步长
let volatilityThreshold = 0.02; // 波动率阈值(默认2%)
let volatilityPeriod = 20; // 波动率计算周期(默认20根K线)

// ========== 波动率检查函数 ==========
function checkVolatility() {
  // 获取历史K线数据
  let records = exchange.GetRecords();
  if (!records || records.length < volatilityPeriod) {
    Log('K线数据不足,无法计算波动率');
    return { isHigh: false, value: 0 };
  }
  
  // 计算最近N根K线的价格波动率
  let prices = [];
  for (let i = records.length - volatilityPeriod; i < records.length; i++) {
    prices.push(records[i].Close);
  }
  
  // 计算平均价格
  let avgPrice = prices.reduce((a, b) => a + b, 0) / prices.length;
  
  // 计算标准差
  let squareDiffs = prices.map(price => Math.pow(price - avgPrice, 2));
  let avgSquareDiff = squareDiffs.reduce((a, b) => a + b, 0) / squareDiffs.length;
  let stdDev = Math.sqrt(avgSquareDiff);
  
  // 计算波动率 (标准差/平均价格)
  let volatility = stdDev / avgPrice;
  
  Log('当前波动率:', (volatility * 100).toFixed(2) + '%', 
      '阈值:', (volatilityThreshold * 100).toFixed(2) + '%');
  
  return {
    isHigh: volatility > volatilityThreshold,
    value: volatility
  };
}

// ========== 初始化前先检查波动率 ==========
if (!grid || Object.keys(grid).length === 0) {
  
  // 检查波动率
  let volatilityCheck = checkVolatility();
  
  if (volatilityCheck.isHigh) {
    Log('⚠️ 当前市场波动率过高:', (volatilityCheck.value * 100).toFixed(2) + '%');
    Log('等待市场平稳后再初始化网格...');
    return { 
      status: 'waiting',
      reason: 'high_volatility',
      volatility: volatilityCheck.value
    };
  }
  
  Log('✓ 波动率检查通过,开始初始化网格');
  
  // ========== 获取初始权益 ==========
  if (!initEquity) {
    let equity = exchange.GetAccount();
    if (equity) {
      initEquity = equity.Equity;
      _G('initEquity', initEquity);
      Log('使用当前市场权益作为初始权益:', initEquity);
    } else {
      Log('获取市场账户失败');
      return null;
    }
  }

  // ========== 获取初始价格 ==========
  if (!initPrice) {
    let ticker = exchange.GetTicker();
    if (ticker) {
      initPrice = ticker.Last;
      _G('initPrice', initPrice);
      Log('使用当前市场价格作为初始价格:', initPrice);
    } else {
      Log('获取市场价格失败');
      return null;
    }
  }

  // ========== 初始化网格 ==========
  grid = {
    // ========== 配置参数 ==========
    stepPercent: stepPercent,        // 网格步长
    maxPositions: maxPositions,      // 最大档位数
    
    // ========== 网格数据 ==========
    longOpenPrices: [],    // 目标多仓开仓价格数组
    longClosePrices: [],   // 目标多仓平仓价格数组
    longPositions: [],     // 多仓持仓状态数组
    shortOpenPrices: [],   // 目标空仓开仓价格数组
    shortClosePrices: [],  // 目标空仓平仓价格数组
    shortPositions: []     // 空仓持仓状态数组
  };
  
  // 初始化多仓网格(价格下跌时开多)
  for (let i = 1; i <= maxPositions; i++) {
    grid.longOpenPrices.push(initPrice * (1 - stepPercent * i));
    grid.longClosePrices.push(initPrice * (1 - stepPercent * (i - 1)));
    grid.longPositions.push({
      isOpen: false,
      openTime: null,
      openPrice: null
    });
  }
  
  // 初始化空仓网格(价格上涨时开空)
  for (let i = 1; i <= maxPositions; i++) {
    grid.shortOpenPrices.push(initPrice * (1 + stepPercent * i));
    grid.shortClosePrices.push(initPrice * (1 + stepPercent * (i - 1)));
    grid.shortPositions.push({
      isOpen: false,
      openTime: null,
      openPrice: null
    });
  }
  
  _G('grid', grid);
  Log('========== 网格初始化完成 ==========');
  Log('初始价格:', initPrice);
  Log('初始权益:', initEquity);
  Log('网格步长:', (stepPercent * 100) + '%');
  Log('最大档位:', maxPositions);
  Log('当前波动率:', (volatilityCheck.value * 100).toFixed(2) + '%');
  Log('多仓网格范围:', grid.longOpenPrices[0].toFixed(2), '-', grid.longOpenPrices[maxPositions-1].toFixed(2));
  Log('空仓网格范围:', grid.shortOpenPrices[0].toFixed(2), '-', grid.shortOpenPrices[maxPositions-1].toFixed(2));
  Log('===================================');
} 

return {};

기능 설명

  • 초기화는 재시작 전략이 필요한 경우에만 수행됩니다., 정상적으로 실행 중일 때는 전략이 바로 건너뛰어집니다.
  • 전략 초기화는 안정적인 상태여야 하므로 변동성 검사를 추가하여 심각한 변동성 상태에서 포지션을 오픈하여 추가 손실을 방지합니다.
  • 사용_G()이 기능은 데이터 지속성을 구현하며 재시작 후에도 데이터가 손실되지 않습니다.
  • 초기 자본, 초기 가격, 그리드 구조 등 3가지 핵심 데이터를 초기화합니다.
  • 긴 방향과 짧은 방향 모두에 대한 그리드 가격 배열을 계산합니다.

노드 3: 그리드 전략 소스 코드

노드 이름: 그리드 전략 소스 코드
노드 유형: Code

전체 코드

var lotSize = $vars.lotSize || 0.001; // 每手数量

var grid = _G('grid');
var initPrice = _G('initPrice');

// 策略未初始化,直接退出策略
if (!initPrice || !grid) {
    return {};
} 

// ========== 多仓开仓检查函数 ==========
function checkLongOpen(price) {
    for (var i = 0; i < grid.longOpenPrices.length; i++) {
        // 条件1: 价格低于或等于目标开仓价
        // 条件2: 该档位当前没有持仓
        if (price <= grid.longOpenPrices[i] && !grid.longPositions[i].isOpen) {
            Log('准备开多仓');
            
            // 设置交易方向为买入(做多)
            exchange.SetDirection('buy');
            
            // 下市价单: -1表示市价, lotSize是数量
            var orderId = exchange.Buy(-1, lotSize);
            
            if (orderId) {
                // 记录开仓信息
                grid.longPositions[i] = {
                    isOpen: true,           // 标记为已开仓
                    openTime: Date.now(),   // 记录开仓时间戳
                    openPrice: price        // 记录开仓价格
                };
                
                // 持久化保存
                _G('grid', grid);
                
                Log('✓ 开多 第', i + 1, '档', 
                    '开仓价:', price, 
                    '目标平仓价:', grid.longClosePrices[i]);
            }
        }
    }
}

// ========== 多仓平仓检查函数 ==========
function checkLongClose(price) {
    for (var i = 0; i < grid.longClosePrices.length; i++) {
        // 条件1: 该档位有持仓
        // 条件2: 价格达到或超过目标平仓价
        if (grid.longPositions[i].isOpen && price >= grid.longClosePrices[i]) {
            Log('准备平多仓');
            
            // 设置交易方向为平多
            exchange.SetDirection('closebuy');
            
            // 下市价单平仓
            var orderId = exchange.Sell(-1, lotSize);
            
            if (orderId) {
                // 计算盈利百分比
                var profit = ((price - grid.longPositions[i].openPrice) / 
                             grid.longPositions[i].openPrice * 100).toFixed(2);
                
                Log('✓ 平多 第', i + 1, '档', 
                    '开仓价:', grid.longPositions[i].openPrice, 
                    '平仓价:', price, 
                    '盈利:', profit + '%');
                
                // 清除持仓信息
                grid.longPositions[i] = {
                    isOpen: false,
                    openTime: null,
                    openPrice: null
                };
                
                // 持久化保存
                _G('grid', grid);
            }
        }
    }
}

// ========== 空仓开仓检查函数 ==========
function checkShortOpen(price) {
    for (var i = 0; i < grid.shortOpenPrices.length; i++) {
        // 条件1: 价格高于或等于目标开仓价
        // 条件2: 该档位当前没有持仓
        if (price >= grid.shortOpenPrices[i] && !grid.shortPositions[i].isOpen) {
            Log('准备开空仓');
            
            // 设置交易方向为卖出(做空)
            exchange.SetDirection('sell');
            
            // 下市价单开空
            var orderId = exchange.Sell(-1, lotSize);
            
            if (orderId) {
                // 记录开仓信息
                grid.shortPositions[i] = {
                    isOpen: true,
                    openTime: Date.now(),
                    openPrice: price
                };
                
                _G('grid', grid);
                
                Log('✓ 开空 第', i + 1, '档', 
                    '开仓价:', price, 
                    '目标平仓价:', grid.shortClosePrices[i]);
            }
        }
    }
}

// ========== 空仓平仓检查函数 ==========
function checkShortClose(price) {
    for (var i = 0; i < grid.shortClosePrices.length; i++) {
        // 条件1: 该档位有持仓
        // 条件2: 价格达到或低于目标平仓价
        if (grid.shortPositions[i].isOpen && price <= grid.shortClosePrices[i]) {
            Log('准备平空仓');
            
            // 设置交易方向为平空
            exchange.SetDirection('closesell');
            
            // 下市价单平仓
            var orderId = exchange.Buy(-1, lotSize);
            
            if (orderId) {
                // 计算盈利百分比(空单盈利 = 开仓价 - 平仓价)
                var profit = ((grid.shortPositions[i].openPrice - price) / 
                             grid.shortPositions[i].openPrice * 100).toFixed(2);
                
                Log('✓ 平空 第', i + 1, '档', 
                    '开仓价:', grid.shortPositions[i].openPrice, 
                    '平仓价:', price, 
                    '盈利:', profit + '%');
                
                // 清除持仓信息
                grid.shortPositions[i] = {
                    isOpen: false,
                    openTime: null,
                    openPrice: null
                };
                
                _G('grid', grid);
            }
        }
    }
}

// ========== 主逻辑 ==========
// 获取当前市场价格
var ticker = exchange.GetTicker();
if (!ticker) {
    Log('获取ticker失败');
    return {};
}

var price = ticker.Last;

// 依次检查多空开平
checkLongOpen(price);      // 检查是否需要开多
checkLongClose(price);     // 检查是否需要平多
checkShortOpen(price);     // 检查是否需要开空
checkShortClose(price);    // 检查是否需要平空

return {};

기능 설명

  • 4개의 독립적인 함수가 각각 긴 개방 논리와 짧은 개방 논리를 처리합니다.
  • 조건이 트리거되는지 확인하기 위해 실행될 때마다 모든 그리드 위치를 탐색합니다.
  • 거래를 보장하려면 시장 주문(-1)을 사용하세요.
  • 상태 변경 사항을 즉시 유지합니다.

트랜잭션 로직 예제

场景1: 价格从40000跌到39500
→ checkLongOpen检测到 price(39500) <= longOpenPrices[0](39600)
→ 开多第1档,记录开仓价39500
→ 等待价格回升到40000平仓

场景2: 价格从39500回升到40100
→ checkLongClose检测到 price(40100) >= longClosePrices[0](40000)
→ 平多第1档,盈利 (40100-39500)/39500 = 1.52%

노드 4: 판단을 유발합니다

노드 이름: 트리거 판단 노드 유형: Code

전체 코드

// ========== 触发判断节点 ==========
var grid = _G('grid');
var ticker = exchange.GetTicker();
var curaccount = exchange.GetAccount();
var initPrice = _G('initPrice');
var initEquity = _G('initEquity');

if (!ticker || !grid || !initPrice || !curaccount || !initEquity) {
    return {};
}

let curProfit = curaccount.Equity - initEquity;
LogProfit(curProfit, "&");

var currentPrice = ticker.Last;
var now = Date.now();
var maxPositions = grid.maxPositions || 5;

// 统计开仓数量和总浮动盈亏
var openCount = 0;
var lastOpenPosition = null;
var totalProfit = 0;
var longCount = 0;
var shortCount = 0;

// 统计多仓
for (var i = 0; i < grid.longPositions.length; i++) {
    if (grid.longPositions[i].isOpen) {
        openCount++;
        longCount++;
        lastOpenPosition = grid.longPositions[i];
        var posProfit = ((currentPrice - grid.longPositions[i].openPrice) / grid.longPositions[i].openPrice) * 100;
        totalProfit += posProfit;
    }
}

// 统计空仓
for (var i = 0; i < grid.shortPositions.length; i++) {
    if (grid.shortPositions[i].isOpen) {
        openCount++;
        shortCount++;
        lastOpenPosition = grid.shortPositions[i];
        var posProfit = ((grid.shortPositions[i].openPrice - currentPrice) / grid.shortPositions[i].openPrice) * 100;
        totalProfit += posProfit;
    }
}

// 构建持仓表格
var table = {
    type: "table",
    title: "双向网格持仓",
    cols: ["初始价", "当前价", "网格步长", "多仓数", "空仓数", "总持仓", "初始权益", "当前权益", "累计盈亏", "浮动盈亏%"],
    rows: [[
        _N(initPrice, 2),
        _N(currentPrice, 2),
        _N(grid.stepPercent * 100, 2) + '%',
        longCount,
        shortCount,
        openCount + '/' + maxPositions,
        _N(initEquity, 2),
        _N(curaccount.Equity, 2),
        _N(curProfit, 2),
        _N(totalProfit, 2) + '%'
    ]]
};

LogStatus("`" + JSON.stringify(table) + "`");

// 不是满仓不触发AI
if (openCount < maxPositions) {
    return { aiTrigger: { shouldTrigger: false } };
}

// 检查AI冷却时间
var lastAItime = _G('lastAItime');
if (lastAItime && (now - lastAItime) < 600000) {
    Log('AI冷却中,剩余', ((600000 - (now - lastAItime)) / 60000).toFixed(1), '分钟');
    return { aiTrigger: { shouldTrigger: false } };
}

// 满仓时计算条件
var holdHours = (now - lastOpenPosition.openTime) / 3600000;
var priceDeviation = Math.abs(currentPrice / lastOpenPosition.openPrice - 1);

// 价格偏离>3% 或 持仓>24小时
var shouldTriggerAI = priceDeviation > 0.03 || holdHours >= 24;

if (shouldTriggerAI) {
    Log('触发AI分析 偏离:', (priceDeviation * 100).toFixed(2) + '% 时长:', holdHours.toFixed(1), '小时');
}

return {
    aiTrigger: {
        shouldTrigger: shouldTriggerAI
    }
};

기능 설명

  • 모든 위치 상태의 실시간 모니터링
  • 다양한 핵심 지표 계산: 포지션 수, 변동 손익, 보유 기간, 가격 편차
  • 상태 표시줄에 시각적 표 표시
  • 핵심 판단 논리:AI 냉각 시간에 도달하면 AI는 창고가 가득 찼을 때 + 이상이 있을 때만 트리거됩니다.

트리거 조건에 대한 자세한 설명

AI冷却:
满足AI冷却时间,进行AI触发;

条件组合:
满仓(openCount >= 5) 
  AND 
  (
    价格偏离>3%  OR  持仓时长>24小时
  )

实际案例:
场景1: 开仓3个 → 不触发(未满仓)
场景2: 开仓5个,持仓12小时,偏离1.5% → 不触发(未达阈值)
场景3: 开仓5个,持仓30小时,偏离1% → 触发(持仓过久)
场景4: 开仓5个,持仓5小时,偏离5% → 触发(价格偏离大)

노드 5: 지점 판단

노드 이름: 나뭇가지
노드 유형: Switch

기능 설명

  • 이전 노드 반환에 따르면aiTrigger.shouldTrigger가치 전환
  • 지점 1(거짓): “작업 없음” 노드로 진입하면 현재 사이클이 종료되어 AI 호출 비용이 절감됩니다.
  • 브랜치 2(참): “감성 뉴스 수집” 노드에 진입하여 AI 분석 프로세스를 시작합니다.

이 노드는비용 관리의 핵심AI가 정말 필요할 때만 호출되도록 보장합니다.


노드 6: 감성 뉴스 인수

노드 이름: 센티먼트 뉴스 인수
노드 유형: MCP Client

기능 설명

  • Alpha Vantage의 NEWS_SENTIMENT 도구 호출
  • 지난 24시간 동안 지정된 거래 쌍에 대한 50개의 뉴스를 받아보세요.
  • 각 뉴스 항목에 대한 감정 점수가 포함되어 있습니다.

도구 구성

工具: NEWS_SENTIMENT
参数:
- tickers: CRYPTO:{{$vars.contract}}  // 从变量读取交易对
- 使用默认配置: 返回最多50条新闻,时间范围由API自动确定

노드 7: 결과 정리

노드 이름: 결과
노드 유형: Code

전체 코드

// n8n 的正确语法
const inputData = $input.all();
const sentimentData = inputData[0].json;  // 获取新闻情绪数据

// 从特定节点获取持仓数据
const positionNode = $node["触发判断"].json;

// 返回整合后的数据
return {
  timestamp: new Date().toISOString(),
  
  // 原始新闻数据
  sentimentData: sentimentData,
  
  // 持仓状态数据
  positions: positionNode
};

기능 설명

  • 두 가지 데이터 소스 통합: 뉴스 감정 + 위치 상태
  • AI 분석 노드를 위한 완전한 입력 데이터 준비
  • 추적을 쉽게 하기 위해 타임스탬프를 추가하세요

노드 8: AI 매개변수 분석

노드 이름: AI 매개변수 분석
노드 유형: 감정 분석

기존 전략을 더욱 스마트하게 만들기: 워크플로우와 AI를 활용한 실용적인 게임플레이

신속한 전체 내용

## 策略背景
你正在分析一个双向网格交易策略。该策略基于初始价格(initPrice)设置多空双向网格:
- **多仓网格**: 在价格下跌时逐级开多,回升时平仓获利(步长1%)
- **空仓网格**: 在价格上涨时逐级开空,回落时平仓获利(步长1%)
- **最大持仓**: 多空各5档,共10个仓位

## 当前触发条件
系统已检测到以下异常情况之一:
1. 持仓数量达到5个(满仓状态)
2. 最长持仓时间超过24小时(持仓被套)
3. 持有空仓时,价格突破网格上限(价格持续上涨)
4. 持有多仓时,价格跌破网格下限(价格持续下跌)

## 你的分析任务
请基于以下数据综合判断:

### 数据1: 持仓状态(positions)
{{JSON.stringify($json.positions)}}

### 数据2: 市场情绪(sentimentData)
{{JSON.stringify($json.sentimentData)}}

## 判断标准

**需要调整网格价格**的情况:
- 市场趋势明确且持续(新闻情绪极度偏多/空)
- 当前价格已远离初始网格范围(突破或跌破超过3%)
- 持仓严重被套且市场情绪不支持反转
- 新闻显示基本面发生重大变化(监管、技术升级、重大事件)

**不需要调整**的情况:
- 价格在网格范围内正常波动
- 新闻情绪中性或矛盾
- 短期波动,缺乏趋势确认
- 持仓浮亏在可接受范围内

**注意**:
- 必须返回明确的"Yes"或"No"
- 理由需简洁、具体、可操作
- 谨慎判断,避免频繁调整网格

기능 설명

  • 사용감정 분석 노드일반적인 AI 대화를 대체하고 보다 체계화된 대화를 출력합니다.
  • 모호한 답변을 피하기 위해 두 가지 범주의 출력(예/아니오)을 제공합니다.
  • AI 모델: 대형 모델(OpenRouter를 통해 호출됨)
  • 동시에 백테스팅 및 최적화를 용이하게 하기 위해 이유 설명이 반환됩니다.

AI 반환 예시

{
  "sentiment": "Yes",
  "sentimentScore": 0.95,
  "reason": ...
}

노드 9: 전략 재설정

노드 이름: 전략 재설정
노드 유형: Code

전체 코드

Log('清仓仓位,重置所有参数')

let positions = exchange.GetPosition();

if (positions[0].Type === 0) {
    // 平多仓 - 市价卖出
    const orderId = exchange.CreateOrder(positions[0].Symbol, 'closebuy', -1, positions[0].Amount);
    Log(`✓ 平多仓成功,订单ID: ${orderId}`);
} else if (positions[0].Type === 1) {
    // 平空仓 - 市价买入
    const orderId = exchange.CreateOrder(positions[0].Symbol, 'closesell', -1, positions[0].Amount);
    Log(`✓ 平空仓成功,订单ID: ${orderId}`);
}

_G('grid', null);
_G('initPrice', null);
_G('lastAItime', Date.now());

return {};

기능 설명

  • 포지션 유형(롱/숏)에 따라 해당 마감 작업을 실행합니다.
  • 시장 주문을 사용하여 즉각적인 실행을 보장합니다.
  • 모든 영구 그리드 데이터 지우기
  • 그리드는 다음 기간에 새로운 가격으로 자동으로 재구축됩니다.

실행 프로세스

当前时刻: 价格35000,多仓5档全开
↓
AI判断: Yes,建议调整
↓
执行清仓: 平掉所有多单
↓
清除数据: grid=null, initPrice=null
↓
60秒后: K线触发器再次触发
↓
重新初始化: 以35000为新的初始价格
↓
重建网格: 新的多空网格围绕35000展开

노드 10: AI 냉각

노드 이름: AI 냉각
노드 유형: Code

Log('AI分析不支持调整原始价格')

_G('lastAItime', Date.now())

return {};

기능 설명

  • AI가 ‘아니요’라고 판단하면 실행
  • AI 통계 시간 기록
  • 이 사이클의 끝

문제 발견부터 조정 완료까지 전체 프로세스가 완전히 자동화되어 인간의 개입이 전혀 필요하지 않습니다.


이것이 왜 유용한가요?

기존 관행과 비교

치수 수동 모니터링 및 매개변수 조정 워크플로우 + AI 자동 의사결정
모니터링 주파수 24시간 모니터링이 필요합니다 60초마다 자동으로 확인
반응 속도 늦은 밤과 이른 아침 지연 몇 초 이내에 응답
의사결정 품질 감정적으로 조작하기 쉽습니다 뉴스 감정과 결합된 객관적 분석
노동비 고강도 노동 가끔씩 로그를 확인하세요

실제 운영 결과

시나리오 1: 변동성 있는 시장(정상 운영)

8:00  - 价格39500,开多第一档
9:00  - 价格39800,平多第一档,盈利0.76%
10:00 - 价格40300,开空第一档
11:00 - 价格40100,平空第一档,盈利0.50%
...持续震荡,网格正常运行
→ AI监控指标正常,不触发分析,零额外成本

시나리오 2: 일방적 감소(AI 개입)

周一 - 价格从40000跌到38000,多仓5档全开
周二 - 继续下跌至36000,持仓24小时触发AI
     → AI分析:市场情绪-0.65(偏空),建议调整
     → 自动平仓5个多单,止损-10%以上
     → 以36000重建网格,继续震荡获利
周三 - 新网格开始运行,当天盈利1.3%

조정이 이루어지지 않을 경우: 5개의 롱 주문이 계속 갇히게 되며, 손실이 -10% 이상으로 확대될 수 있습니다.

시나리오 3: 속보의 영향

14:00 - 价格正常震荡在39800
14:30 - 突发监管利空,价格闪崩至37500
14:31 - 多仓满仓+价格偏离触发AI
      → AI抓取新闻:"SEC突击检查交易所"
      → 情绪评分骤降至-0.85  
      → 判断:短期难反转,建议调整
14:32 - 自动平仓并重置网格至37500

기존 전략에서는 문제를 수동으로 발견하는 데 며칠이 걸릴 수 있습니다.


5. 비용과 빈도를 어떻게 조절할 수 있나요?

많은 사람들이 AI 사용 비용에 대해 걱정하지만, 실제로는 완전히 통제 가능합니다.

정상적인 상황

  • 이 전략은 AI를 호출하지 않고도 자체적으로 실행됩니다.
  • 분석은 비정상 조건이 트리거될 때만 시작됩니다.
  • 시장이 격렬하게 변동할 때 한 번만 호출됩니다., 매번 몇 센트씩 비용이 듭니다.

극단적인 경우

  • 시장이 격렬하게 변동하면 AI가 적절한 시기에 개입해 판단을 내릴 것입니다.
  • 피할 수 있는 손실에 비하면 정말 가치가 있어요

6. 그 밖에 어떤 트릭을 사용할 수 있나요?

이 아이디어는 그리드 전략에만 국한되지 않습니다.

1. 이동평균 전략

  • 이동 평균 신호 기반 자동 거래
  • AI는 일반적인 추세가 바뀌었는지 여부를 판단합니다.
  • 이동 평균 기간을 조정할지 여부를 결정하세요.

2. 마틴게일 전략

  • 전통 마팅게일
  • AI가 위험 노출을 모니터링합니다
  • 레버리지를 줄일지 결정하기

3. 차익거래 전략

  • 거래소 스프레드 모니터링
  • AI가 가격 차이 변화의 원인을 분석합니다.
  • 중재 매개변수 조정

4. 다양한 포트폴리오

  • BTC, ETH, SOL을 동시에 모니터링하세요
  • AI가 다양한 통화 간의 상관관계를 분석합니다.
  • 동적으로 위치 비율을 조정합니다

7. 초보자는 어떻게 시작해야 하나요?

1단계: 기존 전략을 먼저 실행하세요

  • 간단한 그리드 또는 이동 평균 전략을 선택하세요
  • 기본 논리에 익숙해지려면 일주일 동안 실행하세요.
  • 발생한 문제를 기록하세요

2단계: 모니터링 추가

  • 트리거 판단 코드 추가
  • 주요 지표 기록
  • 트리거 조건을 설정합니다(먼저 로그를 사용하고 AI를 연결하지 마세요)

3단계: AI 의사결정에 접근

  • AI 노드 설정
  • 명확한 판단 촉구를 작성하세요
  • 첫째, AI가 자동으로 실행하지 않고 제안만 하도록 합니다.

4단계: 자동 실행

  • AI 추천의 정확성을 확인하세요
  • 자동 매개변수 조정 활성화
  • 프롬프트와 트리거 조건을 지속적으로 최적화합니다.

8. 몇 가지 실용적인 제안

1. 프롬프트를 명확하게 작성하세요

❌ "帮我看看要不要调参数"

✅ "当前持仓5个,被套36小时,市场新闻偏空,
   我的网格中心价是40000,现价35000,
   请判断是否需要调整网格参数"

2. AI가 이유를 말하게 하세요

  • 백테스트 및 검증이 편리합니다.
  • AI의 사각지대를 발견하다
  • 의사결정 논리를 지속적으로 최적화합니다.

3. 보안 경계 설정

  • 단일 조정에 대한 최대 금액
  • 주파수 제한 조정
  • 중요한 결정의 수동 확인

4. 모든 결정을 문서화하세요

모든 AI 결정을 저장합니다.

  • 언제 작동하나요?
  • AI는 어떤 제안을 했나요?
  • 실행 후 효과는 어떻게 되나요?

요약: 워크플로의 진정한 가치

Inventor Platform 워크플로의 가장 큰 가치는 기존 전략을 대체하는 것이 아니라기존 전략을 더욱 스마트하게 만들기

  • ✅ 기존 전략은 안정적이고 신뢰할 수 있지만 유연성이 부족합니다.
  • ✅ AI 의사결정은 지능적이지만 완전히 신뢰할 수는 없습니다.
  • ✅ 규칙과 적응성을 모두 갖춘 두 가지를 결합

이는 마치 성실하지만 융통성 없는 직원에게 똑똑한 컨설턴트를 배정하는 것과 같습니다. 직원은 규칙을 준수할 책임이 있고, 컨설턴트는 중요한 순간에 조언을 제공할 책임이 있습니다.

가장 중요한 것은모든 것이 자동화될 수 있습니다. 24시간 내내 시장을 주시하거나 새벽 3시에 일어나 변수를 조정할 필요가 없습니다. 전략은 실행 중이며 AI가 모니터링을 도와줍니다. 정기적으로 결과만 확인하면 됩니다.

양적 거래란 이런 것입니다. 사람은 큰 그림을 생각하고, 기계는 세부 사항을 실행하고, AI는 시기적절한 최적화를 담당합니다.