API Support Forum
User Profile

Viewing User Profile for: TLau471


About

Aug 27, 2013 11:16 AM

May 28, 2020 02:45 AM

May 28, 2020 02:45 AM



Post Statistics
TLau471 has contributed to 44 posts out of 4906 total posts (0.90%) in 2615 days (0.00 posts per day).

20 most recent posts:

API Support » Different behavior in API vs LIVE server May 28, 2020 @ 02:45 AM (Total replies: 4)

Is there a way to determine if the trader has datafeed permission for his requested symbol?
TLau


Feedback » Account confusion May 19, 2020 @ 09:27 AM (Total replies: 2)

Ok got it. Thanks!
TLau


API Support » Different behavior in API vs LIVE server May 19, 2020 @ 09:26 AM (Total replies: 4)

Ah yes, that was the cause. Thank you.
TLau


API Support » Different behavior in API vs LIVE server May 18, 2020 @ 10:47 PM (Total replies: 4)

The symbol in question is ESM0 and all times are eastern. Thank you.
TLau


Feedback » Account confusion May 18, 2020 @ 10:45 PM (Total replies: 2)

Hi,

I'm quite confused with my account logins at the following places:

1. https://apisupport.gainfutures.com - TLau471, password A
2. https://myaccount.gainfutures.com/Account/Login - TLau471, password B
3. API - TLau471, password B

I can change password B by logging into #2.
How do I change password for A?
TLau


API Support » Different behavior in API vs LIVE server May 18, 2020 @ 10:40 PM (Total replies: 4)

Hi,

I found a difference in behavior between the API and LIVE server:

1. API server, called Subscriptions.Ticks.Subscribe for 18th May 07:19:08 til 07:19:13, Subscriptions.Ticks.TicksReceived is triggered almost immediately
2. LIVE server, called Subscriptions.Ticks.Subscribe for 18th May 07:19:08 til 07:19:13, Subscriptions.Ticks.TicksReceived is not triggered

Please advise. Thank you.
TLau


API Support » GF API login credentials May 12, 2020 @ 02:58 AM (Total replies: 7)

Hi,

I think my API account expired. Please help. Thank you.
TLau


API Support » GFAPI Socket Error after 2 minutes Mar 09, 2020 @ 05:40 AM (Total replies: 13)

Ok, BeginInvoke helped. Thank you.
TLau


API Support » GFAPI Socket Error after 2 minutes Mar 06, 2020 @ 09:12 AM (Total replies: 13)

Too fast? Sorry, but I don't think using sleep(10) is the robust approach to event driven programming.
I mean why 10? why not 1? or 100? It sounds more like a race condition. Can it be looked into?
I can't tell if the server is rejecting the connection or the API being unable to connect out..

Again, what I'm asking is B, what is the recommended way for API clients to perform re-connection.
Since client.Connection.Aggregate.Connect() is an asynchronous call, my first approach is to call it from inside the Disconnected event if the trader has specified to reconnect automatically.

Thank you.
TLau


API Support » GFAPI Socket Error after 2 minutes Mar 06, 2020 @ 03:38 AM (Total replies: 13)

My output as follows
---
Hello OEC!
Connecting...
Account Summary Changed. API003808 (USD): P/L = 0. Total Net Liq: 49774.9999999999
OnLoginComplete: CompleteConnected=True
Accounts: 1, orders: 0, base contracts: 463
Account: API003808
NetLiq: 49774.9999999999
Cash: 49774.9999999999
Open P/L: 0
Total P/L: 0
Initial Margin: 0
Net Options Value: 0
Average Positions: 0
Orders: 0, last one:
6/3/2020 9:36:56 AM 1 2972.5
6/3/2020 9:36:56 AM 1 2972.5
6/3/2020 9:36:56 AM 1 2972.5
6/3/2020 9:36:56 AM 1 2972.5
6/3/2020 9:36:56 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:57 AM 1 2972.5
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 1 2972.25
6/3/2020 9:36:59 AM 2 2972.25
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:00 AM 1 2972.5
6/3/2020 9:37:01 AM 1 2972.75
OnDisconnected: Disconnected by user
Connecting...
OnDisconnected: ConnectionError
OnLoginFailed: ConnectionError
TLau


