예스스탁
예스스탁 답변
2014-09-02 15:12:29
안녕하세요
예스스탁입니다.
아래 내용 참고하셔서 수정보완해 사용하시기 바랍니다.
해외선물 골드의 경우 1계약 증거금을 수식안에서 계산할수 없습니다.
해당 상품의 경우 거래소에서 1계약 증거금을 발표하는데
수량,변동성등 많은 변수값으로 계산되어서 나오게 됩니다.
계산식에 필요한 요소들에 대한 값이 제공되지 않고 및 정확한 계산방법을 알수가 없습니다.
아래수식에서는 5060달러로 지정했습니다.
아래와 같은 내용으로 작성했습니다.
매수신호 발생하면
1. 매수신호가 발생하고 진입주문전에 사용할 모든 배열변수은 -1이 기초값입니다.
2. 주문가능금액의 30%에 해당하는 수량을 계산하고
3. 현재가에서 Diff틱 간격으로 아래로 해당 수량만큼 주문을 냅니다.
4. 이때 주문아이디는 배열변수(BEntryID)에 저장합니다. 0번방부터 순서에 따라 저장됩니다.
5. 주문응답이 들어오면 주문아이디로 구분해 같은 방에 주문번호(BEntryNum)를 저장합니다.
6. 체결이 되면 BEntryNum의 해당방의 값을 0으로 셋팅합니다. BFill은 1씩 저정합니다.
매수청산 신호가 발생하면
1. BEntryNum배열방에 1이상의 값이 저장이 되어 있으면 해당 주문번호는 취소합니다.
2. 진입체결된 수량(BFill)만큼 현재가를 기준으로 Diff간격으로 위로 매도주문을 합니다.
3. 주문아이디는 BExitID에 0번방부터 순서대로 저장하고
4. 주문응답이 들어오면 BExitNum의 동일방번호에 주문번호를 저장합니다.
5. 체결이 되면 해당 값은 0으로 셋팅합니다.
매도신호가 발생하면
1. BExitNum의 각 방의 값이 1이상이면 해당주문번호 취소합니다.
2 취소주문을 하고 주문응답이 들어오면 시장가로 매도합니다.
#지정가에서 시장가로 정정이 되지 않으므로 취소하고 시장가로 매도주문을 내야합니다.
프로그램이 종료되면
필요한 값을 내부파일에 저장합니다.
다시 스팟이 시작이 될때
내부파일에 저장된 BStep값이 0이거나 값이 없으면 기본수식대로 가고
1이상이면 저장된 값을 불러와 변수에 저장해서 이어가게 됩니다.
예스스팟 수식답변은 단순 가이드입니다.
답변으로 작성상 흐름 참고하셔서 수정보완해 사용하시기 바랍니다.
var Dollar = 5060;
var Vol, Diff, Bfill;
var BEntryID = new Array(50);
var BEntryNum = new Array(50);
var BExitID = new Array(50);
var BExitNum = new Array(50);
var BxCancel, BEntryName;
function Main_OnStart()
{
var BS = Main.GetUserValue("BStep");
//내부파일 BStep의 값이 없거나 0이면
if (BS== "" || BS == 0)
{
BStep = 0;//BStep은 0으로 시작
}
else//1이상이면
{
//각 내부파일의 변수값을 스팟의 변수에 옮김
BStep = BS;
BFill = Main.GetUserValue("BFill")
BxFill = Main.GetUserValue("BxFill")
BEntryName = Main.GetUserValue("BEntryName")
//기존 저장된 배열변수의 값을 동일변수에 다시 할당
BEntryID = JSON.parse(Main.GetUserValue("BEntryID"));
BEntryNum = JSON.parse(Main.GetUserValue("BEntryNum"));
BExitID = JSON.parse(Main.GetUserValue("BExitID"));
BExitNum = JSON.parse(Main.GetUserValue("BExitNum"));
}
}
function Chart1_OnRiseSignal(Signal)
{
if (Signal.signalKind == 1)
{
//매수~매수청산까지 사용할 배열변수의 모든 방의 값을 -1로 초기화
//매수진입주문 아이디
//매수진입주문 번호
//매수청산주문 아이디
//매수청산주문 번호
//매수청산취소 아이디
for(var i = 0; i < vol; i++)
{
BEntryID[i] = -1;
BEntryNum[i] = -1;
BExitID[i] = -1;
BExitNum[i] = -1;
}
//주문가능금액의 30% 수량
Vol = Math.floor((Account1.GetBalanceETCinfo(8)*0.3)/Dollar);
BEntryName = Signal.name;
if (EntryName == "a")//신호명이 a일때
Diff = 5;
else
Diff = 10;
//진입주문 체결횟수를 저장할 변수
BFill = 0;
//매수청산주문 체결횟수를 저장할 변수
BxFill = 0;
var Price = MarketData1.current;
//수량이 1이상이면 계산한 수량만큼만 루프
if (Vol >= 1)
{
BStep = 1;
//현재가 기준으로 Diff틱 간격으로 아래로 주문
for(var i = 0; i < Vol; i++)
{
BEntryID[i] = Account1.OrderBuy(MarketData1.code, 1, Price-(MarketData1.GetTickSize()*Diff)*i,2);
}
}
}
if (BStep == 1 && Signal.signalKind == 2)
{
BStep = 2;
//BEntryNum의 각 배열방에 값이 0이 아니면 해당 주문 취소
for(var i = 0; i < Vol; i++)
{
if (BEntryNum[i] > 0)
{
Account1.OrderCancel(BEntryNum[i]);
}
}
//진입 체결수량이 0개 이상이면
if (BFill > 0)
{
//현재가 기준으로 diff틱수 만큼 증가하며 체결수량만큼 주문
var Price = MarketData1.current;
for(var i = 0; i < Bfill; i++)
{
BExitID[i] = Account1.OrderSell(MarketData1.code, 1, Price+(MarketData1.GetTickSize()*Diff)*i,2);
}
}
}
//매도신호가 발생하고 매수진입체결갯수보다 매수청산체결갯수가 작으면
if (Signal.signalKind == 3)
{
//매수청산 중 주문번호값이 0이 아닌 주문은 취소
if (BFill > 0 && BFill > BxFill)
{
for(var i = 0; i < BFill; i++)
{
if (BexitNum[i] > 0)
{
BxCancel = Account1.OrderCancel(BexitNum[i]);
}
}
}
}
}
function Main_OnOrderResponse(OrderResponse)
{
//주문응답이 들어오면 EntryNum의 동일배열방에 주문번호 저장
for(var i = 0; i < Vol; i++)
{
if (OrderResponse.orderID == BEntryID[i] )
{
BEntryNum[i] = OrderResponse.orderNum;
}
}
//주문응답이 들어오면 BExitNum의 동일배열방에 주문번호 저장
for(var i = 0; i < BFill; i++)
{
if (OrderResponse.orderID == BExitID[i] )
{
BExitNum[i] = OrderResponse.orderNum;
}
}
//매수청산 취소주문 주문응답이 수신되면 시장가로 매도주문
if (OrderResponse.orderID == BxCancel)
{
Account1.OrderSell(MarketData1.code, 1,0,1);
}
}
function Main_OnNotifyFill(NotifyFill)
{
//체결되면 해당 주문번호를 0으로 변경
for(var i = 0; i < Vol; i++)
{
if (NotifyFill.orderNum == BEntryNum[i] )
{
BEntryNum[i] = 0;
BFill = BFill+1;
}
}
for(var i = 0; i < BFill; i++)
{
if (NotifyFill.orderNum == BExitNum[i] )
{
BExitNum[i] = 0;
BxFill = BxFill+1;
}
}
}
//종료시 변수 저장
function Main_OnClose()
{
Main.SetUserValue("BStep",BStep);
Main.SetUserValue("BFill",BFill);
Main.SetUserValue("BxFill",BxFill);
Main.SetUserValue("BxFill",BEntryName);
Main.SetUserValue("BEntryID", JSON.stringify(BEntryID));
Main.SetUserValue("BEntryNum", JSON.stringify(BEntryNum));
Main.SetUserValue("BExitID", JSON.stringify(BExitID));
Main.SetUserValue("BExitNum", JSON.stringify(BExitNum));
}
//수식에 사용된 JSON객체에 대해서는 자바스크립트 서적이나
//자유게시판의 890번 글 참고하시기 바랍니다.
즐거운 하루되세요
> gt 님이 쓴 글입니다.
> 제목 : 스팟문의
> 스팟문의드립니다.
해외선물 골드 기준으로 현재 잔고금액의 30%에서 최대주문가능 계약수를 구하는 방법을 알고 싶습니다.
예로 10억의 자금이 있다고 할때 30%인 3억으로 최대가능 계약수를 구한뒤 매수신호가 발생하면 3억으로 10틱 차이로 주문을 쫘악 내고 싶습니다. 만약 3억으로 10계약 매수가능하다고 할때, 현재가가 1300.00 이라고 하면 1300.00에 한계약, 1299.0 1계약, 1298.0 1계약 ~ 1290.0 1계약으로 모두 10계약 매수주문을 냅니다.
여기서 A신호일때는 호가를 5틱 차이로 주문하고, B신호일때는 호가를 10틱차이로 주문을 합니다.
각각의 주문은 배열을 사용해서 주문번호를 기억합니다.
매수청산신호가 발생하면 미체결 진입은 모두 취소시키고, 마찬가지로 진입된 수량을 A신호명일때는 10틱차이로 매도호가에 깔고, B청산신호일때는 5틱차이로 매도호가에 깝니다.
이후 시간이 지나 만약 미체결 수량이 잔고에 있고 매도신호가 발생하면 시장가로 모두 매수청산합니다.
정전이나 예스스팟이 갑작스럽게 종료되는 것을 예방하기 위해 종료시 포지션 진입유무, 포지션, 수량, 진입신호명 등의 정보를 기억하고 있다가, 다시켰을때 이 데이타를 이용했으면 합니다.
요청사항이 많은데 도움주시면 너무 감사하겠습니다.