답변완료
스팟 간단한 내용 검토요청
안녕하세요?
스팟수식 여쭤볼 곳이 없어서, 부득이 부탁드리고합니다.
아래 수식 목표는
단순 진입입니다. 차트에서 1계약 매수 / 매도 시그널 나오면 그대로 적용, 청산 신호 나오면 청산...
그런데 단순한 건데 이상하게 성능보고서와 다르게 청산이 되어도 잔고가 남아 있고... 오류가 있습니다.
검토요청드립니다.
청산시 잔고 없고, 신규 진입시 이전 물량 청산만 하면 됩니다.
다시 한 번 감사드립니다.
-----------------------------------------------------------------
//진입청산주문을 모두 스팟에서 내게 하셔야 합니다.
//차트에 시스템은 시험적용으로 적용하고
//신호가 발생하면 스팟에서 주문을 내고 추적해야 합니다.
//차트객체추가 --> 속성에서 객체명은 Chart1, 아이디 부여해 차트와 연결
//종목객체추가 --> 속성에서 객체명은 MarketData1, 차트와 동일종목으로 지정
//계좌객체추가 --> 속성에서 객체명은 Account1, 계좌번호 지정
// 시장가 주문으로 변경(1))
var BID,Bnum,BIDx,Bnumx;
var SID,Snum,SIDx,Snumx;
function Main_OnStart()
{
Main.MessageLog("시작");
T = 0;
}
function Chart1_OnRiseSignal(Signal)
{
//매수신호 발생하면 신호수량으로 현재가 매수주문
if (Signal.signalKind == 1)
{
T = 1;
//주문후 주문아이디
//주문번호로 미체결객체 셋팅
Account1.SetUnfillOrderNumber(Bnum);
//미체결 잔량이 있으면
if (Account1.Unfill.count > 0 && Account1.Unfill.code == Main.GetOrderCode(MarketData1.code))
{
//취소
Account1.OrderCancel(Bnum);
}
//잔고셋팅
Account1.SetBalanceItem(Main.GetOrderCode(MarketData1.code), 0);
//매도수량이 있으면 매도수량만큼 매수로 청산
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
BIDx = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), Account1.Balance.count,MarketData1.current, 1);
}
// 매수진입
BID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), Signal.count,MarketData1.current, 1);
}
if (Signal.signalKind == 2)
{
T = 0;
//주문번호로 미체결객체 셋팅
Account1.SetUnfillOrderNumber(Bnum);
//미체결 잔량이 있으면
if (Account1.Unfill.count > 0 && Account1.Unfill.code == Main.GetOrderCode(MarketData1.code))
{
//취소
Account1.OrderCancel(Bnum);
}
//잔고셋팅
Account1.SetBalanceItem(Main.GetOrderCode(MarketData1.code), 0);
//매수수량이 있으면 매도로 청산
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
{
SIDx = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), Account1.Balance.count, MarketData1.Bid(3), 1)
}
//매도 신호 수량만큼 진입
SID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), Signal.count, MarketData1.Bid(3), 1)
}
//매도신호 발생하면 신호수량으로 현재가 매도주문
if (Signal.signalKind == 3)
{
T = -1;
//잔고셋팅
Account1.SetBalanceItem(Main.GetOrderCode(MarketData1.code), 0);
//매수수량이 있으면 잔고만큼 매도로 청산
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
{
BIDx = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), Account1.Balance.count,MarketData1.current, 1);
}
}
if (Signal.signalKind == 4)
{
T = 0;
//Snum에 저장된 주문번호로 미체결객체 셋팅
Account1.SetUnfillOrderNumber(Snum);
//미체결 잔량이 있으면
if (Account1.Unfill.count > 0 && Account1.Unfill.code == Main.GetOrderCode(MarketData1.code))
{
//취소
Account1.OrderCancel(Snum);
}
//잔고셋팅
Account1.SetBalanceItem(Main.GetOrderCode(MarketData1.code), 0);
//매도수량이 있으면 잔고만큼 매수로 청산
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
SIDx = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), Account1.Balance.count, MarketData1.Ask(3), 1)
}
}
}
//주문응답수신
function Main_OnOrderResponse(OrderResponse)
{
//BID와 아이디가 같은 주문응답이면
if (OrderResponse.orderID == BID)
{
//매수주문번호를 Bnum에 저장
Bnum = OrderResponse.orderNum;
}
//SID와 아이디가 같은 주문응답이면
if (OrderResponse.orderID == SID)
{
//매도주문번호를 Snum에 저장
Snum = OrderResponse.orderNum;
}
//BIDx와 아이디가 같은 주문응답이면
if (OrderResponse.orderID == BIDx)
{
//매수주문번호를 Bnum에 저장
Bnumx = OrderResponse.orderNum;
}
//SID와 아이디가 같은 주문응답이면
if (OrderResponse.orderID == SIDx)
{
//매도주문번호를 Snum에 저장
Snumx = OrderResponse.orderNum;
}
}
2021-08-19
2336
글번호 225532
답변완료
매수매도 수량 확인후 청산
매수매도가 체결되었는지 확인후 매수매도 청산하기 위해서 아래 프로그램을 사용하고자 합니다.
해외선물에서 지정가,+/_2호가로 매수매도를 위해서
BID = Account1.OrderBuy(Main.GetOrderCode(Signal.code),2,MarketData1.Bid(2),2);
SID = Account1.OrderSell(Main.GetOrderCode(Signal.code),2,MarketData1.Ask(2),2);
로 하였는데 맞게 된 건가요?
====================== 예제 ===================
var BID,SID,BNum,SNum;
function Main_OnStart()
{
Main.MessageList("Start")
}
function Chart1_OnRiseSignal(Signal)
{
if (Signal.signalKind == 1)
{
BID = Account1.OrderBuy(Main.GetOrderCode(Signal.code),2,MarketData1.Bid(1),2);
Main.SetTimer(1,60000);
}
if (Signal.signalKind == 2)
{
Account1.SetUnfill(BNum);
if ( Account1.Unfill.count > 0 )
{
Account1.OrderCancel(Bnum);
}
Account1.SetBalance(Main.GetOrderCode(Signal.code), 2);
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
{
Account1.OrderSell(Main.GetOrderCode(Signal.code),Account1.Balance.count,MarketData1.Ask(1),0)
}
}
if (Signal.signalKind == 3)
{
SID = Account1.OrderSell(Main.GetOrderCode(Signal.code),2,MarketData1.Ask(2),2);
Main.SetTimer(2,60000);
}
if (Signal.signalKind == 4)
{
Account1.SetUnfill(SNum);
if ( Account1.Unfill.count > 0)
{
Account1.OrderCancel(Snum);
}
Account1.SetBalance(Main.GetOrderCode(Signal.code), 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Main.GetOrderCode(Signal.code),Account1.Balance.count,MarketData1.Bid(1),2)
}
}
}
function Main_OnOrderResponse(OrderResponse)
{
if (OrderResponse.orderID == BID)
{
BNum = OrderResponse.orderNum;
}
if (OrderResponse.orderID == SID)
{
SNum = OrderResponse.orderNum;
}
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
Main.KillTimer(1);
Account1.SetUnfill(BNum);
if (Account1.Unfill.count > 0)
{
BID = Account1.OrderReplacePrice(Bnum,MarketData1.Ask(4);
}
}
if (nEventID == 2)
{
Main.KillTimer(2);
Account1.SetUnfill(SNum);
if (Account1.Unfill.count > 0)
{
SID = Account1.OrderReplacePrice(Snum,MarketData1.Bid(4));
}
}
}
2021-08-12
2212
글번호 225524
답변완료
종목검색 삭제
안녕하세요.
아래 수식에서 PSearch 종목검색후 종목검색조건에서 제외되어 파워종목검색에서 사라진 종목도 여전히 스팟에 남아 있는데요.
조건에서 제외되어 파워종먹검색에서 사라진 종목들은 스팟에서 검색 업데이트시 제외되도록 수정 부탁드립니다.
var BL = [],req;
var CT = [],MK = [];
function Main_OnStart()
{
//처음 시작시 step은 0
step = 0;
//시작시점의 보유종목수
var num = Account1.GetTheNumberOfBalances();
//보유종목이 1개 이상이면 보유종목의 종목코드를 BL변수에 순차적으로 저장
if (num > 0)
{
BL = [];
for(var i = 0 ; i < num ; i++)
{
Account1.SetBalance(i);
BL.push(Account1.Balance.code);
}
Main.MessageList("BL : ",BL);
if (BL.length >= 1)
{
req = 0;
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10); // 최대진입횟수
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
Main.MessageList("차트객체요청 :",BL[req]);
}
}
else //보유종목이 없으면 바로 1분 타이머 시작
{
Main.MessageList("보유종목없음");
Main.SetTimer(1, 10000);//1번 타이머, 60초
}
}
function Main_OnRcvChartEx(ChartEx)
{
if (ChartEx.GetCode(1) == BL[req])
{
Main.MessageList("차트객체생성 :",ChartEx.GetCode(1));
CT.push(ChartEx);
Main.ReqMarketData(BL[req]);
Main.MessageList("종목객체요청 :",BL[req]);
}
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == BL[req])
{
Main.MessageList("종목객체생성 :",MarketData.code);
MK.push(MarketData);
req = req+1;
if (req < BL.length)
{
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10);
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
Main.MessageList("차트객체요청 :",BL[req]);
}
else
{
Main.SetTimer(1, 10000);//1번 타이머, 60초
Main.MessageList("보유종목차트생성완료",CT.length,MK.length);
}
}
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
//타이머 종료
Main.KillTimer(1);
Main.ReqPowerSearch("PSearch");
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
//검색된 종목이 없으면
if (nCount == 0)
{
//타이머 다시 셋팅
Main.SetTimer(1, 100000);//1번 타이머, 60초
}
//검색된 종목이 있으면
if (nCount >= 1)
{
//검색된 종목과 기존 만든 차트들의 종목코드를 비교해
//차트가 만들어 지지 않은 종목이면 BL변수에 종목코드 추가
BL = [];
for(var i = 0 ; i < aItemList.length ; i++)
{
var add = true;
for(var z = 0 ; z < CT.length ; z++)
{
if (aItemList[i] == CT[z].GetCode(1))
{
add = false;
break;
}
}
if (add == true)
{
BL.push(aItemList[i]);
}
}
Main.MessageList("BL : ",BL);
//차트 생성해야할 종목이 있으면 차트요청
if (BL.length >= 1)
{
req = 0;
//차트 요청
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10);
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
}
else //없으면 타이머 다시 셋팅
{
Main.SetTimer(1, 100000);//1번 타이머, 60초
}
}
}
2021-07-28
2595
글번호 225520
답변완료
문의드립니다.
안녕하세요. YL에서 도움을 많이 주셔서 시스템 구성을 개략적으로 마무리하고 이제 자동매매를 위해 예스스팟을 공부 중에 있습니다.
현재 현물/선물 거래를 동시에 하고 있어서 몇가지 질문을 드리고자 합니다.
1) 계좌 1에서 선물거래 중인데 수익금/손실금을 기준으로 계좌2에서 피라미딩 또는 헷지를 해보려고 합니다.
예를 들어
* 진입
계좌 1에서 300만원 수익이 난 경우, 매수/매도 수량 절반을 계좌2에서 반대로 진입하고, 600만원까지 수익이 증가하면 나머지 수량 절반을 계좌2에서 반대로 진입
* 청산
1. 계좌1 수익이 600만원 수익 후 300만원까지 수익이 감소하면 계좌 2 진입물량 절반 청산, 계좌1 수익이 300만원 수익 후 0까지 감소하면 계좌2 진입물량을 모두 청산.
2. 계좌1 진입물량이 모두 청산(잔고0)되면 계좌 2 진입물량도 모두 청산.
이렇게 가정하고 수식을 짜봤습니다.
var HCount1 = 0;
var HCount2 = 0;
var BaNumber = 0;
function Main_OnStart()
{
Main.MessageLog("시작")
//1초 타이머
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
//계좌 재조회
Account1.Refresh();
Account1.SetBalance(Account1.Balance.code,0);
BaNum = Account1.GetTheNumberOfBalances();
}
function Main_OnU*dateAccount(sAccntNum, sItemCode, lU*dateID)
{
if (Account1.number == sAccntNum && lU*dateID == 30000)
{
//현재 예탁자산총평가액과 전일예탁자산의 차이
var PL = Account1.GetBalanceETCinfo(10)-Account1.GetBalanceETCinfo(0);
//300만원 이상 수익인 경우
if (PL >= 3000000)
{
if (Account1.Balance.position == 1) // 계좌1 매도일 때 매수수량의 절반을 계좌2에서 매도
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count/2,0,1);
if (Account1.Balance.position == 2) // 계좌1 매수일 때 매도수량의 절반을 계좌2에서 매도
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count/2,0,1);
HCount1 = HCount1++; // 수익이 300만원 이상인 경우를 체크
}
//600만원 이상 수익
if (PL >= 6000000)
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count/2,0,1);
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count/2,0,1);
HCount2 = HCount2++; // 수익이 600만원 이상은 경우를 체크
}
if (HCount1 > 0 && HCount2 > 0 && PL<=3000000) // 수익이 600만원 이상 발생했다가 300만원까지 떨어진 경우
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account2.Balance.count/2,0,1); // 계좌2 매도수량의 절반 정리
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account2.Balance.count/2,0,1); // 계좌2 매도수량의 절반 정리
}
if (HCount1 > 0 && PL<=0) // 수익이 300만원 이상 발생했다가 0까지 떨어진 경우
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); // 계좌2 매도수량 정리
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count,0,1); // 계좌2 매수수량 정리
}
if (BaNum == 0) // 계좌1에 잔고가 없는 경우 매수/매도수량 정리(이미 Account1은 잔고가 없는 상황이라서 괄호안 내용으로는 맞지 않는 것 같습니다)
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account2.Balance.count,0,1);
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account2.Balance.count,0,1);
}
}
//타이머종료
Main.KillTimer(1);
}
2. 현물시스템 운용 중에 특정가격을 YL에서 매수 가격으로 세팅하고 Yesstop으로 매수 시, 하루에 한 번만 매수가 되는 것 같습니다.
yl에서는 분할매수를 하고 있으며 1) 통계목적 상으로, 신호가 나오면 수량을 달리해서 2~3회 동시 매수하고 있고, 2)가격을 달리해서 매수(같은 봉 또는 다른 봉에서 3-4회)하고 있습니다.
작성한 수식 중
=> if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0)
이 부분에서 count부분을 삭제하면 수차례 매수될 것으로 생각했는데 어떻게 수정해야되는지 가이드 부탁드립니다. 감사합니다.
var ItemList;
var Count;
var ReqCount;
var d;
var H;
function Main_OnStart()
{
Main.MessageLog("스팟시작");
d = new Date();
h=d.getDate();
//지정한 관심그룹의 종목수(관심그룹지정 필요)
Count = Main.GetItemCountOfInterest("스팟연습");
Main.MessageList("지정관심그룹 종목수 : ", Count);
ItemList = [];
//관심그룹 종목코드를 ItemList로 옮김
for(var i = 0 ; i < Count ; i++)
{
//관심그룹지정 필요
ItemList.push(Main.GetItemCodeInInterest("스팟연습", i));
}
Main.SetTimer(1, 500);
ReqCount = 0;
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
var ChartSet = new ReqChartItem(ItemList[ReqCount],15,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
/////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo)
var SystemSet = new SystemInfo("@@연습", YL_TYPE_NORMAL, null, null, null);
Main.ReqChartEx(ChartSet,SystemSet);
Main.MessageLog("확장차트생성_"+ItemList[ReqCount]);
ReqCount = ReqCount+1;
if (ReqCount == Count)
{
Main.KillTimer(1);
Main.MessageLog("종목검색완료");
}
}
}
//신호발생
function Main_OnRiseSignal(ChartEx, Signal)
{
//신호발생 종목에 대해 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(Signal.code),0);
//매수신호이고 잔고가 없을때만 매수 수정
if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0)
{
Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0);
Main.MessageLog("매수주문9");
}
if (Signal.signalKind == 2)
{
//전체미체결주문 갯수
var num = Account1.GetTheNumberOfUnfills();
//전체 미체결수 만큼 루프를 돌면서
for (var i = 0; i < num; i++)
{
//미체결을 하나씩 셋팅하고 Account1.GetTotalAmount(nCategory, nTradeKind)
Account1.SetUnfill(i);
//미체결종목이 신호종목과 같고 미체결수량이 있으면
if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
//잔고수량만큼만 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0);
Main.MessageLog("매도주문");
}
}
}
가이드 주시면 보완해 나가겠습니다.
노고에 항상 감사드립니다.
즐거운 주말 보내세요.
2021-07-30
2690
글번호 225515