API Support » GFAPI Socket Error after 2 minutes Mar 06, 2020 @ 03:35 AM (Total replies: 13)

I managed to replicate the issue in this sample code from the docs
---
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports GF.Api
Imports GF.Api.Accounts
Imports GF.Api.Connection
Imports GF.Api.Contracts
Imports GF.Api.Contracts.Lookup
Imports GF.Api.Contracts.Lookup.Request
Imports GF.Api.Messaging.Chat
Imports GF.Api.Messaging.Notifications
Imports GF.Api.Orders
Imports GF.Api.Orders.Drafts
Imports GF.Api.Orders.Drafts.Validation
Imports GF.Api.Positions
Imports GF.Api.Threading
Imports GF.Api.Utils
Imports GF.Api.Values.Contracts.Lookup
Imports GF.Api.Values.Orders

Namespace ConsoleSample
Friend Class Program
Private Shared _frontEsSymbolLookupRequestID As SymbolLookupRequestID
Private Shared _statusTimer As System.Timers.Timer

Public Shared Sub Main(ByVal args As String())
Console.WriteLine("Hello OEC!")
Dim client As IGFClient = GF.Api.Impl.GFApi.CreateClient()
Dim runner = New GFClientRunner(client)
runner.Start()

AddHandler client.Connection.Aggregate.LoginCompleted, AddressOf GFClient_OnLoginCompleted
AddHandler client.Connection.Aggregate.LoginFailed, AddressOf GFClient_OnLoginFailed
AddHandler client.Connection.Aggregate.Disconnected, AddressOf GFClient_OnDisconnected

AddHandler client.Contracts.Lookup.SymbolLookupReceived, AddressOf GFClient_OnSymbolLookupReceived
AddHandler client.Subscriptions.Price.PriceTick, AddressOf GFClient_OnPriceTick
AddHandler client.Orders.OrderStateChanged, AddressOf GFClient_OnOrderStateChanged
AddHandler client.Orders.OrderConfirmed, AddressOf GFClient_OnOrderConfirmed
AddHandler client.Orders.OrderFilled, AddressOf GFClient_OnOrderFilled
AddHandler client.Accounts.AvgPositionChanged, AddressOf GFClient_OnAvgPositionChanged
AddHandler client.Accounts.AccountSummaryChanged, AddressOf GFClient_OnAccountSummaryChanged
AddHandler client.Accounts.BalanceChanged, AddressOf GFClient_OnBalanceChanged
AddHandler client.Messaging.Notifications.NotificationMessageReceived, AddressOf GFClient_OnNotificationMessageReceived
AddHandler client.Messaging.Chat.ChatMessageReceived, AddressOf GFClient_OnChatMessageReceived
AddHandler client.Logging.ErrorOccurred, AddressOf GFClient_OnErrorOccurred

Dim username As String
Dim password As String
Dim uuid As String

Do

client.Connection.Aggregate.Connect(New ConnectionContextBuilder().
WithUserName(username).
WithPassword(password).
WithPort(9210).WithHost("api.gainfutures.com").
WithUUID(uuid).
WithForceLogin(True).Build())

Console.WriteLine("Connecting...")
_statusTimer = New System.Timers.Timer With {
.Interval = TimeSpan.FromSeconds(10).TotalMilliseconds
}
AddHandler _statusTimer.Elapsed, Sub(__, ___) StatusTimer_Tick(client)
_statusTimer.Start()

Dim cki As ConsoleKeyInfo
cki = Console.ReadKey()

client.Connection.Aggregate.Disconnect()
_statusTimer.[Stop]()

Select Case cki.Key
Case ConsoleKey.X
Exit Do
End Select
Loop

