Snippets

GainFuturesDev GFApi Paged load Contracts by BaseSymbol

Created by Sergey Pikalov last modified
using System;
using GF.Api.Connection;
using GF.Api.Contracts.Base;
using GF.Api.Contracts.Criteria;
using GF.Api.Contracts.Load.Expression;
using GF.Api.Contracts.Load.Request;
using GF.Api.Contracts.Lookup.Request;
using GF.Api.Impl;
using GF.Api.Threading;
using GF.Api.Values.Contracts.Lookup;

namespace GF.GFApiPagedLoadContractsByBaseSymbol
{
    class Program
    {
        private const string BaseSymbol = "OEW"; //"ES";
        private const int MaxPageSize = 1000; //Load request does not allow more than this
        private const int PageSize = MaxPageSize;

        private const string UserName = "";
        private const string Password = "";

        private SymbolLookupRequestID _symbolLookupRequestID;

        private IContractLoadExpression _loadContractExpression;
        private int _loadRequestCounter;
        private ContractLoadRequestID _loadRequestID;
        private Action _loadCompleteAction;

        static void Main(string[] args)
        {
            new Program().Run();
        }

        private void Run()
        {
            var client = GFApi.CreateClient();
            var runner = new GFClientRunner(client);
            runner.Start();

            Console.WriteLine("Connecting...");
            client.Connection.Aggregate.LoginFailed += Aggregate_LoginFailed;
            client.Connection.Aggregate.LoginCompleted += Aggregate_LoginCompleted;
            client.Contracts.Lookup.SymbolLookupReceived += Lookup_SymbolLookupReceived;
            client.Contracts.Load.ContractLoadReceived += Load_ContractLoadReceived;
           
            client.Connection.Aggregate.Connect(
                new ConnectionContextBuilder()
                    .WithUserName(UserName)
                    .WithPassword(Password)
                    .WithPort(9210)
                    .WithHost("api.gainfutures.com")
                    .WithUUID("9e61a8bc-0a31-4542-ad85-33ebab0e4e86")
                    .WithForceLogin(true)
                    .Build());

            Console.WriteLine("Press any key to exit");
            Console.WriteLine();
            Console.ReadKey();

            runner.Stop();
        }

        private void Aggregate_LoginCompleted(GF.Api.IGFClient client, LoginCompleteEventArgs e)
        {
            Console.WriteLine("Connected");
            Console.WriteLine($"Request by BaseSymbol {BaseSymbol}");
            Console.WriteLine();

            _symbolLookupRequestID = client.Contracts.Lookup.ByCriteria(
                new SymbolLookupRequestBuilder()
                    .WithResultCount(1)
                    .WithBaseSymbol(BaseSymbol, TextSearchMode.Exact)
                    .Build());
        }

        private static void Aggregate_LoginFailed(GF.Api.IGFClient client, LoginFailedEventArgs e) =>
            Console.WriteLine($"Login failed: {e.FailReason}");

        private void Lookup_SymbolLookupReceived(GF.Api.IGFClient client, GF.Api.Contracts.Lookup.SymbolLookupEventArgs e)
        {
            if (e.RequestID != _symbolLookupRequestID)
                return;

            if (e.Contracts.Count < 1)
            {
                Console.WriteLine($"Looking up contract {BaseSymbol} returns no results");
                return;
            }

            var contract = e.Contracts[0];

            Console.WriteLine($"Lookup result received for {BaseSymbol}");
            Console.WriteLine($"IsOption: {contract.IsOption}");

            if (contract.IsOption)
            {
                //If the contract is an option, then we must first load all available parent contracts
                LoadByBaseContract(client, contract.ParentContract.BaseContract);
                _loadCompleteAction = () =>
                {
                    LoadByBaseContract(client, contract.BaseContract);
                    _loadCompleteAction = null;
                };
            }
            else
                LoadByBaseContract(client, contract.BaseContract);
        }

        private void LoadByBaseContract(GF.Api.IGFClient client, IBaseContract baseContract)//IContractLoadExpression expression)
        {
            Console.WriteLine($"Requesting first {PageSize} contracts by {baseContract.Symbol}");

            _loadContractExpression = new ContractLoadExpressionBuilder()
                    .Push(new BaseContractIDCriterion(baseContract.ID))
                    .Build();

            var request = new ContractLoadRequestBuilder()
                       .WithSkipCount(0)
                       .WithResultCount(PageSize)
                       .WithExpression(_loadContractExpression)
                       .Build();

            _loadRequestID = client.Contracts.Load.Request(request);
        }


        private void Load_ContractLoadReceived(GF.Api.IGFClient client, GF.Api.Contracts.Load.ContractLoadResponseEventArgs e)
        {
            if (_loadRequestID != e.RequestID)
                return;

            Console.WriteLine($"{e.Contracts.Count} contracts received");
            Console.WriteLine("Contracts:");
            foreach (var contract in e.Contracts)
                Console.WriteLine($"\t{contract.Symbol}");

            if (e.Contracts.Count >= PageSize)
            {
                _loadRequestCounter++;

                Console.WriteLine($"Requesting next {PageSize} contracts. Page# {_loadRequestCounter}");

                var request = new ContractLoadRequestBuilder()
                    .WithSkipCount(PageSize * _loadRequestCounter)
                    .WithResultCount(PageSize)
                    .WithExpression(_loadContractExpression)
                    .Build();

                _loadRequestID = client.Contracts.Load.Request(request);
            }
            else
            {
                _loadRequestCounter = 0;

                Console.WriteLine("Done.");
                
                _loadCompleteAction?.Invoke();
            }
        }
    }
}

Comments (1)

  1. Linda Melson
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.