답변완료
수정 부탁드립니다.
안녕하세요?
파워검색 종목이 발생하면 자동매수하고, 3분봉 기준 매수한 시점의 동일한 봉이 완성되는 시점에서 매도세가 매수세보다 크거나 음봉일 경우, 3분봉 완성 시점에서 전량 매도하는 로직입니다.
매수시점의 봉의 정보를 저장하는 부분부터 에러가 발생하는 것 같습니다. 아래 함수들을 참고해서 수정해 주시면 감사하겠습니다. 다른 로직은 표기하지 않고 관련 로직만 표기하였습니다.
Main_OnRcvMarketData(MarketData): 매수시점의 봉의 정보를 저장하는 부분포함
isCandleClose(stockCode): 봉 마감 여부를 확인하는 함수
checkSellCondition(stockCode): 매수/매도 거래량 비교 및 매수 시점의 봉과 동일한 봉인지 확인하는 함수
getCandleTime(): 봉의 시작 시간을 반환하는 함수
var timer = 3; // 3초
var 매수금 = 500000;
var 종목손절 = 0.97; // 종목 손절 % 조정
var 계좌익절 = 1.07; // 계좌 익절 % 조정 (7% 익절)
var OrderList = [];
var MKList = [];
var req;
var 매수시점봉 = {}; // 매수 시점의 봉 정보를 저장할 객체
var BuyVolume = 0;
var SellVolume = 0;
function Main_OnStart()
{
// 1번 타이머
Main.SetTimer(1, timer * 1000);
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
// 스팟 시작시 잔고 평가금액
V1 = Account1.GetBalanceETCinfo(100);
Main.MessageList("Start");
}
function Main_OnTimer(nEventID)
{
var d = new Date();
var YYYYMMDD = d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate();
var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds();
if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS < 151500) // 9:00 ~ 15:15
{
// 종목 검색 수정
Main.ReqPowerSearch("(분) 시가배팅_가격보조지표_통합"); // 파워 종목 검색
Main.MessageList("ReqPowerSearch");
}
if (nEventID == 1)
{
// 계좌 보유 종목 수
var num = Account1.GetTheNumberOfBalances();
// 9:00 ~ 15:15 사이
if (HHMMSS >= 90000 && HHMMSS < 151500)
{
// 보유 종목이 1개 이상일 때
if (num >= 1)
{
for (var i = 0; i < num; i++)
{
// 잔고 설정
Account1.SetBalance(i);
var stockCode = Account1.Balance.code;
var currentPrice = Account1.Balance.current;
var avgCost = Account1.Balance.avgUnitCost;
var ratio = currentPrice / avgCost;
// 매수 시점의 봉이 끝나는 시점에서만 매도 조건 확인
if (isCandleClose(stockCode) && checkSellCondition(stockCode))
{
Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1);
Main.MessageList("조건 충족, 전량 매도");
}
}
}
}
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
}
}
function Main_OnRcvMarketData(MarketData)
{
if(MarketData.code==OrderList[req])
{
MKList.push(MarketData);
//계좌에 같은 종목이 있는지 확인
if(!IsStockInAccount(MarketData.code))
{
//계좌에 없는 경우에만 매수
Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1); //매수금 시장가 주문
// 매수 시점의 봉 정보를 저장
매수시점봉[MarketData.code] =
{
time: getCandleTime(), // 매수 시점 봉의 시간
high: MarketData.high,
low: MarketData.low,
close: MarketData.current
};
Main.MessageList(MarketData.code + "주식을 매수합니다");
}
else
{
Main.MessageList(MarketData.code + "검색종목은 이미 계좌에 있으므로 매수하지 않습니다.");
}
req=req+1;
if(req<OrderList.length)
{
var aa=Main.ReqMarketData(OrderList[req]);
if(aa==-1)
{
Main.SetTimer(2,15000);
}
}
else
{
Main.SetTimer(1,timer*1000);
}
}
}
// 봉 마감 여부 확인 (3분봉 기준)
function isCandleClose(stockCode)
{
var now = new Date();
var minutes = now.getMinutes();
return minutes % 3 === 0; // 3분 마다 봉이 마감
}
// 매수/매도 거래량 비교 및 매수 시점의 봉과 동일한 봉인지 확인
function checkSellCondition(stockCode)
{
//var balance = Account1.Balance;
var 매수봉 = 매수시점봉[stockCode];
// 매수한 봉과 현재 봉이 동일해야 조건 체크
if (getCandleTime() !== 매수봉.time)
{
return false; // 매수한 봉과 현재 봉이 다르면 매도 조건 확인하지 않음
}
// 거래량 계산
BuyVolume = (MarketData.high === MarketData.low) ? 0 : MarketData.volume * (MarketData.current - MarketData.low) / (MarketData.high - MarketData.low);
SellVolume = (MarketData.high === MarketData.low) ? 0 : MarketData.volume * (MarketData.high - MarketData.current) / (MarketData.high - MarketData.low);
// 조건: 매도 거래량이 매수 거래량보다 크거나, 봉이 음봉일 경우
if (SellVolume > BuyVolume || MarketData.current < MarketData.open)
{
Main.MessageList("매도 조건 충족: 매도 거래량이 많거나 음봉");
return true;
}
return false;
}
// 봉의 시작 시간을 반환하는 함수 (3분봉 기준)
function getCandleTime()
{
var now = new Date();
return now.getHours() * 100 + Math.floor(now.getMinutes() / 3) * 3;
}
2024-10-14
529
글번호 226139
답변완료
문의드립니다.
안녕하세요?
랭귀지에 대한 기초지식이 없다보니 이것저것 테스트 하는데 시간이 많이 소요되어서
문의 드립니다.
1) 15분봉으로 검색기는 만들었습니다.("TEST")
2) 15분마다 읽어 들여서 기본적으로 매수/매도 하는 식을 부탁드립니다.
Main.ReqPowerSearch("TEST")
var MK = [];
var OrderCount = [];
var BuyPrice = [];
var MM = 500000;
var 타이머간격 = 5;// 5초
var 매수금 = 100000
var OrderList = [];
var MKList = [];
var req;
function Main_OnStart()
{
Main.SetTimer(1, 타이머간격*1000); //1번타이머, 주기 5분(종목검색간격)
// Main.SetTimer(1, 300000); //1번타이머, 주기 5분(종목검색간격)
// Main.SetTimer(2, 10000); //2번타이머, 주기 10초 (추가매수 타이밍 및 익절을 체크하는 시간간격)
}
//타이머동작
function Main_OnTimer(nEventID)
{
var d = new Date();
YYYYMMDD = d.getFullYear()*10000+(d.getMinutes()+1)*100+d.getSeconds();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//1번타이머
if (nEventID == 1 && HHMMSS > 90000 && HHMMSS < 151500) //9시 ~15시15분
{
// Main.KillTimer(1); //타이머중지
Main.ReqPowerSearch("TEST"); //****** 종목검색실행
}
//2번타이머
if (nEventID == 2)
{
// Main.KillTimer(2);
Main.ReqMarketData(MKList[req]);
}
}
2024-09-17
408
글번호 226128
답변완료
account1이 정의되지 않았습니다
account1이 정의되지 않았습니다 라고 뜨네요
account1 is not defined 바쁘시더라도 수정 부탁 드려요
건강하세요
var timer2 = 2; // 2초
var 매수금 = 17000000;
var 손절 = 0.95;
var 익절 = 1.03;
var OrderList = [];
var MKList = [];
var req;
var 종목수 = 1, BuyCount;
function Main_OnStart()
{
//1번 타이머, 1초
Main.SetTimer(1, timer2*1000);
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
//스팟 시작시 잔고평가금액
V1 = Account1.GetBalanceETCinfo(100);
BuyCount = 0;
}
function Main_OnTimer(nEventID)
{
var d = new Date();
YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
if (nEventID == 1 && HHMMSS >= 090000 && HHMMSS < 113000 && BuyCount < 종목수)
{
//종목검색 수행
Main.ReqPowerSearch("단타")
}
if (nEventID == 1)
{
//계좌보유종수
var num = Account1.GetTheNumberOfBalances();
//9시~11시 15분 사이
if (HHMMSS >= 090000 && HHMMSS < 113000)
{
//보유종목이 1개 이상
if (num >= 1)
{
//계좌평가금액이 스팟시작시 평가금액대비 3% 이상이면 전종목 전량매도
if (Account1.GetBalanceETCinfo(100) >= V1*1.03)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 3%수익이거나 5% 손실이면 시장가 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
else //아니면 개별종목 3%익절, -5%손절 체크
{
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 3%수익이거나 -5% 손실이면 시장가 매도
if (Account1.Balance.count > 0 &&
(Account1.Balance.current >= Account1.Balance.avgUnitCost*익절 ||
Account1.Balance.current <= Account1.Balance.avgUnitCost*손절))
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
}
}
//13시 00분이후이면 모든 종목 전량 수익에 상관없이 매도
if (HHMMSS >= 130000)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 3%수익이거나 -5% 손실이면 시장가 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
Main.KillTimer(1);
OrderList = [];
if (nCount >= 1)
{
if (MKList.length == 0)
{
OrderList = aItemList;
}
else
{
for (var a = 0; a < nCount; a++)
{
var Add = true;
for (var b = 0; b < MKList.length; b++)
{
if (aItemList[a] == MKList[b].code)
{
Add = false;
}
}
if (Add == true && !IsStockInAccount(aItemList[a]))
{
OrderList.push(aItemList[a]);
}
}
}
}
if (OrderList.length == 0)
{
Main.SetTimer(1, timer2*1000);
}
else
{
req = 0;
Main.ReqMarketData(OrderList[req]);
}
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == OrderList[req])
{
MKList.push(MarketData);
// 계좌에 같은 종목이 있는지 확인
if (!IsStockInAccount(MarketData.code))
{
if (BuyCount < 종목수)
{
// 계좌에 없는 경우에만 매수
//Account1.OrderBuy(MarketData.code,1,0,1); 밑에 한번에 17000000 시장가에 매수
Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1);
//Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(4)),MarketData.Ask(1),0);
//지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다.
Main.MessageList(MarketData.code + " 주식을 매수합니다.");
BuyCount = BuyCount+1;
}
}
else
{
Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다.");
}
req = req+1;
if (req < OrderList.length && BuyCount < 종목수)
{
var aa = Main.ReqMarketData(OrderList[req]);
if (aa == -1)
{
Main.SetTimer(2, 15000);
}
}
else
{
Main.SetTimer(1, timer2*1000);
}
}
}
function IsStockInAccount(stockCode)
{
// 계좌에 해당 종목이 있는지 확인하는 함수
var numberOfBalances = Account1.GetTheNumberOfBalances();
for (var i = 0; i < numberOfBalances; i++)
{
Account1.SetBalance(i);
if (stockCode == Account1.Balance.code)
{
return true; // 계좌에 같은 종목이 있으면 true 반환
}
}
return false; // 계좌에 같은 종목이 없으면 false 반환
}
2024-09-12
479
글번호 226126