runner.[Stop]()
End Sub

Private Shared Sub GFClient_OnChatMessageReceived(ByVal client As IGFClient, ByVal e As ChatMessageEventArgs)
Console.WriteLine($"User Message. {e.ChatMessage.FromUser.Name} - {e.ChatMessage.Message}")
client.Messaging.Chat.SendMessage(e.ChatMessage.FromUser.ID, "Hey, I'm just a robot!")
End Sub

Private Shared Sub GFClient_OnNotificationMessageReceived(ByVal client As IGFClient, ByVal e As NotificationMessageEventArgs)
DisplayNotificationMessage(DateTime.UtcNow, e.NotificationMessage.Channel, e.NotificationMessage.Message)
End Sub

Private Shared Sub DisplayNotificationHistory(ByVal client As IGFClient)
For Each notification In client.Messaging.Notifications.[Get]()
DisplayNotificationMessage(notification.Timestamp, notification.Channel, notification.Message)
Next
End Sub

Private Shared Sub DisplayNotificationMessage(ByVal timestamp As DateTime, ByVal channel As NotificationChannel, ByVal message As String)
Console.WriteLine($"Notification. {channel}: {message} at {timestamp.ToLocalTime()}")
End Sub

Private Shared Sub GFClient_OnBalanceChanged(ByVal client As IGFClient, ByVal e As BalanceChangedEventArgs)
DisplayBalance("Balance Changed", e.Account, e.Currency)
End Sub

Private Shared Sub GFClient_OnAccountSummaryChanged(ByVal client As IGFClient, ByVal e As AccountSummaryChangedEventArgs)
DisplayBalance("Account Summary Changed", e.Account, e.Currency)
End Sub

Private Shared Sub DisplayBalance(ByVal comment As String, ByVal account As IAccount, ByVal currency As GF.Api.Currencies.ICurrency)
Dim balance As GF.Api.Balances.IBalance = account.Balances(currency)
Console.WriteLine($"{comment}. {account.Spec} ({currency.Name}): P/L = {Math.Round(balance.OpenPnL + balance.RealizedPnL, 2)}. Total Net Liq: {account.TotalBalance.NetLiq}")
End Sub

Private Shared Sub GFClient_OnAvgPositionChanged(ByVal client As IGFClient, ByVal e As PositionChangedEventArgs)
Console.WriteLine("Average Position. {0}/{1}: Net Pos: {2} @ {3}, Bought: {4}, Sold {5}, Prev Pos: {6} P/L: {7:c}", e.Account.Spec, e.ContractPosition.Contract.Symbol, e.ContractPosition.Net.Volume, e.ContractPosition.Contract.PriceToString(e.ContractPosition.Net.Price), e.ContractPosition.Long.Volume, e.ContractPosition.Short.Volume, e.ContractPosition.Prev.Volume, e.ContractPosition.OTE + e.ContractPosition.Gain)
'If e.ContractPosition.Net.Volume = 0 Then Stop
End Sub

Private Shared Sub GFClient_OnOrderFilled(ByVal client As IGFClient, ByVal e As OrderFilledEventArgs)
Console.WriteLine("#{0} New fill: {1} @ {2} ({3}). Total filled qty: {4}, avg. price: {5}", e.Order.ID, e.Fill.Quantity, e.Fill.Contract.PriceToString(e.Fill.Price), If(e.Fill.IsActive, "active", "cancelled"), e.Order.Fills.TotalQuantity, e.Order.Contract.PriceToString(e.Order.Fills.AvgPrice))
End Sub

Private Shared Sub GFClient_OnErrorOccurred(ByVal client As IGFClient, ByVal e As ErrorEventArgs)
Console.WriteLine($"OnError: {e.Exception.Message}")
End Sub

Private Shared Sub GFClient_OnOrderConfirmed(ByVal client As IGFClient, ByVal e As OrderConfirmedEventArgs)
Console.WriteLine($"#{e.OriginalOrderID} order confirmed. New order ID is {e.Order.ID}")
End Sub

