리소스 로딩... 로딩...

네트워크 거래 전략

저자:선함, 2018-08-23 13:45:27, 업데이트:

네트워크 거래 전략 (www.fmz.com) 그리드 트레이딩의 기본 아이디어는 매우 간단합니다. 하나의 트레이드를 배치하는 대신, 우리는 그리드 패턴을 형성하는 여러 트레이드를 배치합니다. 일반적으로 이것들은 현재 가격 수준 주위의 스톱 또는 리미트 주문으로 입력되지만 항상 아닙니다.

네트워크 트레이딩이란 무엇인가요? 어떻게 작동할까요? 그리드 트레이딩은 시장 변동성에 대한 게임입니다. 트레이더들이 선호하는 두 가지 이유가 있습니다. 첫째는 시장 방향에 대한 확실한 예측을 할 필요가 없다는 것입니다.

두 번째는 변동적인 시장에서 잘 작동한다는 것입니다. 명확한 추세가 없는 시장에서는 이러한 조건이 외환 시장에서 매우 일반적입니다.

그리드 트레이딩 (Grid trading) 은 특정 그리드 패턴 내의 움직임을 기반으로 하는 기술 분석 거래의 일종이다. 그리드 트레이딩은 외환 거래에서 인기가 있다. 전반적으로 이 기술은 미리 정의된 기본 가격 이상의 일정 간격과 그 이하의 일정 일정 간격에서 구매 및 판매 주문을 배치하여 시장의 정상적인 가격 변동성을 활용하고자 한다. 이러한 구매 및 판매 주문은 일반적으로 10 또는 15 단위 간격으로 구간되어 거래 그리드를 만듭니다.

그리드는 방향을 사용자 정의할 수 있습니다

기본 거래: 먼저 사서 팔자.

그리드는 첫 번째 가격 아래의 가격으로 구매 주문을 보내기 시작합니다. 첫 번째 가격 (제2의 최신 구매 가격, 세 번째 최신 구매 가격...등) 에 따라가는 가격입니다. 각 구매 주문은 가격 간격 매개 변수로 분리됩니다. 미뤄진 주문의 수는 단일 양이며, 총 양이 채워질 때까지 전체 주문을 보낼 것입니다.

어떤 구매 주문이 완료 된 후, 프로그램은 구매 가격에 기초하여, 판매 가격에 가격 차이 매개 변수의 가격을 추가 하 고, 주문이 판매 된 후, 그 다음이 그리드 전략의 진행을 다시 시작 (검색, 배치 주문, 실행 될 때까지 기다립니다, 판매)

먼저 단축 판매를 하고 그 다음에는 커버를 위해 구매합니다. 이 작업은 바로 반대입니다.

이 전략의 가장 큰 위험은 시장 트렌드가 일방적으로 움직이고 가격 변동이 그리드를 초과할 때입니다.

다음 코드는 자동 스톱 손실과 움직임 기능을 가진 격자를 만들었습니다.

언급:

이 전략은 가상 대기 주문 디자인을 사용하여 대기 주문 수를 제한하기 위해 거래소에 많은 처리를 제공하며 문제를 유연하게 해결합니다.

그리드 로직은 디자인적으로 유연하고 구조적으로는 똑똑합니다.

이익과 손실 계산, 각 수치 통계 알고리즘은 참조로 사용할 수 있으며 각 상태 탐지 디자인은 엄격합니다. (BUG의 가능성을 최소화하기 위해)

소스 코드는 배울 가치가 있습니다.

더 자세한 내용은 다음을 참조하십시오:

https://www.fmz.com/strategy/112633

소스 코드:

` // 그리드는 방향을 사용자 정의 할 수 있습니다 // 기본 거래 운영: 먼저 구매하고 판매. // 그리드는 첫 번째 가격 아래의 가격에 구매 주문을 보내기 시작할 것입니다. // 첫 번째 가격 (두 번째 최신 구매 가격, 세 번째 최신 구매 가격...등) 에 의해. 각 구매 주문은 // 값 간격 매개 변수. 대기 주문의 수는 일량입니다. // 총량이 채워집니다. // 어떤 구매 주문이 완료 된 후, 프로그램은 구매 가격에 기초하여, 가격의 가격을 추가합니다 // difference 매각 가격에 매각 후, 순서가 판매 된 후, 그리고 다시이 진행을 시작 // 그리드 전략 (검사, 순서를 배치, 실행 될 때까지 기다립니다, 판매) // 먼저 짧은 판매를 하다가 커버를 구입: 작업은 바로 반대입니다 // 이 전략의 가장 큰 위험은 시장 추세가 일방적으로 움직이고 가격 변동이 그리드를 초과할 때입니다. // 다음 코드는 자동 스톱 손실과 움직임 기능을 가진 격자를 만들었습니다. // 댓글: // 전략은 가상 대기 주문 디자인을 사용 합니다. // 대기 주문, 그리고 유연하게 문제를 해결합니다. // 그리드 로직은 설계에서 유연하고 구조에서 똑똑합니다. // 이익과 손실 계산, 각 수치 통계 알고리즘은 참조를 위해 사용할 수 있습니다, 그리고 각 조건 탐지 설계 //는 엄격합니다. (BUG의 가능성을 최소화하기 위해) // 소스 코드는 배울 가치가 있습니다.

// 소스 코드: /* 인터페이스 매개 변수 (코드에서 글로벌 변수로 표시) OpType 그리드 방향 드롭다운 박스 (선택) 먼저 구매하고 판매합니다. FirstPriceAuto 초기 가격 자동 부울 (진/거짓) true 첫 번째 가격 (FirstPrice@!FirstPrice) 자동 초기 가격 숫자 (번호) 100 모든 번호 총 숫자 (수) 10 PriceGrid 가격 간격 숫자 (수) 1 가격차별 스프레드 숫자 (수) 2 양형 주문 크기 드롭다운 박스 (선택) 같은 금액을 구매하고 판매합니다. 양Once@AmountType==0 단일 거래 양 숫자 (수) 0.1 BAmountOnce@AmountType==1 구매 주문 크기 숫자 (수) 0.1 SAmountOnce@AmountType==1 판매 주문 크기 숫자 (수) 0.1 AmountCoefficient@AmountType==0 양의 차이는 문자열 (string) *1 AmountDot 소수점 숫자 (수) 3 EnableProtectDiff 스프레드 보호를 (진/거짓) false ProtectDiff@EnableProtectDiff 진입 스프레드 가격 보호 숫자 (수) 20 CancelAllWS stop 모든 대기 주문을 취소합니다 체크Interval 투표 간격 번호 숫자 (수) 2000 간격 실패 반복 시도 간격 수 (수) 1300 RestoreProfit 마지막 수익을 복원합니다. LastProfit@RestoreProfit 마지막 이익 숫자 (수) 0 ProfitAsOrg@RestoreProfit 마지막 이익은 평균 가격으로 계산됩니다. EnableAccountCheck 균형 검증을 활성화하십시오 부올리언 (진/거짓) true EnableStopLoss@EnableAccountCheck 오픈 중지 손실 부올리안 (진/거짓) 거짓 StopLoss@EnableStopLoss 최대 변동 손실 숫자 (수) 100 StopLossMode@EnableStopLoss 포스트 스톱 손실 작업 드롭다운 박스 (선택) 재활용 및 종료 EnableStopWin@EnableAccountCheck 취득을 켜라 부올리언 (진/거짓) 거짓 StopWin@EnableStopWin 최대 변동 수익 번호 유형 (번호) 120 StopWinMode@EnableStopWin 수익을 취한 후 운영 드롭다운 박스 (선택) 재활용 및 출구 AutoMove@EnableAccount검사자동 이동 부올어 (진/거짓) false MaxDistance@AutoMove 최대 거리 숫자 (수) 20 MaxIdle@AutoMove 최대 무동 (초) 숫자 (수) 7200 EnableDynamic 역동적인 대기 주문을 돌리는 것 부올어 (진/거짓) 거짓 DynamicMax@EnableDynamic 주문 만료 거리는 번호 (번호) 30 ResetData는 시작시 모든 데이터를 삭제합니다. 정밀 가격 소수점 길이 숫자 (수) 5 */

function hasOrder ((orderId, orderId) { // 매개 변수 순서에서 순서 ID가 있는 순서가 있는지 확인 for (var i = 0; i < orders.length; i++) { // 같은 id가 있는지 확인하기 위해 명령을 통과, 만약 그렇다면 true를 반환 if (order[i].Id == orderId) { true 를 반환합니다. } } false를 반환; // 모든 경로를 통과, 트리거가 없습니다. }

함수 취소Pending() { // 모든 대기 주문 함수를 취소 var ret = false; // 반환 성공 태그 변수를 설정 while (true) { // while 루프 if (ret) { // if ret is true then Sleep for a certain time if (ret) { // if ret is true then Sleep for a certain time if (ret) { // ret is true then Sleep for a certain time if (ret) { // ret is true then Sleep for a certain time 수면 (Interval) } var orders = _C(exchange.GetOrders); // API를 호출하여 교환이 실행하지 않은 주문 정보를 얻으십시오. if (orders.length == 0) { // 빈 배열이 반환되면 교환에는 실행되지 않은 명령이 없습니다. break; // while 루프에서 점프 }

    for (var j = 0; j < orders.length; j++) {              // Traverse the unfinished order array and use orders[j].Id one by one to cancel the order based on the index j.
        exchange.CancelOrder(orders[j].Id, orders[j]);
        ret = true;                                        // Once there is a cancel operation, ret is assigned a value of true. Used to trigger above Sleep, wait for re-exchange.GetOrders detection 
    }
}
return ret;                                                // return ret

}

함수 값ToString(값, pos) { // 문자열로 변환 값 var result = ; // 반환을 위해 빈 문자열 결과를 선언 if (typeof(pos) === undefined) { // pos 매개 변수가 전달되지 않으면 pos에 0의 값을 부여합니다. pos = 0; } for (var i = pos; i < values.length; i++) { // 전달된 pos에 따라 프로세스 값 배열 if (i > pos) { // 첫 번째 루프 외에도, 결과 문자열 뒤에 공간을 추가 결과 += } if (values[i] === null) { // If values (function argument list array) the current indexs element is null then result adds null string if (values[i] === null) { // If values (function argument list array) the current indexs element is null then result adds null string if (values[i] === null) { // 만약 값 (함수 논증 목록 배열) 의 현재 인덱스s 요소가 null이라면 그 결과 null 문자열이 추가됩니다 결과 += null; } else if (typeof(values[i]) == undefined) { // 만약 정의가 되지 않는다면, undefined을 추가합니다 결과 += 불정정; } else { // 나머지 타입은 스위치 검출을 별도로 수행합니다 스위치 (values[i].constructor.name) { // 타입 이름인 값[i]의 생성자의 이름 속성을 확인 케이스 : 케이스 번호: 대수 string: 부문 기능 : result += values[i].toString(); // 날짜 타입, 숫자 타입, 문자열 타입 또는 함수 타입이라면 toString 함수를 호출하고 문자열로 변환한 다음 추가합니다 휴식 기본값: result += JSON.stringify(values[i]); // 다른 경우, JSON.stringify 함수를 사용하여 JSON 문자열로 변환합니다. 휴식 } } } 반환 결과; // 반환 결과 }

함수 트레이더 ((() { // 트레이더 함수, 폐쇄를 사용. var vId = 0; var orderBooks = []; // 주문서 var hisBooks = []; // 역사 순서 책 var orderBooksLen = 0; this.Buy = function ((가격, 금액, 추가) { // 구매 기능, 매개 변수: 가격, 양, 확장 정보 if (typeof(extra) === undefined) { // 만약 매개 변수 extra가 전달되지 않는다면, 즉 typeof는 undefined를 반환합니다 extra = ; // extra에 빈 문자열을 할당 다른 것 extra = valuesToString ((arguments, 2); // this.Buy 함수를 호출할 때 전달된 논증 논증들은 valuesToString 함수에 전달됩니다. } vId++; // var orderId = V + vId; // orderBooks[orderId] = { // orderId 속성을 orderbook 배열에 추가하고 구성된 객체로 초기화합니다. 타입: ORDER_TYPE_BUY, // 구성된 객체 타입 속성: 타입 구매 상태: ORDER_STATE_PENDING, // 대기 상태 ID: 0, // orderID 0 가격: 가격, // 가격 파라미터 가격 양: 양, // 주문량 매개 변수 금액 추가: 추가 // 확장 정보 valuesToString에 의해 처리 된 문자열 }; orderBooksLen++; // 주문책의 길이가 1로 증가합니다 return orderId; //이번 구성된 주문의 orderId를 반환합니다 (무 교환 주문 ID, 혼동하지 마십시오.) }; this.Sell = function ((가격, 금액, 추가) { // 기본적으로 이것과 비슷합니다. if (typeof(extra) === undefined) { 추가 = ; 다른 것 extra = valuesToString ((항제, 2); } vId++; var orderId = V + vId orderBooks[orderId] = { 타입: ORDER_TYPE_SELL 상태: ORDER_STATE_PENDING, 아이디: 0 가격: 가격 금액: 금액 추가: 추가 }; orderBooksLen++; 반환명령 }; this.GetOrders = function() { // 완료되지 않은 주문 정보를 얻으십시오 var order = _C(exchange.GetOrders); // 주문에 할당 완료되지 않은 주문 정보를 얻기 위해 API GetOrders를 호출 for (orderId in orderBooks) { // 트레이더 객체에서 orderBooks를 통과 var order = orderBooks[orderId]; // orderId를 기반으로 주문을 꺼내 if (order.Status!== ORDER_STATE_PENDING) { // order 상태가 잠정 상태와 같지 않으면 이 루프를 건너가 계속 } var found = false; // true로 발견 변수를 초기화 (찾면 표시) for (var i = 0; i < orders.length; i++) { // API에서 반환된 실행되지 않은 명령에 대한 데이터를 통과
if (order[i].Id == order.Id) { // orderBooks에서 같은 order id를 가진 순서를 찾을 때 true의 값을 찾아라. 발견 = true;
break; // 현재 루프에서 점프 } } if (!found) { // 만약 발견되지 않으면 orderBooks[orderId]를 명령으로 누르십시오. orders.push ((orderBooks[orderId]); // 왜 이렇게 누르고 싶습니까? } } 반환 명령; // 반환 명령 } this.GetOrder = function ((orderId) { // 순서를 얻으십시오 if (typeof(orderId) === number) { // If the passed argument orderId is a numeric type 만약 전달된 논증의 순서가 숫자 유형이라면 반환 교환.GetOrder(orderId); // API GetOrder를 호출 하 여 orderId을 기반으로 주문 정보를 얻고 반환. } if (typeof(hisBooks[orderId])!== undefined) { // Typeof(hisBooks[orderId]) if not equal to undefined return hisBooks[orderId]; // hisBooks에서 orderId로 속성을 가진 데이터를 반환 } if (typeof(orderBooks[orderId])!== undefined) { // 위와 같이, orderBooks에 orderId의 값이 있다면, 이 데이터가 반환됩니다. 반환 주문 책[orderId]; } null를 반환; // 위의 조건이 충족되지 않으면 null을 반환 }; this.Len = function() { // 트레이더의 오더BookLen 변수를 반환하고, 오더북의 길이를 반환합니다. 반환 주문BooksLen; }; this.RealLen = function() { // 다시 주문번호부에서 주문량을 활성화합니다. var n = 0; // 초기 수치는 0입니다 for (orderId in orderBooks) { // 순서록을 통과 if (orderBooks[orderId].Id > 0) { // if the Id of the current order in the traversal is greater than 0, 즉, 초기 시간 이외의 0 // 주문이 이루어졌다는 것을 나타냅니다. 주문이 활성화되었습니다. n++; // 누적적으로 활성화 된 순서 } } return n; // true order book length를 반환하는 n의 값을 반환합니다. (활성화된 주문 수) }; this.Poll = function ((ticker, priceDiff) { // var 명령 = _C ((exchange.GetOrders); // 실행되지 않은 모든 명령을 얻으십시오 for (orderId in orderBooks) { // 순서록을 통과 var order = orderBooks[orderId]; // 현재 순서를 순서에 할당하십시오 if (order.Id > 0) { // order.Id가 0이 아닌 상태에서 var found = false; // 변수 발견 (표시 발견) 은 false for (var i = 0; i < orders.length; i++) { // 교환에 의해 반환 실행 명령 정보에서 동일한 명령 번호를 찾아 if (order.Id == orders[i].Id) { // 만약 발견되면 true의 값을 찾아라, 이는 그것이 발견되었다는 것을 의미합니다. 발견 = true; } } if (!found) { // If current orderId는 교환이 반환한 미완성 주문의 순서에서 발견되지 않은 주문을 나타냅니다. order.Status = ORDER_STATE_CLOSED; // orderBooks (즉 현재 순서 변수) 의 orderId에 대응하는 순서를 업데이트하고 업데이트 // ORDER_STATE_CLOSED (즉 폐쇄) 로 상태 속성 hisBooks[orderId] = 순서; // 완료 된 순서는 역사적인 순서 책, 즉 hisBooks, 통일, 고유 순서 번호에 기록됩니다. delete ((orderBooks[orderId]); // orderId value라는 명령어 책 속성을 삭제합니다. (완료된 명령어는 삭제됩니다.) orderBooksLen; // 주문책 길이를 줄여 계속; // 다음 코드는 루프를 건너뛰습니다. } } var diff = _N(order.Type == ORDER_TYPE_BUY? (ticker.Buy - order.Price) : (order.Price - ticker.Sell)); // Diff는 현재 주문서에서 계획된 오더 오픈 가격과 현재 실시간 오더 오픈 가격의 차이입니다.

        var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell;   // Assign the corresponding API function reference to pfn according to the type of the order.
        // That is, if the order type is a buy order, pfn is a reference to the exchange.Buy function, the same as the sell order.

        if (order.Id == 0 && diff <= priceDiff) {                                // If the order order in the order book is not activated (ie Id is equal to 0) and the current price is less than or 
                                                                                 // equal to the order plan price, the priceDiff passed in the parameter.   
            var realId = pfn(order.Price, order.Amount, order.Extra + "(distance: " + diff + (order.Type == ORDER_TYPE_BUY ? (" ask price: " + ticker.Buy) : (" bid price: " + ticker.Sell))+")");
            // Execute order function, parameter passing price, quantity, order extension information + pending order distance + market data (ask price or bid price), return exchange order id

            if (typeof(realId) === 'number') {    // If the returned realId is a numeric type
                order.Id = realId;                // Assign the Id attribute of the current order order to the order book.
            }
        } else if (order.Id > 0 && diff > (priceDiff + 1)) {  // If the order is active and the current distance is greater than the distance passed in by the parameter
            var ok = true;                                    // Declare a variable for tagging       Initially set true 
            do {                                              // Execute "do" first and then judge while    
                ok = true;                                    // Ok assign true
                exchange.CancelOrder(order.Id, "unnecessary" + (order.Type == ORDER_TYPE_BUY ? "buying" : "selling"), "placed order price:", order.Price, "volume:", order.Amount, ", distance:", 
                                             diff, order.Type == ORDER_TYPE_BUY ? ("ask price: " + ticker.Buy) : ("bid price: " + ticker.Sell));
                // Cancel the pending order that is out of range. After canceling the order, print the current order information and the current distance diff.

                Sleep(200);                                   // Wait 200 milliseconds
                orders = _C(exchange.GetOrders);              // Call the API to get an uncompleted order in the exchange.
                for (var i = 0; i < orders.length; i++) {     // Traverse these unfinished orders.
                    if (orders[i].Id == order.Id) {           // If the cancelled order is found in the list of orders that have not been completed by the exchange
                        ok = false;                           // Assign ok this variable to false, that is, no cancellation is successful.
                    }
                }
            } while (!ok);                                    // If ok is false, then !ok is true and while will continue to repeat the loop, continue to cancel the order,
                                                              // and check if the cancellation is successful.
            order.Id = 0;                                     // Assigning a value of 0 to order.Id means that the current order is inactive.
        }
    }
};

}

function balanceAccount ((orgAccount, initAccount) { // Balance Account Function Parameter 전략이 시작될 때 초기 계정 정보 cancelPending(); //Call the custom function cancelPending() to cancel all pending orders. //Call the custom function cancelPending() 는 대기 중인 모든 주문을 취소하기 위해 사용자 정의 함수를 호출합니다. var nowAccount = _C ((exchange.GetAccount); // 현재 계정에 대한 최신 정보를 기록하기 위해 nowAccount 변수를 선언합니다. var slidePrice = 0.2; // Set the slip price when placing the order as 0.2 오더를 배치할 때 슬립 가격을 0.2로 설정합니다 var ok = true; // 태그 변수 initially set true while (true) { // while loop) while (true) { // while loop) while (true) } while (true) { // while loop) while (true) { // while loop) while (true) } while (true) { // while loop) var diff = _N ((nowAccount.Stocks - initAccount.Stocks); // 현재 계정과 초기 계정 사이의 차이를 계산합니다 if (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, if (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, if (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, if (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, if the absolute value of the currency difference is less than the minimum transaction volume of the exchange, then if the absolute value of the currency difference is less than the minimum transaction volume of the exchange, then if the absolute value of the currency difference is less than the minimum transaction volume of the exchange, then if the absolute value of the currency difference is less than the minimum transaction volume of the exchange, then if the exchange is less than the minimum transaction volume of the exchange, // the break jumps out of the loop and does not perform balancing operations. // the break는 루프 밖으로 점프하고 균형을 이루는 작업을 수행하지 않습니다. 브레이크; ♪ ♪ var depth = _C ((exchange.GetDepth); // Get the exchange depth information Assign to the declared depth variable (교환 깊이 정보를 얻으십시오) var books = diff > 0? depth.Bids : depth.Asks; // According to the difference of the currency is greater than 0 or less than 0, extract the buy order array or // sell order array in depth (equal to 0 will not be processed, it is break when it is judged to be less than GetMinStock) // sell order array in depth (0에 해당하는 경우 처리되지 않습니다. // 코인 사이의 차이는 0보다 크다, 그래서 구매 주문 배열을 보세요. // the difference between the coins is less than 0 is the opposite. // the difference between the coins is less than 0 is the opposite. // the difference between the coins is less than 0 is the opposite. // the difference between the coins is less than 0 is the opposite. // the difference between the coins is less than 0 is the opposite. // the difference between the coins is less than 0 is the opposite. var n = 0; // statement n initial is 0 var price = 0; // Statement price initial 0 (표시 가격 초기 0) for (var i = 0; i < books.length; i++) { // Traversing the buy or sell order array n += books[i].Amount; // Accumulate Amount (order quantity) for each order based on the index i traversed [서류의 질량] if (n >= Math.abs ((diff)) { // If the cumulative order quantity n is greater than or equal to the currency difference, then: 만약 n >= Math.abs ((diff)) { // If the cumulative order quantity n is greater than or equal to the currency difference, then: price = books[i].Price; // Get the price of the current indexed order, assign it to price 현재 인덱스 된 주문의 가격을 받아서 가격에 할당하십시오 break; // Jump out of the current for traversal cycle 트러버럴 사이클을 위한 전류 ♪ ♪ ♪ ♪ var pfn = diff > 0? exchange.Sell : exchange.Buy; // the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn // 0보다 크거나 0보다 작은 통화 차이에 기초한 var amount = Math.abs(diff); // order의 양은 declared amount variable에 할당된 통화의 차이, diff입니다. var price = diff > 0? (price - slidePrice) : (price + slidePrice); // The direction of buying and selling according to the difference in the currency, increase or decrease the // 가격에 기반한 슬립 가격 (슬립 가격은 거래를 더 쉽게하기 위해), and then assign it to price Log ((start the balance??, (diff > 0? sell?? : buy??), amount,?? of coins??); // The number of coins that the output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. // Output log balances. if (diff > 0) { // According to the direction of the buying and selling, determine whether the account currency or the amount of coins is sufficient. 만약 (diff > 0) { // 구매 및 판매의 방향에 따라, 계정 화폐 또는 동전의 양이 충분 여부를 결정한다. amount = Math.min ((nowAccount.Stocks, amount); // Order amount가 현재 계정의 사용 가능한 동전을 초과하지 않도록하십시오. } else { amount = Math.min ((nowAccount.Balance / price, amount); // placed order amount does not exceed the amount of money available in the current account. 주문 금액이 현금 계좌에 사용 가능한 금액을 초과하지 않도록하십시오. ♪ ♪ if (amount < exchange.GetMinStock()) { // Check if the final order quantity is less than the minimum order quantity allowed by the exchange // 최종 주문 양이 교환이 허용하는 최소 주문 양보다 적을 경우 확인 Log (( Insufficient funds, unable to balance to the initial state); // If the order quantity is too small, the information is printed. // 주문 양이 너무 작으면 정보는 인쇄됩니다. ok = false; // 태그 밸런스 실패 break; // while 루프에서 Jump out ♪ ♪ pfn ((price, amount)); // Execute order API (pfn reference) sleep ((1000); // 1초 동안 중지 cancelPending(); // 모든 대기 주문을 취소합니다. nowAccount = _C ((exchange.GetAccount); // 현재 계정 정보를 얻으십시오 ♪ ♪ if (ok) { // when ok is true (balance is successful) curly braces 안의 코드를 실행합니다 LogProfit ((_N ((nowAccount.Balance - orgAccount.Balance)); // incoming parameter orgAccount (account information before balancing) 의 Balance 속성을 사용하십시오 // to subtract the Balance property of the current account information, that is, the difference in the amount of money. // 현금 정보의 균형 속성, 즉, 돈의 양의 차이를 빼기 위해 // That is, profit and loss (because the number of coins does not change, there is a slight error because some small) // 즉, 이익과 손실 (왜냐하면 동전의 수가 변하지 않기 때문에 약간의 오류가 있습니다. // amounts cannot be balanced) 양이 균형을 잡을 수 없습니다. log ( 밸런스 완료 , nowAccount); // The output log is balanced. ♪ ♪ ♪ ♪

var STATE_WAIT_OPEN = 0; // fishTable의 각 노드의 상태에 사용 var STATE_WAIT_COVER = 1; //... var STATE_WAIT_CLOSE = 2; //... var ProfitCount = 0 var BuyFirst = true; // 초기 인터페이스 매개 변수 var IsSupportGetOrder = true; // 교환을 결정 하 여 주요 함수의 시작을 결정 하는 글로벌 변수인 GetOrder API 함수를 지원 var LastBusy = 0; // 마지막 처리 시간 객체를 기록

함수 setBusy() { // 바쁜 시간을 설정 LastBusy = new Date(); // 현재 시간 객체에 LastBusy를 할당 }

isTimeout function (() { // 시간 종료 여부를 결정합니다 if (MaxIdle <= 0) { // 최대 무동시간 (그림이 자동으로 이동되는지 여부에 따라), // 최대 무동시간 MaxIdle가 0보다 작거나 같으면 return false; // false를 반환, 타임아웃을 판단하지 않습니다. 즉, 항상 타임아웃 없이 false를 반환합니다. } var now = new Date ((); // 현재 시간 객체를 얻으십시오 if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // 현재 시간 객체의 getTime 함수를 사용하여 시간표와 LastBusy의 시간표를 계산합니다. // 두 시간 객체 사이의 초수를 계산하기 위해 1000으로 나누십시오. // 최대 무동 시간 MaxIdle보다 크는지 결정 LastBusy = 지금; // 더 큰 경우, 현재 시간 객체에 LastBusy 업데이트 지금 true를 반환합니다. //는 true를 반환합니다. } false를 반환; // false를 반환 마감 시간 }

함수 onexit ((() { // 프로그램 종료 시 종료 함수 if (CancelAllWS) { // 정지할 때 모든 대기 주문을 취소하려면 cancelPending(를 호출하여 모든 대기 주문을 취소합니다. 로그 (( 종료, 모든 대기 주문을 취소하려고); 취소중입니다. } 로그 (전략이 성공적으로 중지되었습니다) Log ((_C(exchange.GetAccount)); // 프로그램을 종료 할 때 계정 위치 정보를 인쇄하십시오. }

기능 낚시 ((org계산, 물고기계산) { // 캐스팅 매개 변수: 계정 정보, 캐스팅 수 setBusy(); // 현재 시간표로 LastBuys를 설정 var 계정 = _C ((exchange.GetAccount); // 현금 계좌 정보를 얻기 위해 계정 변수를 선언하고 할당합니다. 로그 ((계정); // 낚시 기능에 호출의 시작에서 계정 정보를 출력. var InitAccount = 계정; // 변수 InitAccount를 선언하고 계정과 할당합니다. 여기에 전에 기록 초기 계정 자금 //이 캐스팅, 부동의 이익과 손실을 계산하는 데 사용됩니다.
var ticker = _C(exchange.GetTicker); // 선언된 ticker 변수에 할당된 코트 값을 얻으십시오 var amount = _N(AmountOnce); // 인터페이스 매개 변수 수에 따라 _N를 사용하여 소수점을 처리하고 (_N가 2 비트로 기본 설정됩니다) amount로 할당합니다. var amountB = [amount]; // amountB라는 변수를 선언하는 것은 배열입니다. var amountS = [amount]; // amountS라는 변수를 선언합니다... if (typeof(AmountType)!== undefined && AmountType == 1) { // 사용자 정의 금액에 따라 주문 크기의 유형, 이 인터페이스 매개 변수가 정의되지 않은 경우, // 그리고 AmountType는 인터페이스에서 사용자 정의 금액으로 설정됩니다, 즉, AmountType 값은 1입니다 (드롭다운 박스의 인덱스) for (var idx = 0; idx < AllNum; idx++) { // AllNum의 총 수. 사용자 지정 양을 설정하면 순위 양 배열에 순위 양B/amountS을 전체 순위 수에 따라 순환합니다. amountB[idx] = BAmountOnce; // 인터페이스 매개 변수를 사용하여 구매 주문 배열에 값을 할당 amountS[idx] = SAmountOnce; //... 판매 주문에... } } 다른 { // 다른 for (var idx = 1; idx < AllNum; idx++) { // 전체 격자 수에 기초한 사이클. switch (AmountCoefficient[0]) { // 인터페이스 매개 변수 차이에 따르면 문자열의 첫 번째 문자, AmountCoefficient[0]는 +, -, , / 경우 +: // 인터페이스 매개 변수에 따라 하나의 추가와 인크리멘트를 가진 격자 구조가 구성됩니다. amountB[idx] = amountB[idx - 1] + parseFloat ((AmountCoefficient.substring)) 휴식 부호 -: //... amountB[idx] = amountB[idx - 1] - 파서Float(AmountCoefficient.substring(1)); 휴식 케이스: amountB[idx] = amountB[idx - 1] * 파서Float ((AmountCoefficient.substring)) 휴식 부호 /: amountB[idx] = amountB[idx - 1] / parseFloat ((AmountCoefficient.substring)) 휴식 } amountB[idx] = _N(amountB[idx], AmountDot); // 구매 주문, 구매 금액, 그리고 데이터 소수점을 처리합니다. 양S[idx] = 양B[idx]; // 할당 } } if (FirstPriceAuto) { // 첫 번째 매개 변수가 자동으로 true로 설정되면 인터페이스 매개 변수가 설정되면 if 커리括弧 안의 코드가 실행됩니다. 첫 번째 가격 = 첫 번째 구매? _N (ticker.Buy - PriceGrid, Precision) : _N (ticker.Sell + PriceGrid, Precision); // 인터페이스 매개 변수 FirstPrice는 BuyFirst 글로벌 변수에 따라 첫 번째 가격을 설정합니다. // 그리고 메인의 시작에서 OpType에 따라 할당되었습니다). // 가격은 가격 표지판과 가격 매개 변수 PriceGrid 가격 간격에 의해 설정됩니다.
} // 물고기 테이블을 초기화
var fishTable = {}; // 그리드 객체를 선언 var uuidTable = {}; // 식별 코드 테이블 객체 var needStocks = 0; // 필요한 동전 변수 var needMoney = 0; // 필요한 돈 변수 var realNeedMoney = 0; // 실제로 돈이 필요했습니다 var actualNeedStocks = 0; // 실제로 필요한 동전 var notEnough = false; // 기금이 부족한 태그 변수, 처음에 false로 설정 var canNum = 0; // 사용 가능한 그리드 for (var idx = 0; idx < AllNum; idx++) { // 구조는 그리드 번호 AllNum에 따라 통과됩니다. var price = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), 정확성); // 콘스트럭트를 통과 할 때, 현재 인덱스 idx 가격 설정은 BuyFirst에 따라 설정됩니다. 각 인덱스 가격 사이의 간격은 PriceGrid입니다. needStocks += amountS[idx]; // 판매된 코인의 수는 순환과 함께 점차 축적됩니다. needMoney += price * amountB[idx]; // 구매에 필요한 금액은 순환과 함께 점차 축적됩니다. (.... if (BuyFirst) { // 먼저 구매를 처리 if (_N(needMoney) <= _N(account.Balance)) { // 그리드가 계좌에 사용 가능한 금액보다 적은 돈을 필요로 하는 경우 actualNeedMondy = needMoney; // 필요한 실제 금액에 할당 actualNeedStocks = needStocks; // 필요한 동전의 실제 수로 할당합니다. 여기에 문제가 있습니까? canNum++; // 사용 가능한 그리드의 누적 수 } else { // _N(needMoney) <= _N(account.Salt) 이 조건이 충족되지 않으면, underfunded 태그 변수를 true로 설정합니다. notEnough = true; } } else { // 먼저 판매를 처리합니다 if (_N(needStocks) <= _N(account.Stocks)) { // 필요한 동전 수가 계정에서 사용할 수 있는 동전 수보다 적는지 확인합니다 actualNeedMondy = needMoney; // 할당 actualNeedStocks = needStocks, 즉 실제 필요자본 = 필요자본; canNum++; // 사용 가능한 그리드의 누적 수 다른 것 notEnough = true; // 자금 조건이 충족되지 않으면 true로 설정 } } fishTable[idx] = STATE_WAIT_OPEN; // 현재 인덱스 idx에 따라 그리드 객체의 idx 멤버 (그리드 노드) 의 상태를 설정합니다. // 처음에 STATE_WAIT_OPEN (상황을 열기 위해 기다리고) uuidTable[idx] = -1; // 번호로 된 객체는 또한 자신의 idx 값 (fishTable에 대응하는 노드) 을 현재 idx에 기초하여 -1로 초기화합니다. } if (!EnableAccountCheck && (canNum < AllNum)) { // 자금 확인이 활성화되지 않은 경우, 그리고 그리드 수 (노드 총 수) 로 노드가 작다 // 인터페이스 매개 변수 설정보다 열 수 있습니다. 로그 ((주의, 현재 자금이 만들어질 수 있습니다, 수, 그리드의, 전체 그리드 필요, (BuyFirst? 필요 돈: 필요 주식), 충분한 자금을 유지하십시오); // 로그 출력 경고 메시지를. canNum = AllNum; // 인터페이스 매개 변수에 대한 열 수 있는 설정의 수를 업데이트 } if (BuyFirst) { // 먼저 구매 if (EnableProtectDiff && (FirstPrice - ticker.Sell) > ProtectDiff) { // 스프레드 보호 를 열고 시장 가격 인수 하 여 현재 입찰 가격 을 입력 합니다. 시장 진입 가격 보호
throw 첫 번째 구매 가격은 시장 판매 가격보다 높습니다 + _N(첫 번째 가격 - 틱어.판매, 정확성) + 달러; // 오류 메시지를 던지십시오. } else if (EnableAccountCheck && account.Balance < _N(needMoney)) { // 자금 확인이 활성화되어 계정에 사용할 수 있는 자금이 //그릴에 필요한 금액. if (fishCount == 1) { // 이 격자를 처음으로 캐스팅하는 경우 던지 불충분한 자금, 필요 + _N(필요자금) + 달러 ; // 던지 오류, 불충분한 자금 다른 것 로그 ((불충분한 자금, 필요, _N(필요한 돈), 달러, 프로그램만 만들, 수Num, 그리드 #ff0000); // 첫 번째가 아니라면 그리드를 캐스팅하면 메시지를 출력하십시오. } 다른 경우에는 자본 검사, 가격 보호 등이 없습니다. , _N(needMoney), dollar); // 출력은 자금을 사용할 것으로 예상됩니다. } else { // 먼저 팔고, 다음은 buy first와 비슷합니다 if (EnableProtectDiff && (ticker.Buy - FirstPrice) > ProtectDiff) { throw 첫 번째 판매 가격은 시장 구매 가격보다 높습니다 + _N ((ticker.Buy - FirstPrice, Precision) + 달러; } else if (EnableAccountCheck && account.Stocks < _N(needStocks)) { if (fishCount == 1) { 불충분한 자금, 필요 + _N(필요Stocks) + 동전; 다른 것 로그 ((불충분한 자금, 필요, _N(필요Stocks), 동전, 프로그램만 만들, 수수, 그리드 #ff0000); } 다른 것 기금 사용 추정: , _N(needStocks), coin, 대략, _N(needMoney), dollar); } }

var trader = new Trader();                                          // Constructs a Trader object, assigning it to the trader variable declared here.
var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell;             // According to whether to buy and sell first, set the open function OpenFunc to refer to exchange.Buy or exchange.Sell
var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy;            // same as above
if (EnableDynamic) {                                                // Set OpenFunc/CoverFunc again according to whether the interface parameter EnableDynamic is enabled.
    OpenFunc = BuyFirst ? trader.Buy : trader.Sell;                 // The member function Buy that references the trader object is used for dynamic pending orders (mainly because 
                                                                    // some exchanges limit the number of pending orders, so virtual dynamic pending orders are required)
    CoverFunc = BuyFirst ? trader.Sell : trader.Buy;                // same as above
}
var ts = new Date();                                                // Create a time object at this time (assigned to ts) to record the time at the moment.
var preMsg = "";                                                    // Declare a variable to record the last message, the initial set to empty string
var profitMax = 0;                                                  // Maximum return 
while (true) {                                                      // The main logic after the grid is casted
    var now = new Date();                                           // Record the time when the current cycle started
    var table = null;                                               // Declare a variable
    if (now.getTime() - ts.getTime() > 5000) {                      // Calculate whether the difference between the current time now and the recorded time ts is greater than 5000 milliseconds
        if (typeof(GetCommand) == 'function' && GetCommand() == "Receiving grid") {         // Check if the strategy interaction control command "receives the grid" is received, 
                                                                                            // stops and balances to the initial state.
            Log("Start executing commands to perform grid operations");                                          // Output information 
            balanceAccount(orgAccount, InitAccount);                              // Perform a balancing function to balance the number of coins to the initial state
            return false;                                                         // This time the grid function is fishing and return false
        }
        ts = now;                                                                 // Update ts with current time now for next comparison time
        var nowAccount = _C(exchange.GetAccount);                                 // Declare the nowAccount variable and initially been set as the current account information. 
        var ticker = _C(exchange.GetTicker);                                      // Declare the ticker variable and initially been set as the current market information.
        if (EnableDynamic) {                                                      // If you enable dynamic pending orders
            trader.Poll(ticker, DynamicMax);                                      // Call the Poll function of the trader object to detect and process all orders based on the 
                                                                                  // current ticker market and the interface parameter DynamicMax.
        }
        var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks);  // Calculate the current coin difference
        var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); // Calculate the current money difference
        var floatProfit = _N(money_diff + (amount_diff * ticker.Last));           // Calculate the current floating profit and loss of this time of casting grid
        var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks 
                                 - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last));
        // Calculate the overall floating profit and loss

        var isHold = Math.abs(amount_diff) >= exchange.GetMinStock();             // If the absolute value of the coin difference at this moment is greater than the minimum trading 
                                                                                  // volume of the exchange, it means that the position has been held.
        if (isHold) {                                                             // If you have already held a position, execute the setBusy() function, which will update the LastBusy time.
            setBusy();                                                            // That is, after opening the position, the opening of the opening mechanism is started.
        }

        profitMax = Math.max(floatProfit, profitMax);                             // Refresh the maximum floating profit and loss
        if (EnableAccountCheck && EnableStopLoss) {                               // If you initiate account detection and start a stop loss
            if ((profitMax - floatProfit) >= StopLoss) {                          // If the maximum floating profit or loss minus the current floating profit or loss is greater than or equal to 
                                                                                  // the maximum floating loss value, execute the code inside the curly braces
                Log("Current floating profit a

더 많은 내용