/// <summary> /// Обновить контракт по его метаданным /// </summary> /// <param name="metadata"> /// Метаданные контракта /// </param> /// <param name="dependentObjectDescription"> /// Строковое описание объекта, который зависит от инструмента /// </param> public async Task HandleMetadataAsync(ContractMetadata metadata, string dependentObjectDescription = null) { _Log.Debug().Print( "Contract metadata received", LogFields.ContractId(metadata.contract_id), LogFields.Symbol(metadata.contract_symbol), LogFields.CorrectPriceScale(metadata.correct_price_scale), LogFields.DisplayPriceScale(metadata.display_price_scale) ); using (cacheLock.Lock()) { if (cachedContracts.ContainsKey(metadata.contract_id)) { _Log.Debug().Print("Already cached", LogFields.ContractId(metadata.contract_id)); return; } } Instrument instrument = await InstrumentConverter.ResolveSymbolAsync(adapter, metadata.contract_symbol, dependentObjectDescription); if (instrument == null) { _Log.Warn().Print("Instrument not resolved", LogFields.Symbol(metadata.contract_symbol)); return; } using (cacheLock.Lock()) { _Log.Debug().Print( "Caching instrument", LogFields.ContractId(metadata.contract_id), LogFields.Symbol(metadata.contract_symbol), LogFields.Instrument(instrument) ); cachedContractIds[instrument] = metadata.contract_id; cachedContracts[metadata.contract_id] = instrument; cachedContractPriceScales[metadata.contract_id] = (decimal)metadata.correct_price_scale; } OnInstrumentResolved(metadata.contract_id); }
/// <summary> /// Обновить контракт по его метаданным /// </summary> /// <param name="metadata"> /// Метаданные контракта /// </param> public void HandleMetadata(ContractMetadata metadata) { _Log.Debug().Print( "Contract metadata received", LogFields.ContractId(metadata.contract_id), LogFields.Symbol(metadata.contract_symbol), LogFields.CorrectPriceScale(metadata.correct_price_scale), LogFields.DisplayPriceScale(metadata.display_price_scale) ); using (cacheLock.Lock()) { if (cachedContracts.ContainsKey(metadata.contract_id)) { _Log.Debug().Print("Already cached", LogFields.ContractId(metadata.contract_id)); return; } } var instrument = InstrumentConverter.ResolveSymbolAsync(adapter, metadata.contract_symbol).Result; if (instrument == null) { _Log.Warn().Print("Instrument not resolved", LogFields.Symbol(metadata.contract_symbol)); return; } using (cacheLock.Lock()) { _Log.Debug().Print( "Caching instrument", LogFields.ContractId(metadata.contract_id), LogFields.Symbol(metadata.contract_symbol), LogFields.Instrument(instrument) ); cachedContractIds[instrument] = metadata.contract_id; cachedContracts[metadata.contract_id] = instrument; cachedContractPriceScales[metadata.contract_id] = (decimal)metadata.correct_price_scale; } OnInstrumentResolved(metadata.contract_id); }
public IContractInvoker Create(ContractMetadata contract, IInstanceProvider instanceProvider, ServerRuntimeConfiguration configuration) { if (contract == null) { throw new ArgumentNullException(nameof(contract)); } if (instanceProvider == null) { throw new ArgumentNullException(nameof(instanceProvider)); } if (instanceProvider == null) { throw new ArgumentNullException(nameof(instanceProvider)); } return(new ContractInvoker(configuration) { Contract = contract, InstanceProvider = instanceProvider }); }
public SendMessageFlags Handle(ContractMetadata metadata) { var result = SendMessageFlags.None; var tickSize = (decimal)metadata.tick_size; if (InstrumentParams.PriceStep != tickSize) { InstrumentParams.PriceStep = tickSize; result |= SendMessageFlags.InstrumentParams; } var tickValue = (decimal)metadata.tick_value; if (InstrumentParams.PriceStepValue != tickValue) { InstrumentParams.PriceStepValue = tickValue; result |= SendMessageFlags.InstrumentParams; } // ситуация, когда шаг цены инструмента - плавающая if (metadata.tick_sizes_by_price != null && metadata.tick_sizes_by_price.Count > 0) { TickSizesByPrice = metadata.tick_sizes_by_price.OrderBy(_ => _.minimum_price).ToList(); } var decimalPlaces = metadata.display_price_scale <= 15 // См. описание поля display_price_scale в WebAPI.proto ? metadata.display_price_scale : InstrumentParams.GetDecimalPlaces(); // DecimalPlaces считаются по PriceStep if (InstrumentParams.DecimalPlaces != decimalPlaces) { InstrumentParams.DecimalPlaces = decimalPlaces; result |= SendMessageFlags.InstrumentParams; } return(result); }
public T CreateProxy <T>(IClientPipeline pipeline) where T : class { ContractMetadata contract = BoltFramework.GetContract(typeof(T)); var interceptor = new ChannelInterceptor(); var options = new ProxyGenerationOptions { BaseTypeForInterfaceProxy = _baseProxy }; ProxyMetadata metadata = _metadatas.GetOrAdd(typeof(T), v => new ProxyMetadata(_baseProxy)); var proxy = _generator.CreateInterfaceProxyWithoutTarget <T>( options, interceptor); ProxyBase proxyBase = (ProxyBase)(object)proxy; proxyBase.Contract = contract; proxyBase.Pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); interceptor.Proxy = proxyBase; interceptor.Metadata = metadata; return(proxy); }
private ContractMetadata CrateContractMetadata(ServerActionContext context) { var feature = context.HttpContext.GetFeature<IBoltFeature>(); var m = new ContractMetadata { Actions = BoltFramework.GetContractActions(context.Contract).Select(a => a.Name).ToList(), ErrorHeader = feature.ActionContext.Configuration.Options.ServerErrorHeader, ContentType = feature.ActionContext.Configuration.Serializer.ContentType }; return m; }
public async Task <ActionResult> Action() { var action = Request["Action"]; var args = new Dictionary <string, string>(); byte opcode = 0x01; var address = Request["Address"]; var contractHash = new Address(address).Bytes; string key = HttpServerUtility.UrlTokenEncode(contractHash); var file = $"{key}"; string contractCode = null; var codeFile = Path.ChangeExtension(Path.Combine("db", "contracts", file), ".txt"); if (System.IO.File.Exists(codeFile)) { contractCode = System.IO.File.ReadAllText(codeFile); } var contractInteraction = new ContractInteraction() { Action = action, Address = new Address(contractHash, AddressType.Contract).ToString() }; ContractMetadata contractMetadata = null; try { var _metadata = ContractExamples.Execution.metadata(contractCode); if (FSharpOption <ContractMetadata> .get_IsNone(_metadata)) { contractInteraction.Message = "No metadata"; } else { contractMetadata = _metadata.Value; } } catch { contractInteraction.Message = "Error getting metadata"; return(View(contractInteraction)); } if (contractMetadata.IsCallOption) { var callOptionParameters = (ContractExamples.Execution.ContractMetadata.CallOption)contractMetadata; switch (action) { case "Collateralize": //var pkAddress = new PKAddressField(); //pkAddress.SetValue(Request["return-address"]); //if (pkAddress.Invalid) //{ // contractInteraction.Message = "Invalid return address"; // return View(contractInteraction); //} //args.Add("returnPubKeyAddress", pkAddress.Value); opcode = OPCODE_COLLATERALIZE; break; case "Exercise": var pkExerciseReturnAddress = new PKAddressField(); pkExerciseReturnAddress.SetValue(Request["exercise-return-address"]); if (pkExerciseReturnAddress.Invalid) { contractInteraction.Message = "Invalid send address"; return(View(contractInteraction)); } args.Add("returnPubKeyAddress", pkExerciseReturnAddress.Value); string oracleData; //GetOracleCommitmentData(callOptionParameters.Item.underlying, DateTime.Now.ToUniversalTime()).Result; if (GetLastData(callOptionParameters.Item.underlying, out oracleData)) { args.Add("oracleRawData", oracleData); } else { contractInteraction.Message = "Error getting oracle data"; return(View(contractInteraction)); } opcode = OPCODE_EXERCISE; break; case "Buy": var pkSendAddress = new PKAddressField(); pkSendAddress.SetValue(Request["buy-send-address"]); if (pkSendAddress.Invalid) { contractInteraction.Message = "Invalid send address"; return(View(contractInteraction)); } args.Add("returnPubKeyAddress", pkSendAddress.Value); opcode = OPCODE_BUY; break; //case "Close": // opcode = OPCODE_CLOSE; // break; } } var argsMap = new FSharpMap <string, string>(args.Select(t => new Tuple <string, string>(t.Key, t.Value))); var result = await Client.Send <GetContractPointedOutputsResultPayload>(_address, new GetContractPointedOutputsPayload() { ContractHash = contractHash }); var utxos = GetContractPointedOutputsResultPayload.Unpack(result.PointedOutputs); var data = ContractUtilities.DataGenerator.makeJson(contractMetadata, utxos, opcode, argsMap); if (data.IsError) { contractInteraction.Message = data.ErrorValue.ToString(); } else { contractInteraction.Data = data.ResultValue.JsonValue.ToString(); } return(View(contractInteraction)); }
public ContractMetadata Metadata() { ContractMetadata metadata = contactService.GetMetadata(); return(metadata); }
private async Task <SubscriptionResult> SubscribeAsync(Instrument instrument, SubscriptionFlags flags) { using (LogManager.Scope()) { InstrumentSubscription subscription = null; ContractMetadata metadata = null; var hasSubscriptionLock = false; try { // Получаем параметры подписки на инструмент using (subscriptionsLock.Lock()) { subscriptionsByInstrument.TryGetValue(instrument, out subscription); } if (subscription == null) { // Получаем ID инструмента var contractId = await instrumentResolver.GetContractIdAsync(instrument); if (contractId == uint.MaxValue) { return(SubscriptionResult.Error(instrument, "Symbol is not resolved in tree node for CQG")); } using (subscriptionsLock.Lock()) { if (!subscriptionsByInstrument.TryGetValue(instrument, out subscription)) { if (!subscriptionsByContractId.TryGetValue(contractId, out subscription)) { subscription = new InstrumentSubscription(instrumentResolver, instrument, contractId); // Сразу захватываем блокировку subscription.AcquireFlagsLock(); hasSubscriptionLock = true; subscriptionsByContractId.Add(contractId, subscription); contractMetadatas.TryGetValue(contractId, out metadata); } subscriptionsByInstrument.Add(instrument, subscription); } } } else { // Захватываем блокировку subscription.AcquireFlagsLock(); hasSubscriptionLock = true; } // Подписываемся на инструмент с учетом флагов подписки if ((subscription.Flags & flags) != flags) { // Нужные флаги подписки не проставлены, требуется доподписаться MarketDataSubscription.Level?level = null; switch (subscription.Flags | flags) { case SubscriptionFlags.InstrumentParams: level = MarketDataSubscription.Level.TRADES_BBA_VOLUMES; break; case SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; case SubscriptionFlags.InstrumentParams | SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; } if (level != null) { subscription.Flags |= flags; RequestMarketDataSubscription(subscription, level.Value); } } // При необходимости обрабатываем метаданные и выбрасываем события if (metadata != null) { Process(subscription, metadata, (s, data) => s.Handle(data)); } // Готово var result = SubscriptionResult.OK(instrument); return(result); } catch (OperationCanceledException) { _Log.Warn().Print($"Unable to subscribe to {instrument} (operation has been cancelled)"); return(SubscriptionResult.Error(instrument, "Operation has been cancelled")); } catch (Exception e) { _Log.Error().Print(e, $"Unable to subscribe to {instrument}"); return(SubscriptionResult.Error(instrument, e.Message)); } finally { if (subscription != null && hasSubscriptionLock) { subscription.ReleaseFlagsLock(); } } } }
public ProxyBase(Type contract, IClientPipeline pipeline) { State = ProxyState.Ready; _contract = BoltFramework.GetContract(contract); _pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline)); }
public ContractMetadata Metadata() { ContractMetadata metadata = DonateContract.GetMetadata(); return(metadata); }
public TimeSpan GetActionTimeout(ContractMetadata contract, ActionMetadata actionMetadata) { throw new NotImplementedException(); }
public virtual void Validate(ContractMetadata contract) { }