Private Shared Sub GFClient_OnOrderStateChanged(ByVal client As IGFClient, ByVal e As OrderStateChangedEventArgs)
Console.WriteLine($"#{e.Order.ID} order state changed from {e.PreviousOrderState} to {e.Order.CurrentState}")
End Sub

Private Shared Sub GFClient_OnLoginFailed(ByVal client As IGFClient, ByVal e As LoginFailedEventArgs)
Console.WriteLine($"OnLoginFailed: {e.FailReason}")
End Sub

Private Shared Sub GFClient_OnDisconnected(ByVal client As IGFClient, ByVal e As DisconnectedEventArgs)
Console.WriteLine($"OnDisconnected: {e.Message}")
End Sub

Private Shared Sub GFClient_OnLoginCompleted(ByVal client As IGFClient, ByVal e As LoginCompleteEventArgs)
Console.WriteLine($"OnLoginComplete: CompleteConnected={client.Connection.Aggregate.IsConnected}")
Console.WriteLine($" Accounts: {client.Accounts.[Get]().Count}, orders: {client.Orders.[Get]().Count}, base contracts: {client.Contracts.Base.[Get]().Count}")
DisplayAccount(client, client.Accounts.[Get]().First())
DisplayNotificationHistory(client)
_frontEsSymbolLookupRequestID = client.Contracts.Lookup.ByCriteria(New SymbolLookupRequestBuilder().WithResultCount(1).WithSymbol("ES", TextSearchMode.StartsWith).Build())
End Sub

Private Shared Sub GFClient_OnSymbolLookupReceived(ByVal client As IGFClient, ByVal e As SymbolLookupEventArgs)
If _frontEsSymbolLookupRequestID IsNot Nothing AndAlso e.RequestID = _frontEsSymbolLookupRequestID Then
If e.Contracts.Any() Then
client.Subscriptions.Price.Subscribe(e.Contracts.First().ID)
End If
End If
End Sub

Private Shared Sub GFClient_OnPriceTick(ByVal client As IGFClient, ByVal e As PriceChangedEventArgs)
'Console.WriteLine("#{0} New fill: {1} @ {2} ({3}). Total filled qty: {4}, avg. price: {5}", e.Order.ID, e.Fill.Quantity, e.Fill.Contract.PriceToString(e.Fill.Price), If(e.Fill.IsActive, "active", "cancelled"), e.Order.Fills.TotalQuantity, e.Order.Contract.PriceToString(e.Order.Fills.AvgPrice))
Console.WriteLine("{0} {1} {2}", e.Price.LastDateTime, e.Price.LastVol, e.Price.LastPrice)
If Math.Abs(e.Price.LastPrice - e.Price.BidPrice) < e.Contract.TickSize Then
PlaceOrder(client, e.Contract, OrderSide.Buy, e.Price.BidPrice, "By Bid")
ElseIf Math.Abs(e.Price.LastPrice - e.Price.AskPrice) < e.Contract.TickSize Then
PlaceOrder(client, e.Contract, OrderSide.Sell, e.Price.AskPrice, "By Ask")
End If
End Sub

Private Shared Sub StatusTimer_Tick(ByVal client As IGFClient)
client.Threading.BeginInvoke(Sub()
If client.Connection.Aggregate.IsConnected Then
DisplayAccount(client, client.Accounts.[Get]().First())
CheckAndCancelOrder(client)
ModifyOrder(client)
End If
End Sub)
End Sub

