private static bool CheckRequiredPermissions(ZubrWebsocketClient ws) { List <string> requiredPermissions = new List <string>(); requiredPermissions.Add("GET_ACCOUNT_DATA"); requiredPermissions.Add("MARKET_DATA"); requiredPermissions.Add("ORDER_DATA"); requiredPermissions.Add("NEW_ORDER"); requiredPermissions.Add("CANCEL_ORDER"); bool ok = true; foreach (var permission in requiredPermissions) { if (!ws.Permissions.Contains(permission)) { ok = false; break; } } return(ok); }
static void Main(string[] args) { string configStr = File.ReadAllText("config.json"); JToken config = JToken.Parse(configStr); logLogic = config.Value <bool>("LogLogicalEvents"); logTransport = config.Value <bool>("LogTransport"); ws = new ZubrWebsocketClient(config.Value <string>("apiKey"), config.Value <string>("apiSecret"), config.Value <string>("apiEndpoint")); ws.LogTransport = logTransport; ws.Login(); while (!ws.LoggedIn) { Thread.Sleep(100); } if (!CheckRequiredPermissions(ws)) { throw new Exception("Api key's permission level not suitable for trading"); } ///Setting instrument from config /// instrumentCode = config.Value <int>("InstrumentCode"); volume = config.Value <int>("QuoteSize"); interest = config.Value <decimal>("Interest"); shift = config.Value <decimal>("Shift"); maxPosition = config.Value <decimal>("MaxPosition"); minTickSize = config.Value <decimal>("MinTickSize"); ///Initial position read /// //check if configured position size should be used for calculations, otherwise if (config.Value <bool>("InitialPositionFromConfig")) { position = config.Value <decimal>("InitialPosition"); positionInitialised = true; if (logLogic) { Console.WriteLine("Initial position read from config"); } } else { //subscribe to positions //get SOW position //Unsubscribe -- using execution reports for position calculations going forward ws.Positions += Ws_PositionsInit; ws.Subscribe(Channel.positions); while (!positionInitialised) { Thread.Sleep(100); } ws.Unsubscribe(Channel.positions); ws.Positions -= Ws_PositionsInit; if (logLogic) { Console.WriteLine("Initial position stream unsubscribed"); } } ///Setting up eventhandlers to act upon price change and fills ws.Tickers += Ws_TickersUpdate; ws.OrderFills += Ws_OrderFillsUpdate; ws.Orderbook += Ws_OrderbookUpdate; ws.Orders += Ws_OrdersUpdate; ws.OrderConfirmations += WS_OrderConfirmationsUpdate; ws.Subscribe(Channel.tickers); ws.Subscribe(Channel.orderFills); ws.Subscribe(Channel.orderbook); ws.Subscribe(Channel.orders); if (logLogic) { Console.WriteLine("Streams subscribed"); } while (asks.Count == 0 || bids.Count == 0) { //We have to have the orderbook info first to be able to place any trade Thread.Sleep(100); } if (logLogic) { Console.WriteLine("Orderbook received"); } while (!orderSnapshotReceived) { //We only want to work with the new orders from now on Thread.Sleep(100); } if (logLogic) { Console.WriteLine("Order snapshots received"); } AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit); Console.CancelKeyPress += new ConsoleCancelEventHandler(CurrentDomain_ProcessExit); InitOrders(); while (true) { //do everything on other threads, we just can't let the main thread exit Thread.Sleep(100); } }