Alapaca 트레이딩 자동화
이것은Crypto Trading분야의자동화 워크플로우로, 19개의 노드를 포함합니다.주로 Code, Wait, Merge, SplitOut, HttpRequest 등의 노드를 사용하며. AI驱动의자동화股票交易:통합Alpaca및Google Sheets
- •대상 API의 인증 정보가 필요할 수 있음
- •Google Sheets API 인증 정보
카테고리
{
"id": "6Bn6KSpg1le9mG4Y",
"meta": {
"instanceId": "34d07950904120624117fd89d9d9b4f13d9fa466720a0972ac5aa843f9eb8cb8",
"templateCredsSetupCompleted": true
},
"name": "Alapaca Trade automation",
"tags": [],
"nodes": [
{
"id": "1311dd64-4b51-4e2e-ab20-9621e3b41e03",
"name": "Alpaca-계정-정보-가져오기",
"type": "n8n-nodes-base.httpRequest",
"position": [
-140,
680
],
"parameters": {
"url": "https://paper-api.alpaca.markets/v2/account",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpCustomAuth",
"queryParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p1dJbEo98pH5SVih",
"name": "Query Auth account"
},
"httpCustomAuth": {
"id": "cY4cJyCzDnwhbKkw",
"name": "Custom Auth account"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "1aa8a8aa-b765-4674-9177-15167da914be",
"name": "Alpaca-매도-주문-전송",
"type": "n8n-nodes-base.httpRequest",
"position": [
1620,
580
],
"parameters": {
"url": "=https://paper-api.alpaca.markets/v2/positions/{{$json.asset_id}}",
"method": "DELETE",
"options": {},
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{}
]
},
"genericAuthType": "httpCustomAuth",
"queryParameters": {
"parameters": [
{}
]
},
"headerParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p1dJbEo98pH5SVih",
"name": "Query Auth account"
},
"httpCustomAuth": {
"id": "cY4cJyCzDnwhbKkw",
"name": "Custom Auth account"
}
},
"typeVersion": 4.2
},
{
"id": "0d966c99-bf41-4cc6-82de-217e25a7fcf2",
"name": "Alpaca-매수-주문-전송",
"type": "n8n-nodes-base.httpRequest",
"position": [
1620,
780
],
"parameters": {
"url": "https://paper-api.alpaca.markets/v2/orders",
"method": "POST",
"options": {},
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "symbol",
"value": "={{ $json.symbol }}"
},
{
"name": "notional",
"value": "={{ $json.market_value_per_symbol.toFixed(2) }}"
},
{
"name": "side",
"value": "buy"
},
{
"name": "type",
"value": "market"
},
{
"name": "time_in_force",
"value": "day"
}
]
},
"genericAuthType": "httpCustomAuth",
"queryParameters": {
"parameters": [
{}
]
},
"headerParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p1dJbEo98pH5SVih",
"name": "Query Auth account"
},
"httpCustomAuth": {
"id": "cY4cJyCzDnwhbKkw",
"name": "Custom Auth account"
}
},
"typeVersion": 4.2
},
{
"id": "60ba11a2-065f-453a-b310-4cc65f3b726d",
"name": "상위-감성-점수-필터링",
"type": "n8n-nodes-base.code",
"position": [
520,
680
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\n// Sort the array by sentimentScore in descending order\nconst sortedItems = $input.all().sort((a, b) => b.json.sentimentScore - a.json.sentimentScore);\n\n// Get the top 4 items\nconst top4Items = sortedItems.slice(0, 4);\n\n// Return the result in the n8n expected format\nreturn top4Items\n\n\n"
},
"typeVersion": 2
},
{
"id": "6f876b15-aeb6-4def-96f1-3ec20b8e4919",
"name": "오늘의-감성-점수-읽기",
"type": "n8n-nodes-base.googleSheets",
"position": [
300,
680
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{$today}}\n",
"lookupColumn": "date"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=0",
"cachedResultName": "sentiments"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "c4ce7556-5966-493e-8017-0377c2bcd2be",
"name": "오늘의-계정-잔고-기록",
"type": "n8n-nodes-base.googleSheets",
"position": [
80,
680
],
"parameters": {
"columns": {
"value": {
"date": "={{$today}}\n",
"change": "={{($json.equity- $json.last_equity)/ $json.last_equity}}",
"balance": "={{ $json.equity }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "balance",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "balance",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "change",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "change",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"date"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {
"useAppend": true
},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 449152551,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=449152551",
"cachedResultName": "balance"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "657726f0-38f0-4863-b911-1050cf345d84",
"name": "Alpaca-미결-포지션-가져오기",
"type": "n8n-nodes-base.httpRequest",
"position": [
740,
680
],
"parameters": {
"url": "https://paper-api.alpaca.markets/v2/positions",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpCustomAuth",
"queryParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p1dJbEo98pH5SVih",
"name": "Query Auth account"
},
"httpCustomAuth": {
"id": "cY4cJyCzDnwhbKkw",
"name": "Custom Auth account"
}
},
"executeOnce": true,
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "7d04afeb-3b24-4c96-9cf9-16999a14fec4",
"name": "청산-포지션과-신규-오픈-포지션-생성",
"type": "n8n-nodes-base.code",
"position": [
960,
680
],
"parameters": {
"jsCode": "// Accessing data from the previous nodes\nconst openPositions = $('Alpaca_get_open_positions').all();\nconst topSentiment = $(\"filter_top_sentiment_score\").all();\n\n// Extracting the symbols for easier comparison\nconst openPositionSymbols = openPositions.map(pos => pos.json.symbol);\nconst topSentimentSymbols = topSentiment.map(sen => sen.json.stock);\n\n// Table 1: Open positions not in the top sentiment filter\nconst positionsNotInTopSentiment = openPositions\n .filter(pos => !topSentimentSymbols.includes(pos.json.symbol))\n .map(pos => ({\n symbol: pos.json.symbol,\n market_value: pos.json.market_value,\n qty: pos.json.qty,\n asset_id : pos.json.asset_id\n }));\n\n// Table 2: Symbols from top sentiment not in open positions\nconst symbolsNotInOpenPositions = topSentiment\n .filter(sen => !openPositionSymbols.includes(sen.json.stock))\n .map(sen => ({\n symbol: sen.json.stock,\n }));\n\n// Calculate the total market value of the first table\nconst totalMarketValue = positionsNotInTopSentiment.reduce((sum, pos) => {\n return sum + parseFloat(pos.market_value);\n}, 0);\n\n// Calculate the value to be assigned to each symbol in the second table\nconst valuePerSymbol = symbolsNotInOpenPositions.length > 0\n ? totalMarketValue / symbolsNotInOpenPositions.length\n : 0;\n\n// Add the calculated value to each symbol in the second table\nconst symbolsWithMarketValue = symbolsNotInOpenPositions.map(item => ({\n ...item,\n market_value_per_symbol: valuePerSymbol,\n}));\n\n// Returning the two tables as separate outputs\nreturn [\n {\n json: {\n positions_not_in_top_sentiment: positionsNotInTopSentiment,\n \n symbols_not_in_open_positions: symbolsWithMarketValue,\n \n }}\n];"
},
"typeVersion": 2
},
{
"id": "1e846978-377d-477f-9e62-5ae465066315",
"name": "오픈할-포지션",
"type": "n8n-nodes-base.splitOut",
"position": [
1180,
780
],
"parameters": {
"options": {},
"fieldToSplitOut": "symbols_not_in_open_positions"
},
"typeVersion": 1
},
{
"id": "a8bbdca1-d531-4384-bde9-8c1bf0979677",
"name": "청산할-포지션",
"type": "n8n-nodes-base.splitOut",
"position": [
1400,
580
],
"parameters": {
"options": {},
"fieldToSplitOut": "positions_not_in_top_sentiment"
},
"typeVersion": 1
},
{
"id": "a6175bb8-d92e-4c36-9f70-9411567f80c8",
"name": "시트에-기록할-주문-병합",
"type": "n8n-nodes-base.merge",
"position": [
1840,
680
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "d74f036b-e085-43d4-a47d-82820e68bbed",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-920,
380
],
"parameters": {
"width": 400,
"height": 380,
"content": "## Alpaca Trading 📈\nthis workflow takes the sentiment analysis made by our sentiment analysis bot workflow ([template link](https://n8n.io/workflows/5369-automated-stock-sentiment-analysis-with-google-gemini-and-eodhd-news-api/)) and translates it into automated trading actions using a paper trading account on Alpaca. It manages the portfolio by selling underperforming assets and buying stocks with high positive sentiment."
},
"typeVersion": 1
},
{
"id": "61a3c87f-00f1-4dad-94c1-bd9ef1a9c906",
"name": "Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
2060,
680
],
"parameters": {
"columns": {
"value": {
"date": "={{ $today }}",
"order": "={{ $json.side }}",
"value": "={{ $if( $json.side == \"buy\",$json.notional,$('positions_to_close').item.json.market_value) }}",
"symbol": "={{ $json.symbol }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "symbol",
"type": "string",
"display": true,
"required": false,
"displayName": "symbol",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "order",
"type": "string",
"display": true,
"required": false,
"displayName": "order",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "value",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "value",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"date"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 486231870,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=486231870",
"cachedResultName": "positions"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "22e12a7a-0a3d-46d7-a103-648e9628f3c4",
"name": "대기",
"type": "n8n-nodes-base.wait",
"position": [
1400,
780
],
"webhookId": "3d1031f5-7a20-4c3a-8791-748e93830402",
"parameters": {
"unit": "minutes",
"amount": 2
},
"typeVersion": 1.1
},
{
"id": "ea31c298-b298-4e59-8057-a582a9fed462",
"name": "일정-트리거",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-360,
680
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 16,
"triggerAtMinute": 45
}
]
}
},
"typeVersion": 1.2
},
{
"id": "2b54791d-fec9-47f4-bf86-4e967884c5c0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
380
],
"parameters": {
"color": 6,
"width": 620,
"height": 560,
"content": "## 1. Daily Trigger and Account Snapshot 📈\n**Schedule Trigger:** The workflow is automatically triggered every day at 4:45 PM (Asia/Jerusalem time). The time is set so it will run after the stock market in the US open\n\n**Alpaca-get-account-info:** It starts by fetching your current Alpaca paper trading account information, like your equity and balance.\n\n**write_account_balace_today:** This node logs your account balance for the day into a Google Sheet named \"balance\". It also calculates and records the daily percentage change in your balance, allowing you to track performance over time."
},
"typeVersion": 1
},
{
"id": "a2bc2441-e498-4de4-9d5e-b4af8fa1d5d4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
260,
380
],
"parameters": {
"width": 620,
"height": 560,
"content": "## 2. Sentiment-Based Stock Selection 👍👎\n**read_sentiments_score_today:** The workflow reads the sentiment scores from a google sheet the scores were generated by a \"Sentiment Analysis Bot\"([template link](https://n8n.io/workflows/5369-automated-stock-sentiment-analysis-with-google-gemini-and-eodhd-news-api/)) for the current day from the \"sentiments\" sheet in a sentiment analysis Google Sheet.\n\n**filter_top_sentiment_score:** This code block selects the top four stocks with the highest sentiment scores from the list, focusing your trading strategy on the most promising assets.\n\n**Alpaca_get_open_positions:** It then retrieves a list of all currently open positions in your Alpaca account to compare against the top sentiment stocks."
},
"typeVersion": 1
},
{
"id": "e80a7608-0850-4da6-af19-a2d271a6960c",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
920,
100
],
"parameters": {
"color": 3,
"width": 840,
"height": 840,
"content": "## 3. Trading Logic and Execution ⚙️\n**create_positions_to_close_and_positions_two_open:** This is the core logic of your trading strategy. The code compares the stocks you currently hold with the top four sentiment stocks for the day.\n\nIt identifies which of your current positions are no longer in the top four and marks them to be sold.\n\nIt identifies which of the top four sentiment stocks you do not currently own and marks them to be bought.\n\nIt calculates the total market value of the positions to be sold and divides that amount equally among the new stocks to be purchased.\n\n**positions_to_close:** This node takes the list of stocks to be sold and processes them one by one.\n\n**Alpaca-post-order-sell:** For each stock in the \"to-sell\" list, this node sends a \"sell\" order to Alpaca to close the position.\n\n**Wait:** A two-minute pause is implemented to ensure that the sell orders are processed and the funds are available before the buy orders are placed.\n\n**positions_to_open:** This node takes the list of top-sentiment stocks that you don't currently own.\n\n**Alpaca-post-order-buy:** For each of these stocks, a \"buy\" order is sent to Alpaca using the allocated portion of the funds from the sold assets."
},
"typeVersion": 1
},
{
"id": "d824c44b-d4c3-4334-b563-f0390541c2e8",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1800,
420
],
"parameters": {
"color": 4,
"width": 520,
"height": 520,
"content": "## 4. Logging and Record-Keeping 📝\n**merge_orders_to_write_to_sheets:** This node gathers the results from both the buy and sell orders.\n\n**Google Sheets (Append):** Finally, the details of every trade (date, symbol, order type, and value) are logged in the \"positions\" sheet of your Google Sheet, providing a complete record of all trading activity."
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"timezone": "Asia/Jerusalem",
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1"
},
"versionId": "83841c35-e0c9-4cee-86c2-e8bc1ae465bb",
"connections": {
"22e12a7a-0a3d-46d7-a103-648e9628f3c4": {
"main": [
[
{
"node": "0d966c99-bf41-4cc6-82de-217e25a7fcf2",
"type": "main",
"index": 0
}
]
]
},
"ea31c298-b298-4e59-8057-a582a9fed462": {
"main": [
[
{
"node": "1311dd64-4b51-4e2e-ab20-9621e3b41e03",
"type": "main",
"index": 0
}
]
]
},
"1e846978-377d-477f-9e62-5ae465066315": {
"main": [
[
{
"node": "22e12a7a-0a3d-46d7-a103-648e9628f3c4",
"type": "main",
"index": 0
}
]
]
},
"a8bbdca1-d531-4384-bde9-8c1bf0979677": {
"main": [
[
{
"node": "1aa8a8aa-b765-4674-9177-15167da914be",
"type": "main",
"index": 0
}
]
]
},
"0d966c99-bf41-4cc6-82de-217e25a7fcf2": {
"main": [
[
{
"node": "a6175bb8-d92e-4c36-9f70-9411567f80c8",
"type": "main",
"index": 1
}
]
]
},
"1aa8a8aa-b765-4674-9177-15167da914be": {
"main": [
[
{
"node": "a6175bb8-d92e-4c36-9f70-9411567f80c8",
"type": "main",
"index": 0
}
]
]
},
"1311dd64-4b51-4e2e-ab20-9621e3b41e03": {
"main": [
[
{
"node": "c4ce7556-5966-493e-8017-0377c2bcd2be",
"type": "main",
"index": 0
}
]
]
},
"657726f0-38f0-4863-b911-1050cf345d84": {
"main": [
[
{
"node": "7d04afeb-3b24-4c96-9cf9-16999a14fec4",
"type": "main",
"index": 0
}
]
]
},
"60ba11a2-065f-453a-b310-4cc65f3b726d": {
"main": [
[
{
"node": "657726f0-38f0-4863-b911-1050cf345d84",
"type": "main",
"index": 0
}
]
]
},
"c4ce7556-5966-493e-8017-0377c2bcd2be": {
"main": [
[
{
"node": "6f876b15-aeb6-4def-96f1-3ec20b8e4919",
"type": "main",
"index": 0
}
]
]
},
"6f876b15-aeb6-4def-96f1-3ec20b8e4919": {
"main": [
[
{
"node": "60ba11a2-065f-453a-b310-4cc65f3b726d",
"type": "main",
"index": 0
}
]
]
},
"a6175bb8-d92e-4c36-9f70-9411567f80c8": {
"main": [
[
{
"node": "61a3c87f-00f1-4dad-94c1-bd9ef1a9c906",
"type": "main",
"index": 0
}
]
]
},
"7d04afeb-3b24-4c96-9cf9-16999a14fec4": {
"main": [
[
{
"node": "a8bbdca1-d531-4384-bde9-8c1bf0979677",
"type": "main",
"index": 0
},
{
"node": "1e846978-377d-477f-9e62-5ae465066315",
"type": "main",
"index": 0
}
]
]
}
}
}이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 암호화폐 거래
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
Raz Hadas
@raz-hadasCo-founder of buildmyflow, on a mission to create powerful and easy-to-use n8n automation templates. With a background in AI and a passion for social impact as the co-founder of TovTech, I'm dedicated to building a community-focused resource for free and premium workflows that save you time and unlock new possibilities. Let's automate together! https://www.linkedin.com/in/raz-hadas/
이 워크플로우 공유