Private Shared Sub PlaceOrder(ByVal client As IGFClient, ByVal contract As IContract, ByVal orderSide As OrderSide, ByVal limitPrice As Double, ByVal comments As String)
Return
If client.Orders.[Get]().Count = 0 OrElse client.Orders.[Get]().Last().IsFinalState Then
Dim orderDraft = New OrderDraftBuilder().WithAccountID(client.Accounts.[Get]().First().ID).WithContractID(contract.ID).WithSide(orderSide).WithOrderType(OrderType.Limit).WithPrice(limitPrice).WithQuantity(1).WithEnd(DateTime.UtcNow.AddMinutes(1)).WithComments(comments).Build()
Dim validationErrors As IReadOnlyList(Of OrderDraftValidationError) = client.Orders.Drafts.Validate(orderDraft)

If validationErrors.Any() Then
Console.WriteLine($"ERROR. Order draft is invalid ({orderSide} {orderDraft.Quantity} {contract.Symbol} @ {contract.PriceToString(limitPrice)}):")

For Each [error] In validationErrors
Console.WriteLine($" {[error].Message}")
Next
Else
Dim order As IOrder = client.Orders.SendOrder(orderDraft)
Console.WriteLine($"Order {order} was sent")
End If
End If
End Sub

Private Shared Sub ModifyOrder(ByVal client As IGFClient)
If client.Orders.[Get]().Any() AndAlso Not client.Orders.[Get]().Last().IsFinalState Then
Dim currentWorkingOrder As IOrder = client.Orders.[Get]().Last()

If currentWorkingOrder.Commands.Last().State = CommandState.Executed Then
Dim priceChange = If(currentWorkingOrder.IsBuySide, currentWorkingOrder.Contract.TickSize, -currentWorkingOrder.Contract.TickSize)
Dim modifyOrderDraft As ModifyOrderDraft = New ModifyOrderDraftBuilder().FromOrder(currentWorkingOrder).WithPrice((If(currentWorkingOrder.Price, 0.0)) + priceChange).Build()
Dim validationErrors As IReadOnlyList(Of OrderDraftValidationError) = client.Orders.Drafts.Validate(modifyOrderDraft)

If validationErrors.Any() Then
Console.WriteLine($"ERROR. Attempt to modify the order {currentWorkingOrder} failed:")

For Each [error] In validationErrors
Console.WriteLine($" {[error].Message}")
Next
Else
Dim order As IOrder = client.Orders.ModifyOrder(modifyOrderDraft)
Console.WriteLine($"Modify request has been sent: {order}")
End If
End If
End If
End Sub

Private Shared Sub CheckAndCancelOrder(ByVal client As IGFClient)
If client.Orders.[Get]().Any() AndAlso Not client.Orders.[Get]().Last().IsFinalState Then
Dim currentWorkingOrder As IOrder = client.Orders.[Get]().Last()

If currentWorkingOrder.Commands.Last().State = CommandState.Executed Then

If client.Orders.Drafts.GetPriceCount(currentWorkingOrder.Type) > 0 Then

If Math.Abs((If(currentWorkingOrder.Price, 0.0)) - currentWorkingOrder.Contract.CurrentPrice.LastPrice) >= 3 * currentWorkingOrder.Contract.TickSize Then
Console.WriteLine($"Send request to cancel: {currentWorkingOrder}")
client.Orders.CancelOrder(currentWorkingOrder.ID, SubmissionType.Automatic)
End If
End If
End If
End If
End Sub

Private Shared Sub DisplayAccount(ByVal client As IGFClient, ByVal account As IAccount)
'If account.AvgPositions.Count = 0 Then Stop
Dim totalBalance As GF.Api.Balances.IBalance = account.TotalBalance
Console.WriteLine($"Account: {account.Spec}")
Console.WriteLine($" NetLiq: {totalBalance.NetLiq}")
Console.WriteLine($" Cash: {totalBalance.Cash}")
Console.WriteLine($" Open P/L: {totalBalance.OpenPnL}")
Console.WriteLine($" Total P/L: {totalBalance.RealizedPnL + totalBalance.OpenPnL}")
Console.WriteLine($" Initial Margin: {totalBalance.InitialMargin}")
Console.WriteLine($" Net Options Value: {totalBalance.LongCallOptionsValue + totalBalance.LongPutOptionsValue + totalBalance.ShortCallOptionsValue + totalBalance.ShortPutOptionsValue}")
Console.WriteLine($"Average Positions: {account.AvgPositions.Count}")
Console.WriteLine($"Orders: {client.Orders.[Get]().Count}, last one: {(If(client.Orders.[Get]().Count > 0, client.Orders.[Get]().Last().ToString(), String.Empty))}")
End Sub
End Class
End Namespace
TLau


