커뮤니티
자동매도 문의
아래 수식을 작성하여 자동매도를 실행하는데 매도주문을 내지 않습니다. 무엇을 잘못한건지 알려주시면 감사하겠습니다.
주말 잘 보내시길 바랍니다.
var timerInterval = 5;
var HighPrices = {};
var ProfitTaken = {};
var EntryPrices = {};
function Main_OnStart()
{
var d = new Date();
var HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds();
Main.MessageList(HHMMSS, "|계좌 모니터링 스크립트 시작 (최유리지정가 매도 적용)");
Main.SetTimer(1, timerInterval*1000);
}
function Main_OnTimer(nEventID)
{
var d = new Date();
var HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds();
if (nEventID == 1)
{
if (HHMMSS >= 90000 && HHMMSS <= 152000)
{
var num = Account1.GetTheNumberOfBalances();
for (var i = 0; i < num; i++)
{
Account1.SetBalanceIndex(i);
var code = Account1.Balance.code;
var avgCost = Account1.Balance.avgUnitCost;
var curPrice = Account1.Balance.current;
var qty = Account1.Balance.count;
var unfillQty = getUnfillQty(code);
if (qty > 0)
{
// 1. 신규 매수 감지 및 데이터 초기화
if (EntryPrices[code] != avgCost)
{
EntryPrices[code] = avgCost;
HighPrices[code] = curPrice;
ProfitTaken[code] = false;
Main.MessageList(HHMMSS, "|신규진입감지|상태초기화", code);
}
// 1차 익절 달성 상태에서만 고점 갱신
if (ProfitTaken[code] == true && curPrice > HighPrices[code])
{
HighPrices[code] = curPrice;
}
// 2. 트레일링 스탑 : 고점 대비 4% 하락 (1차 익절 완료 상태)
if (ProfitTaken[code] == true && curPrice <= HighPrices[code] * 0.96)
{
if (unfillQty > 0)
{
CancelAllUnfillOrders(code);
Main.MessageList(HHMMSS, "|트레일링스탑|미체결취소", code);
continue;
}
else
{
Main.MessageList(HHMMSS, "|트레일링스탑|최유리전량청산", code, "고점:"+HighPrices[code]);
// 매도 가격 0, 주문종류 3(최유리지정가 - 매수 1호가 타겟)
Account1.OrderSell(code, qty, 0, 3);
delete HighPrices[code];
delete ProfitTaken[code];
delete EntryPrices[code];
continue;
}
}
// 3. 손절 : 매수가 대비 3% 하락
if (curPrice <= avgCost * 0.97)
{
if (unfillQty > 0)
{
CancelAllUnfillOrders(code);
Main.MessageList(HHMMSS, "|손절도달|미체결취소", code);
continue;
}
else
{
Main.MessageList(HHMMSS, "|손절|최유리전량청산", code, "평단:"+avgCost);
// 매도 가격 0, 주문종류 3(최유리지정가)
Account1.OrderSell(code, qty, 0, 3);
delete HighPrices[code];
delete ProfitTaken[code];
delete EntryPrices[code];
continue;
}
}
// 4. 1차 익절 : 매수가 대비 4% 상승 시 50% 매도
if (unfillQty == 0 && curPrice >= avgCost * 1.04 && ProfitTaken[code] == false)
{
var sellQty = Math.floor(qty / 2);
if (sellQty > 0)
{
Main.MessageList(HHMMSS, "|1차익절|50%최유리매도", code, curPrice);
// 매도 가격 0, 주문종류 3(최유리지정가)
Account1.OrderSell(code, sellQty, 0, 3);
ProfitTaken[code] = true;
HighPrices[code] = curPrice;
}
}
}
}
}
}
}
// 미체결 수량 합산 함수
function getUnfillQty(targetCode)
{
var unfillSum = 0;
var unfillNum = Account1.GetTheNumberOfUnfills();
for (var j = 0; j < unfillNum; j++)
{
Account1.SetUnfillIndex(j);
if (Account1.Unfill.code == targetCode)
{
unfillSum += Account1.Unfill.count;
}
}
return unfillSum;
}
// 미체결 주문 취소 함수
function CancelAllUnfillOrders(targetCode)
{
var unfillNum = Account1.GetTheNumberOfUnfills();
for (var j = 0; j < unfillNum; j++)
{
Account1.SetUnfillIndex(j);
if (Account1.Unfill.code == targetCode && Account1.Unfill.count > 0)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
}