답변완료
ELW 관련 수식문의("[01165] 주식워런트증권 지정가호가 매매만 가능합니다")
아래의 수식으로 현물거래를하다가 ELW 거래에 적용해보니 아래와 같은 에러 메시지가 뜹니다.
"[01165] 주식워런트증권 지정가호가 매매만 가능합니다"
그래서 가격 구분을 지정가로 바꾸고, 가격을 직접입력해서 해봤는데도 계속 주문 가격이 0으로 나가서 거래가 되질 않네요. 수식상의 어디를 수정하면 되는지요??
function Chart1_OnRiseSignal(Signal)
{
//buy신호발생
if (Signal.signalKind == 1)
{
//신호종목 잔고 셋팅
Account1.SetBalance(Main.GetOrderCode(Signal.code),0);
//보유수량이 없으면
if (Account1.Balance.count == 0)
{
//10주 시장가로 매수
Account1.OrderBuy(Main.GetOrderCode(Signal.code), 10, 0,1);
}
//보유수량이 있다면
else if (Account1.Balance.count > 0)
{
//현재가가 평균단가 대비 10% 하락시 보유수량+10주 시장가로 매수
if (Account1.Balance.current < Account1.Balance.avgUnitCost*0.9)
{ Account1.OrderBuy(Main.GetOrderCode(Signal.code), Account1.Balance.count +10, 0,1);
}
//현재가가 평균단가 대비 3% 이상 상승시 전량매도
if (Account1.Balance.current > Account1.Balance.avgUnitCost*1.03)
{ Account1.OrderSell(Main.GetOrderCode(Signal.code), Account1.Balance.count, Account1.Balance.current,0)
}
}
}
2016-12-13
2097
글번호 224061
답변완료
수식문의
올려져 있는식 조금 수정해서 사용중입니다.
0. 며칠 돌려보니 문제점이 좀 있습니다.
종목검색된후 EntryItem에 하나하나 쌓이는데, 예스스팟을 재가동한다던지, YT를 재접속할 경우 EntryItem에 쌓인 종목들이 모두 없어집니다. 따라서 Start()에서 현재 잔고에 있는 종목들을 먼저 파악후 EntryItem에 넣어주는 작업 등이 선행되어야 할 듯 합니다. EntryObject, EntryPrice 등의 정보도 ....더 좋은 방법 있으면 알려주시면 감사하겠습니다. 파일로 저장해서 가지고 있는 방법보다 잔고확인이 더 좋을 듯 싶은데...
그리고 Req의 사용 목적은 무엇인가요? 어디 선언된 곳도 없는데... DataReq는 종목데이타를 요청했는지 구분하려고 하는 거 같고...
1. 검색되는 종목을 모두 동적으로 1분차트 생성하고, AA이평선지표 적용, AA지표 20MA를 -2틱으로 깨면 보유중인 종목 중 해당 종목을 강제청산하고 미체결주문이 있을 경우 취소하고자 합니다. 이후 강제청산된 종목은 동적생성된 차트를 제거합니다. 수식부탁드립니다. 혹 동적으로 차트 생성하지 않고도 AA지표의 20MA를 계산하여 적용가능한지요? 만약 가능하다면 이 방법으로 기술부탁드립니다.
참고로 확장차트는 시스템을 적용하지 않고 오직 청산이나 손절의 목적으로 사용하려고 합니다.
2. 종목검색이후 매수주문을 2번에 걸쳐 하는데, 하나는 매도호가 1호가에 하나는 매수호가 3호가에 주문을 넣습니다. 만약 5분후 주문 체결이 안된것이 있으면 취소하고자 합니다.
3. 잔고와 시세가 변경되는 걸 감시하면서 진입된 종목명, 수량, 진입시간, 진입이후 최고가, 진입이후 최고수익률, 청산시간, 최종수익률을 엑셀에 기입하고 당일 모니터링하고자 합니다. 날짜별로 엑셀시트를 변경하여 기록으로 남기고 싶습니다. 수식을 추가부탁드립니다.
4. 매도#2 부분이 정상적으로 작동되지 않더군요. 진입이후 최고가 대비 3% 빠지면 청산하는 것인데, 어떤 종목은 진입하자마자 청산이 되더군요. 관찰해보니 고가대비 3%하락하면 진입했다가 바로 청산되더군요.
5. 시간여력이 되신다면 주석도 부탁드리겠습니다. 추후 많은 도움이 될 듯 합니다.
6. SendInterest() 함수와 반대로, 관심종목에 있는 종목을 삭제 또는 편입된 종목을 체크하는 기능은 없는지요?
다소질문이 많습니다. 아직 프로그래밍이 미숙해서 도움요청을 드립니다.
바쁘시겠지만 부탁드립니다.
var EntryMoney; // 총 예수금
var ItemList; // 종목검색후 종목리스트 저장변수
var Count; // 종목검색후 종목수 저장변수
var EntryObject = []; // 종목객체 저장
var EntryItem = []; // 종목코드 저장
var EntryHH = []; // 종목최고가 저장
var EntryPrice = []; // 종목진입가 저장
var LossCnt = []; // ?
var EntryCnt = 0; // ?
var RcvData = 0; // ?
var Search = false; // 종목검색 여부
var DataReq = false; // ?
var DayX = false; // ?
//스팟시작
function Main_OnStart()
{
//Main.MessageLog("----------------------------------------------------------------------------------------");
Main.MessageLog("+STOCK FIND GETs READY!");
//Main.MessageLog("----------------------------------------------------------------------------------------");
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();
Main.SetTimer(1, 5000); // 타이머 설정 2s
Search = false;
DataReq = false;
DayX = false;
RcvData = 0;
// 계좌 예수금 조회
EntryMoney = Math.floor(Account1.GetBalanceETCinfo(0));
}
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 (HHMMSS > 090100 && HHMMSS < 152000)
{
//1번 타이머동작하면 사용자검색조건 실행
if (nEventID == 1 && Search == false)
{
Main.MessageList("검색요청");
Main.ReqPowerSearch("#PowerSearch");
Req = 0;
Search = true;
DataReq = false;
}
if (nEventID == 2 && Req == Count)
{
Main.MessageList("요청종료");
Search = false;
Main.KillTimer(2);
}
if (nEventID == 2 && Req < Count && Search == true && DataReq == false)
{
Main.MessageList("요청전 EntryItem: ", EntryItem);
var Entry = false;
for (var i = 0; i < EntryItem.length; i++)
{
if (EntryItem[i] == ItemList[Req])
{
Entry = true;
}
}
if (Entry == false)
{
Main.ReqMarketData(ItemList[Req], 0, 0);
Main.MessageList("요청: ",ItemList[Req],Req);
}
if (Entry == true)
{
Main.MessageList("요청x: ",ItemList[Req]);
}
Req = Req + 1;
}
}
}
//종목검색이 완료
function Main_OnRcvItemList(aItemList, nCount)
{
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();
//검색종목수가 1개 이상이면
if (nCount >= 1 && DataReq == false)
{
ItemList = aItemList;
Count = nCount;
Main.MessageList("검색완료: ", ItemList);
//종목객체 생성 요청
var Entry = false;
for(var i = 0; i < EntryItem.length; i++)
{
if (EntryItem[i] == ItemList[Req])
{
Entry = true;
}
}
if (Entry == false)
{
DataReq = true;
Main.ReqMarketData(ItemList[Req], 0, 0);
Main.MessageList("요청 마켓데이타: ", ItemList[Req], Req);
// 시세 관심종목에 보내기
Main.SendInterests("관심시세[" + YYYYMMDD + "]", aItemList, true); // true: 종목추가, false: 종목대체
//Main.MessageLog("----------------------------------------------------------------------------------------");
Main.MessageLog("+Send Interests [" + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + "]");
//Main.MessageLog("----------------------------------------------------------------------------------------");
}
if (Entry == true)
{
DataReq = false;
Main.MessageList("잔고편입중 요청안함: ", ItemList[Req]);
}
Req = Req + 1;
Main.SetTimer(2, 5000); //간격(1초)
}
else
{
Main.MessageList("검색종목 없어 5초후 재검색");
Search = false;
}
}
//요청한 종목객체가 생성되면
function Main_OnRcvMarketData(MarketData)
{
EntryItem[RcvData] = MarketData.code;
EntryObject[RcvData] = MarketData;
Account1.SetBalanceItem(MarketData.code,0);
//1주 단위일 경우
Main.MessageList("종목수신:" ,EntryObject[RcvData]);
if (Account1.Balance.count == 0)
{
var Vol = 0;
Vol = Math.floor(EntryMoney / EntryObject[RcvData].Ask(5));
Main.MessageList("종목수량:", EntryMoney, Vol);
if (Vol > 0)
{
EntryHH[RcvData] = EntryObject[EntryCnt].current;
EntryPrice[RcvData] = EntryObject[EntryCnt].current;
LossCnt[RcvData] = 0;
Main.MessageList("주문:",EntryObject[RcvData].code);
// 매도 1호가에 주문접수
Account1.OrderBuy(EntryObject[RcvData].code, 1, EntryObject[RcvData].Ask(1), 0);
}
}
RcvData = RcvData + 1;
DataReq = false;
}
//생성된 종목들의 시세수신
function Main_OnUp*dateMarket(sItemCode, lUp*dateID)
{
var d = new Date();
var HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds();
//15시 19분에 잔고에 있는 종목 전량 청산(당일청산)
if (DayX == false && HHMMSS >= 151900 && RcvData >= 1)
{
DayX = true;
// 타이머 삭제
Main.KillTimer(1);
var num = Account1.GetTheNumberOfBalances();
for(var i = 0; i < num; i++)
{
Account1.SetBalanceIndex(i);
// 매도
if (Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1);
}
// 매수포지션이면
if (Account1.Balance.position == 2)
{
// 시장가 청산
Account1.OrderSell(Account1.Balance.code, Account1.Balance.count,0,1);
Main.MessageList("매도#1: ", Account1.Balance.code);
}
}
}
if (lUp*dateID == 20001 && HHMMSS < 153000 && RcvData >= 1)
{
for(var i = 0; i < EntryItem.length; i++)
{
if (sItemCode == EntryObject[i].code)
{
//진입이후 최고가
if (EntryObject[i].current > EntryHH[i])
EntryHH[i] = EntryObject[i].current;
/* //진입이후 최고가 -3%
if (EntryObject[i].current <= EntryHH[i]*0.97)
{
Account1.SetBalance(EntryObject[i].code , 0);
if (Account1.Balance.count > 0)
{
//Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, EntryObject[i].Bid(5),0);
Main.MessageList("매도#2: ", Account1.Balance.code);
}
}*/
//상한가 청산
if (EntryObject[i].current >= EntryObject[i].limitUp)
{
Account1.SetBalance(EntryObject[i].code, 0);
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, EntryObject[i].Bid(5),0);
Main.MessageList("매도#3: ", Account1.Balance.code);
}
}
}
}
}
}
2016-12-15
2445
글번호 224049
답변완료
수식 문의 드립니다.
안녕하세요
당일청산 선물신호 시스템 을 이용한, 아래 스팟수식으로 당일손실제한(1.0 PT)
전량 청산할경우, 당일 추가 선물신호가 발생해도 추가 진입이 안되도록 수정
요청 드립니다.
(스팟수식으로 당일손실제한정산 될 경우, PT 청산 메시지 출력 요청 드림니다)
감사합니다.
스팟수식요류
if (Signal.signalKind == 3 sumPL > 당일손실제한) => ReferenceError 오류
=> if (Signal.signalKind == 3, sumPL > -1.0) 수정 확인 점검 요청드림니다.
스크립트 객체설정
차트객체 추가 --> 속성에서 객체명은 Chart1, 아이디 연결
계좌객체 추가 --> 속성에서 객체명은 Account1, 계좌번호 지정
종목객체 추가 --> 속성에서 객체명은 MarketData1, 주문낼 종목으로 지정
입력변수 추가 --> 속성에서 변수명은 당일손실제한, 초기값 음수로 지정, 데이터형 숫자
var sumPL; -1.0 //당일손실제한 1.0 PT 설정
var BuyID, BxID, SellID,SxID;
var BuyNum, BxNum, SellNum,SxNum;
var BuyAvg,SellAvg;
var EntryStart,Dayloss,sumPL,T;
function Main_OnStart()
{
sumPL = 0;
T = 0;
EntryStart = false;
Dayloss = false;
Main.SetTimer(1, 5000);
}
//차트에서 신호나오면 MarketData1 종목에 대해 주문
function Chart1_OnRiseSignal(Signal)
{
//매수진입신호 발생
if (Signal.signalKind == 1 && Dayloss == false)
{
BuyID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), Signal.count,MarketData1.Ask(3), 0);
EntryStart = true;
}
//매수청산신호 발생
if (EntryStart == true && Signal.signalKind == 2)
{
//매수진입 미체결 있으면 취소
Account1.SetUnfill(BuyNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(BuyNum);
}
//잔고셋팅해 매수포지션 있으면 잔고수량만큼만 청산
Account1.SetBalance(Main.GetOrderCode(MarketData1.code), 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
{
//매수포지션 잔고 평단가 저장
BuyAvg = Account1.Balance.avgUnitCost;
BxID = Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,MarketData1.Bid(3), 0);
T = 1;
}
}
//매도진입신호 발생
if (Signal.signalKind == 3 sumPL > 당일손실제한) <============= 수식요류메세지
{
SellID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), Signal.count,MarketData1.Bid(3), 0);
EntryStart = true;
}
//매도청산신호 발생
if (EntryStart == true && Signal.signalKind == 4)
{
//매수진입 미체결 있으면 취소
Account1.SetUnfill(SellNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(SellNum);
}
//잔고셋팅해 매도포지션 있으면 잔고수량만큼만 청산
Account1.SetBalance(Main.GetOrderCode(MarketData1.code), 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
//매도포지션 잔고 평단가 저장
SellAvg = Account1.Balance.avgUnitCost;
SxID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), Signal.count,MarketData1.Ask(3), 0);
T = -1;
}
}
}
function Main_OnOrderResponse(OrderResponse)
{
if (OrderResponse.orderID == BuyID)
BuyNum = OrderResponse.orderNum;
if (OrderResponse.orderID == BxID)
BxNum = OrderResponse.orderNum;
if (OrderResponse.orderID == SellID)
SellNum = OrderResponse.orderNum;
if (OrderResponse.orderID == SxID)
SxNum = OrderResponse.orderNum;
}
function Main_OnNotifyFill(NotifyFill)
{
//매수청산신호의 체결이 수신되면
if (NotifyFill.orderNum == BxNum)
{
sumPL = sumPL +(NotifyFill.fillPrice-BuyAvg)*NotifyFill.fillCount;
}
//매도청산신호의 체결이 수신되면
if (NotifyFill.orderNum == SxNum)
{
sumPL = sumPL +(SellAvg-NotifyFill.fillPrice)*NotifyFill.fillCount;
}
}
function Main_OnTimer(nEventID)
{
if (EntryStart == true && T == 1)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code), 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
{
tempPL = sumPL+(Account1.Balance.current-Account1.Balance.avgUnitCost)*Account1.Balance.count;
if (tempPL <= 당일손실제한)
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,MarketData1.Bid(3), 0);
Dayloss = true;
}
}
}
if (EntryStart == true && T == -1)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code), 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
tempPL = sumPL+(Account1.Balance.avgUnitCost-Account1.Balance.current)*Account1.Balance.count;
if (tempPL <= 당일손실제한)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,MarketData1.Ask(3), 0);
Dayloss = true;
}
}
}
}
2016-11-25
2287
글번호 224044