API Support » GFAPI Socket Error after 2 minutes Mar 05, 2020 @ 11:31 AM (Total replies: 13)

Ok, I think the term re-connection is just semantics.

To be explicit, there are 2 problems here,

A. Why does the API disconnect after 2 mins of external activities
B. How should we deal with disconnections

1. Yes, the 2 mins is happening inside the OnLoginComplete handler
2. So, this is probably the reason why I'm getting the Disconnected event

Now, more importantly, even after removing the 2 mins from the handler and solving
problem A, I still need to deal with problem B since disruptions can and will happen.

3. After getting Disconnected event, does the GFAPI re-establish the connection by itself?
4. If it does not, what should I do about it?
5. Currently, once I call the code to connect again, it triggers more Disconnected events.
6. I'm signed up for gfClient.Logging.ErrorOccurred, but nothing popping up there
7. I have described in detail the events that are being triggered in my OP
8. Able to check the API server for logs on what I might be doing wrong?

Thank you.
TLau

Edited by TLau471 on Mar 05, 2020 11:32 AM

API Support » GFAPI Socket Error after 2 minutes Mar 05, 2020 @ 08:58 AM (Total replies: 13)

Hi,

My question is, how do I perform a re-connection successfully? That seems impossible at the moment.
Side note, I already started GFClientRunner in #1, why do I still need to call gfClient.Threading.Advance()?
TLau

Edited by TLau471 on Mar 05, 2020 08:59 AM

API Support » GFAPI Socket Error after 2 minutes Mar 05, 2020 @ 04:18 AM (Total replies: 13)

Hi,

1. My app instantiates the GFAPI cilent and starts the GFClientRunner
2. After connecting and logging in, it takes 2 minutes to perform some non-GFAPI activities
3. After the 2 mins, it calls client.Contracts.Lookup.ByCriteria(), but that results in a Disconnected being fired with "Socket Error"
4. It tries to reconnect, and Disconnected fires again with "ConnectionError"
5. The cycle repeats between #3 and #4
6. If I skip the 2 minute activity, everything works fine.

I need the reconnection to work. What am I doing wrong here?
Thank you.
TLau


API Support » GF API equivalent of OEC.client.RequestTicks Feb 17, 2020 @ 01:16 AM (Total replies: 1)

Hi,

What is the GF API equivalent of OEC's client.RequestTicks()? The one that we used to get backfill for a symbol. Thank you.
TLau


API Support » GF API login credentials Feb 12, 2020 @ 04:28 AM (Total replies: 7)

Hi, do you have the GF API targeted at dotnet 4.5?
TLau


API Support » GF API login credentials Jan 06, 2020 @ 09:53 AM (Total replies: 7)

Can someone advise? Thanks!
TLau


API Support » GF API login credentials Jan 05, 2020 @ 10:34 PM (Total replies: 7)

The error is InvalidUserOrPassword
TLau


API Support » GF API login credentials Jan 05, 2020 @ 10:32 PM (Total replies: 7)

Hi,

I have an API account by the same name TLau471.
However, it is not able to connect to api.gainfutures.com using the GF Advanced Example.

Please advise. Thank you.
TLau


API Support » How to use OEC.API.SymbolLookupCriteria Apr 28, 2019 @ 08:21 PM (Total replies: 3)

Hi,

It worked... until it stopped working again.
I set DesiredResultCount = 1000 but still, only 50 is returned and there is no K9 now, i.e. May 2019.

Please help. Thank you.
TLau