답변완료
유진선물예스트레이더 예스스팟 stime 오류
안녕하세요. 친절한 답변에 미리 감사드립니다. 유진선물예스트레이더 내 예스스팟에서 차트 객체의 stime를 불러다 데이터베이스 객체로 외부의 dbms로 stime을 수출해 보면 중간에 마이너스 음수가 나오는 오류가 발생합니다. stime을 수천봉 수입해다가 외부의 dbms로 내보낼때 중간중간에 마이너스 음수가 나옵니다. 해결 부탁드립니다!
사용 수식
==============================================
/*
2023년 9월 1일. 미9연미사 와 미12에서 쓰는 예스트레이더 예스스팟 날초마다 켜두는
실시간자료 ssj 수출 짠은 이 AD_nal_ssj_soochool_1.js 퍄일이다.
다른거 신경쓰지 않고 단순하게 오직 실시간자료 ssj 수출만 하는 것이 필요하기에
soochool.js 계열과 다르게 간결하게 정리한 것이 이 퍄일이다.
2023년 9월 1일. 후 3시1분.
AD_nal_ssj_soochool_2.js 는 마리아디비 miBon_ssjGoEreum 생성시 첫째 컬럼을 `MMA` BIGINT NULL AUTO_INCREMENT
로 생성하였기에 그에 맞춰 ins**t 함수를 수정한 것이다.
2023년 9월 9일. 후 5시1분.
미9연미사나 완전 완성본의 것. 실인미진민참.
*/
var hhRoGoEreum="ADC_JJNASDAQ100_YESTRADER_SSJ"; // 손잡이- 줄리아 공유 실시간자료고 이름
var choKkuenSi_sseulMisaBongSu=8500; // 손잡이- 10000 하면 좋으나 줄여도 됨.
var hhSseulGoId=1; // 손잡이 이나 고정- 봉번 ID는 날초 시 언제나 1번부터임.
var hhSdate=0;
var hhStime=0;
var hhO=0;
var hhH=0;
var hhL=0;
var hhC=0;
var hhV=0;
var sqlins**t="0";
var hhBongBun=0;
function Main_OnStart()
{
Main.MessageList("AD yestrader ssj <soochool> sijac. hhSseulGoId=",hhSseulGoId);
//////////////// 자료고 날 최초시 갈래
for (var ffa=choKkuenSi_sseulMisaBongSu; ffa>=0; ffa--){ // 손잡이
//////////////// 마련
hhSdate=Chart1.GetSDate(1,ffa);
hhStime=Chart1.GetSTime(1,ffa);
hhO=Chart1.GetOpen(1,ffa);
hhH=Chart1.GetHigh(1,ffa);
hhL=Chart1.GetLow(1,ffa);
hhC=Chart1.GetClose(1,ffa);
hhV=Chart1.GetVolume(1,ffa);
//////////////// 로고 sql 마련
sqlins**t=hhRoGoEreum+" (ID,SDATE,STIME,O,H,L,C,V) VALUES (";
sqlins**t+=String(hhSseulGoId);
sqlins**t+=",";
sqlins**t+=String(hhSdate);
sqlins**t+=",";
sqlins**t+=String(hhStime);
sqlins**t+=",";
sqlins**t+=String(hhO);
sqlins**t+=",";
sqlins**t+=String(hhH);
sqlins**t+=",";
sqlins**t+=String(hhL);
sqlins**t+=",";
sqlins**t+=String(hhC);
sqlins**t+=",";
sqlins**t+=String(hhV);
sqlins**t+=");";
//////////////// 로고 실행
DataBase1.ins**t(sqlins**t);
hhSseulGoId+=1; // 1증.
}
}
function Chart1_OnBarAppended(nData)
{
// Main.MessageList("Chart1_OnBarAppended / hhSseulGoId=",hhSseulGoId);
if (nData==1){
hhBongBun=0; // 0부여.
//////////////// 마련
hhSdate=Chart1.GetSDate(1,hhBongBun);
hhStime=Chart1.GetSTime(1,hhBongBun);
hhO=Chart1.GetOpen(1,hhBongBun);
hhH=Chart1.GetHigh(1,hhBongBun);
hhL=Chart1.GetLow(1,hhBongBun);
hhC=Chart1.GetClose(1,hhBongBun);
hhV=Chart1.GetVolume(1,hhBongBun);
//////////////// 로고 sql 마련
sqlins**t=hhRoGoEreum+" (ID,SDATE,STIME,O,H,L,C,V) VALUES (";
sqlins**t+=String(hhSseulGoId);
sqlins**t+=",";
sqlins**t+=String(hhSdate);
sqlins**t+=",";
sqlins**t+=String(hhStime);
sqlins**t+=",";
sqlins**t+=String(hhO);
sqlins**t+=",";
sqlins**t+=String(hhH);
sqlins**t+=",";
sqlins**t+=String(hhL);
sqlins**t+=",";
sqlins**t+=String(hhC);
sqlins**t+=",";
sqlins**t+=String(hhV);
sqlins**t+=");";
//////////////// 로고 실행
DataBase1.ins**t(sqlins**t);
hhSseulGoId+=1; // 1증.
}
}
답변완료
안녕하세요..
안녕하세요 //부장님
부장님이 해결해주신 내용입니다.
그런데 가격이 3.5이상에서는 시스템이 아웃되어 버립니다.
종목을 지정해서 불어오면 실행되는데
동시 거래가 있는 종목은 상관없는데 동시거래가 없으면 시스템이 아웃되는 현상이 일어나므로
추가해서
즉 입력란에서 임의 선택된 콜은 250부터 5개 풋은 245부터 5개 강제적으로 불러오는 곳을 추가하고 싶습니다.
동시시세가 없더라도 불러오고 싶네요
전략실행차트 여실때 자동으로 종목이 선정되게는 가능하지 않습니다.
스팟안에서 차트객체를 이용하신다면 스팟수식안에서 종목선정해 차트를 만들 수 있습니다.
기본차트는 KP200연결선물이고 콜/풋 옵션을 참조데이터로 추가하는데
4.0에 가까운 순서로 5개씩 추가합니다.
스크립트 객체설정
종목객체 추가 -> 속성에서 객체명 MarketData1, KP200연결선물로 지정
옵션객체 추가 -> 속성에서 객체명 Option1, KP200지수옵션으로 지정
var FutrueOpen;
var 콜기준 = 4.0;
var 풋기준 = 4.0;
var CallOrderCode1,CallOrderCode2,CallOrderCode3,CallOrderCode4,CallOrderCode5;
var PutOrderCode1,PutOrderCode2,PutOrderCode3,PutOrderCode4,PutOrderCode5;
function Main_OnStart()
{
FutrueOpen = false;
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
if (FutrueOpen == false && MarketData1.open > 0)
{
FutrueOpen = true;
Main.KillTimer(1);
var Calldiff = [];
if (콜기준 > 0)
{
var a = 0;
for (var i = -Option1.lowersATM; i < Option1.uppersATM; i++)
{
Calldiff[a] = new Array(Math.abs(콜기준-Option1.GetCurrent(0,i)),Option1.GetATMCallRecent(i));
a = a+1;
}
Calldiff.sort(CompareForSort);
CallOrderCode1 = Calldiff[0][1];
CallOrderCode2 = Calldiff[1][1];
CallOrderCode3 = Calldiff[2][1];
CallOrderCode4 = Calldiff[3][1];
CallOrderCode5 = Calldiff[4][1];
}
var Putdiff = [];
if (풋기준 > 0)
{
a = 0;
for (var i = -Option1.lowersATM; i < Option1.uppersATM; i++)
{
Putdiff[a] = new Array(Math.abs(풋기준-Option1.GetCurrent(1,-i)),Option1.GetATMPutRecent(-i));
a = a+1;
}
Putdiff.sort(CompareForSort);
PutOrderCode1 = Putdiff[0][1];
PutOrderCode2 = Putdiff[1][1];
PutOrderCode3 = Putdiff[2][1];
PutOrderCode4 = Putdiff[3][1];
PutOrderCode5 = Putdiff[4][1];
}
var ChartSet = new ReqChartItem("00000000",1,CHART_PERIOD_MINUTE,10000,CHART_REQCOUNT_BAR,false,false);
var R11 = new ReqChartItem(CallOrderCode1,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R12 = new ReqChartItem(CallOrderCode2,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R13 = new ReqChartItem(CallOrderCode3,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R14 = new ReqChartItem(CallOrderCode4,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R15 = new ReqChartItem(CallOrderCode5,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R21 = new ReqChartItem(PutOrderCode1,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R22 = new ReqChartItem(PutOrderCode2,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R23 = new ReqChartItem(PutOrderCode3,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R24 = new ReqChartItem(PutOrderCode4,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var R25 = new ReqChartItem(PutOrderCode5,1,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var ReferDataSet = new Array(R11,R12,R13,R14,R15,R21,R22,R23,R24,R25);
Main.ReqChartEx(ChartSet,null,null,ReferDataSet);
}
}
function CompareForSort(a, b)
{
return( a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0 );
}
답변완료
스크립트 실행시에 오류보고에 에러 발생 코드
referenceError: handleError is not defined 와 같은 에러가 지속 발생 됩니다.
원인 파악을 못하겠네요.
스팟 스크립트 적용하고 3초뒤에 발생되네요.
--------------------------------------------이하 스팟 코드
var timer5 = 5; //5초
var 매수금 = 100000;
var 손절 = 0.95;
var 익절 = 1.05;
var OrderList = [];
var MKList = [];
var req;
var orderId; // 주문 ID 저장용 전역 변수
var orderNumber; // 주문 번호 저장용 전역 변수
var orderFailurePrice = {}; // 주문 실패 시점의 가격 저장용 객체
var initialPrice = {}; // 초기 주문 가격 저장용 객체
var currentPrice; // 현재가 저장용 변수
function Main_OnStart()
{
try {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[시작] 스팟 전략 시작");
//1번 타이머, 5초
Main.SetTimer(1, timer5*1000);
Main.MessageLog("[타이머] 5초 타이머 설정 완료");
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
Main.MessageLog("[초기화] 매수 종목 관리 배열 초기화 완료");
//스팟 시작시 잔고평가금액
V1 = A1.GetBalanceETCinfo(100);
Main.MessageLog("[잔고] 초기 평가금액: " + V1);
Main.MessageLog("--------------------------------------------");
} catch (error) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[에러] 스팟 시작 중 오류 발생: " + error.message);
Main.MessageLog("--------------------------------------------");
}
}
/**
* 주문 처리 함수
* @param {string} code - 종목코드
* @param {number} quantity - 주문수량
* @param {string} orderType - 주문타입 ('BUY' or 'SELL')
*/
function processOrder(code, quantity, orderType) {
var localOrderId; // 지역 변수로 주문 ID 선언
try {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[주문] 주문 처리 시작");
Main.MessageLog("- 종목코드: " + code);
Main.MessageLog("- 주문수량: " + quantity);
Main.MessageLog("- 주문유형: " + orderType);
// 시장가 주문으로 진행 (가격 0, 가격구분 1)
Main.MessageLog("[주문] 시장가 주문 진행");
if (orderType === 'BUY') {
// 매수 시장가 주문
localOrderId = A1.OrderBuy(code, quantity, 0, 1);
orderId = localOrderId; // 전역 변수에 할당
Main.MessageLog("[주문] 매수 시장가 주문 완료");
} else {
// 매도 시장가 주문
localOrderId = A1.OrderSell(code, quantity, 0, 1);
orderId = localOrderId; // 전역 변수에 할당
Main.MessageLog("[주문] 매도 시장가 주문 완료");
}
Main.MessageLog("--------------------------------------------");
return localOrderId;
} catch (error) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[에러] 주문 처리 중 오류 발생: " + error.message);
Main.MessageLog("--------------------------------------------");
return null;
}
}
/**
* 가격 상승률 체크 함수
* @param {string} code - 종목코드
* @returns {boolean} - 가격 상승률이 3% 이상이면 true
*/
function isPriceIncreased(code) {
if (!orderFailurePrice[code]) return false;
const currentPrice = MarketData.Ask(1);
const priceIncrease = ((currentPrice - orderFailurePrice[code]) / orderFailurePrice[code]) * 100;
return priceIncrease >= 3;
}
/**
* 주문 응답 처리
* @param {Object} OrderResponse - 주문 응답 객체
*/
function Main_OnOrderResponse(OrderResponse) {
try {
if (OrderResponse.orderID === orderId) {
orderNumber = OrderResponse.orderNum;
// 주문 실패 시 시장가로 재시도
if (OrderResponse.orderResult === 'FAIL') {
const code = OrderResponse.code;
const quantity = OrderResponse.count;
const orderType = OrderResponse.orderType;
if (orderType === 'BUY') {
// 매수 주문 실패 시 시장가로 재시도
A1.OrderBuy(code, quantity, 0, 1);
Main.MessageLog(code + " 주식을 시장가로 매수합니다.");
} else {
// 매도 주문 실패 시 시장가로 재시도
A1.OrderSell(code, quantity, 0, 1);
Main.MessageLog(code + " 주식을 시장가로 매도합니다.");
}
}
}
} catch (error) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[에러] 주문 응답 처리 중 오류 발생: " + error.message);
Main.MessageLog("--------------------------------------------");
}
}
function Main_OnTimer(nEventID)
{
try {
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) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[타이머] 이벤트 발생 - 현재시간: " + HHMMSS);
if (HHMMSS >= 90000 && HHMMSS < 151500) {
Main.MessageLog("[검색] 종목 검색 시작");
var searchResult = Main.ReqPowerSearch("power2");
if (searchResult === false) {
Main.MessageLog("[에러] 종목 검색 요청 실패");
} else {
Main.MessageLog("[검색] 종목 검색 요청 성공");
}
} else {
Main.MessageLog("[시간] 거래 시간이 아닙니다. (현재: " + HHMMSS + ")");
}
Main.MessageLog("--------------------------------------------");
}
if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS < 151500)
{
//계좌보유종수
var num = A1.GetTheNumberOfBalances();
//9시~15시 15분 사이
if (HHMMSS >= 90000 && HHMMSS < 151500)
{
//보유종목이 1개 이상
if (num >= 1)
{
//계좌평가금액이 스팟시작시 평가금액대비 5% 이상이면 전종목 전량매도
if (A1.GetBalanceETCinfo(100) >= V1*1.05)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
A1.SetBalance(i);
//수량이 있고 5%수익이거나 5% 손실이면 시장가 매도
if (A1.Balance.count > 0)
{
processOrder(A1.Balance.code, A1.Balance.count, 'SELL');
}
}
}
else //아니면 개별종목 5%익절, -5%손절 체크
{
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
A1.SetBalance(i);
//수량이 있고 5%수익이거나 5% 손실이면 시장가 매도
if (A1.Balance.count > 0 &&
(A1.Balance.current >= A1.Balance.avgUnitCost * 1.015 ||
A1.Balance.current <= A1.Balance.avgUnitCost * 0.98))
{
processOrder(A1.Balance.code, A1.Balance.count, 'SELL');
}
}
}
}
}
//15시 15분이후이면
if (HHMMSS >= 151500)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
A1.SetBalance(i);
//수량이 있고 5%수익이거나 5% 손실이면 시장가 매도
if (A1.Balance.count > 0)
{
processOrder(A1.Balance.code, A1.Balance.count, 'SELL');
}
}
}
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
}
} catch (error) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[에러] 타이머 이벤트 처리 중 오류 발생: " + error.message);
Main.MessageLog("--------------------------------------------");
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
try {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[검색결과] 수신된 종목 수: " + nCount);
Main.KillTimer(1);
OrderList = [];
if (nCount >= 1)
{
if (MKList.length == 0)
{
OrderList = aItemList;
Main.MessageLog("[검색결과] 신규 종목 목록 설정 완료");
}
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]);
}
}
Main.MessageLog("[검색결과] 기존 종목 제외 후 남은 종목 수: " + OrderList.length);
}
}
if (OrderList.length == 0)
{
Main.MessageLog("[검색결과] 처리할 종목이 없습니다. 5초 후 재시도");
Main.SetTimer(1, timer5*1000);
}
else
{
req = 0;
Main.MessageLog("[검색결과] 첫 번째 종목 시세 조회 시작: " + OrderList[req]);
Main.ReqMarketData(OrderList[req]);
}
Main.MessageLog("--------------------------------------------");
} catch (error) {
Main.MessageLog("--------------------------------------------");
Main.MessageLog("[에러] 종목 목록 처리 중 오류 발생: " + error.message);
Main.MessageLog("--------------------------------------------");
Main.SetTimer(1, timer5*1000); // 에러 발생 시 5초 후 재시도
}
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == OrderList[req])
{
MKList.push(MarketData);
// 계좌에 같은 종목이 있는지 확인
if (!IsStockInAccount(MarketData.code)) {
// 계좌에 없는 경우에만 매수
const quantity = Math.floor(매수금/MarketData.Ask(1));
if (quantity > 0) {
processOrder(MarketData.code, quantity, 'BUY');
}
Main.MessageLog(MarketData.code + " 주식을 매수합니다.");
} else {
Main.MessageLog( 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, timer5*1000);
}
}
}
function IsStockInAccount(stockCode) {
// 계좌에 해당 종목이 있는지 확인하는 함수
var numberOfBalances = A1.GetTheNumberOfBalances();
for (var i = 0; i < numberOfBalances; i++) {
A1.SetBalance(i);
if (stockCode == A1.Balance.code) {
return true; // 계좌에 같은 종목이 있으면 true 반환
}
}
return false; // 계좌에 같은 종목이 없으면 false 반환
}