public WebCacheInstance() { //initialize ProdDefs = new List <ProdDef>(); Quotes = new List <Quote>(); mapper = MapperConfig.GetAutoMapperConfiguration().CreateMapper(); _redisClientsManager = YJYGlobal.PooledRedisClientsManager; //get value from Redis using (var redisClient = _redisClientsManager.GetClient()) { try { ProdDefs = redisClient.As <ProdDef>().GetAll(); Quotes = redisClient.As <Quote>().GetAll(); } catch (Exception e) { YJYGlobal.LogExceptionAsInfo(e); } } //set timer _timerProdDef = new Timer(UpdateProdDefs, null, _updateIntervalProdDef, TimeSpan.FromMilliseconds(-1)); _timerQuote = new Timer(UpdateQuotes, null, _updateIntervalQuote, TimeSpan.FromMilliseconds(-1)); }
//private IRedisTypedClient<Quote> redisQuoteClient; //private IRedisTypedClient<ProdDef> redisProdDefClient; // public IRedisTypedClient<> //public AyondoFixFeedApp() //{ //var basicRedisClientManager = YJYGlobal.GetNewBasicRedisClientManager(); //redisQuoteClient = YJYGlobal.BasicRedisClientManager.GetClient().As<Quote>(); //redisProdDefClient = basicRedisClientManager.GetClient().As<ProdDef>(); //} public void ToAdmin(Message message, SessionID sessionID) { YJYGlobal.LogLine("ToAdmin: "); if (message.Header.GetString(Tags.MsgType) == MsgType.LOGON) { YJYGlobal.LogLine(" sending username and password..."); //demo message.SetField(new Username(_username)); message.SetField(new Password(_password)); //message.SetField(new Username("thcnprices")); //message.SetField(new Password("sl6map3go")); ////demo UAT //message.SetField(new Username("thcnuatprices")); //message.SetField(new Password("slktrp2")); } //message.SetField(new Username("thcntrade")); //message.SetField(new Password("d093gos3j")); //message.SetField(new Username("tradeheroprices")); //message.SetField(new Password("4gs9k2osw")); }
public void SendMDS1Request() { if (Session != null) { try { //Product Definition Request var order = new Message(); order.Header.SetField(new MsgType("MDS1")); order.SetField(new UserRequestID("ProdDef")); Session.Send(order); //} } catch (Exception e) { YJYGlobal.LogLine("send mds1 request failed"); YJYGlobal.LogException(e); } } else { //// This probably won't ever happen. //Console.WriteLine("Can't send message: session not created."); throw new Exception("fix session is null."); } }
private static void QuoteBroadcast(object state) { while (true) { try { var quotes = new List <Quote>(); while (!myApp.QueueQuotesForRedistribution.IsEmpty) { Quote obj; var tryDequeue = myApp.QueueQuotesForRedistribution.TryDequeue(out obj); quotes.Add(obj); } if (quotes.Count > 0) { QuoteFeedTicker.Instance.Broadcast(quotes); } } catch (Exception e) { YJYGlobal.LogException(e); } Thread.Sleep(_intervalQuoteBroadcast); } }
public void Broadcast(List <Quote> quotes) { if (_subscription.Count > 0) { try { foreach (var pair in _subscription) { var userId = pair.Key; var subscribedQuotesIds = pair.Value; var subscribedQuotes = quotes.Where(o => subscribedQuotesIds.Contains(o.Id)); if (subscribedQuotes.Any()) { //Clients.Group(userId) Clients.Client(userId) .p(subscribedQuotes.Select(o => new QuoteFeed { id = o.Id, last = Quotes.GetLastPrice(o), //bid = o.Bid, //ask = o.Ask, time = o.Time, })); } } } catch (Exception e) { YJYGlobal.LogException(e); } } }
public PositionDTO NetPosition(NetPositionFormDTO form) { var cache = WebCache.Instance; var prodDef = cache.ProdDefs.FirstOrDefault(o => o.Id == form.securityId); if (prodDef.QuoteType == enmQuoteType.Closed || prodDef.QuoteType == enmQuoteType.Inactive) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, Resources.Resource.ProductClosed)); } var quote = cache.Quotes.FirstOrDefault(o => o.Id == form.securityId); var positionService = new PositionService(); var closedPosition = positionService.DoClosePosition(UserId, form.posId, form.securityId, Quotes.GetLastPrice(quote)); var posIdToFollowClose = closedPosition.Id; Task.Run(() => { YJYGlobal.LogLine("NEW THREAD: check and CLOSE follow positions for pos " + posIdToFollowClose); var checkAndCloseFollowPositions = PositionService.CheckAndCloseFollowPositions(posIdToFollowClose); MessageService.AddAutoCloseMessages(checkAndCloseFollowPositions); }); var result = Mapper.Map <PositionDTO>(closedPosition); return(result); }
public ResultDTO LikeStatus(int statusId) { var status = db.Status.FirstOrDefault(o => o.Id == statusId); if (status == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "no such status")); } try { db.StatusLikes.Add(new StatusLike() { StatusId = statusId, LikeUserId = UserId, Time = DateTime.UtcNow, }); db.SaveChanges(); } catch (Exception e) { //return new ResultDTO(false); YJYGlobal.LogException(e); } return(new ResultDTO(true)); }
public void ToApp(Message message, SessionID sessionId) { YJYGlobal.LogLine("ToApp: "); YJYGlobal.LogLine(message.ToString()); //message.SetField(new MsgType("MDS1")); //message.SetField(new UserRequestID("test1111")); }
private static void SaveTicks(object state) { while (true) { try { IList <Quote> quotes = new List <Quote>(); while (!myApp.QueueQuotesForTick.IsEmpty) { Quote obj; var tryDequeue = myApp.QueueQuotesForTick.TryDequeue(out obj); quotes.Add(obj); } using (var redisClient = YJYGlobal.PooledRedisClientsManager.GetClient()) { var redisTickClient = redisClient.As <Tick>(); var redisProdDefClient = redisClient.As <ProdDef>(); var prodDefs = redisProdDefClient.GetAll(); if (quotes.Count > 0) { //the time of the last message received from Ayondo var dtAyondoNow = quotes.Max(o => o.Time); var openingProds = prodDefs.Where( o => o.QuoteType == enmQuoteType.Open || o.QuoteType == enmQuoteType.PhoneOnly).ToList(); var dtBeginSave = DateTime.Now; foreach (var prodDef in openingProds) { var quotesByProd = quotes.Where(o => o.Id == prodDef.Id).ToList(); UpdateRedisTick(redisTickClient, prodDef.Id, dtAyondoNow, quotesByProd, TickSize.OneMinute); UpdateRedisTick(redisTickClient, prodDef.Id, dtAyondoNow, quotesByProd, TickSize.TenMinute); UpdateRedisTick(redisTickClient, prodDef.Id, dtAyondoNow, quotesByProd, TickSize.OneHour); } YJYGlobal.LogLine("\t" + " Ticks " + openingProds.Count + "/" + quotes.Count + " " + " Time: " + quotes.Min(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + " ~ " + quotes.Max(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + " Saved to Redis " + (DateTime.Now - dtBeginSave).TotalMilliseconds); } } } catch (Exception e) { YJYGlobal.LogException(e); } Thread.Sleep(_intervalTicks); } }
public void OnLogon(SessionID sessionID) { YJYGlobal.LogLine("OnLogon: "); Session = Session.LookupSession(sessionID); DD = Session.ApplicationDataDictionary; SendMDS1Request(); }
private static TimeSpan LogEndOfJob(TimeSpan execTime) { YJYGlobal.LogLine("-"); YJYGlobal.LogLine("................................................................................"); YJYGlobal.LogLine(" TH_JOBS FINISHED: @ (local) " + DateTime.Now.ToString("dd MMM yyyy HH:mm") + ", execTime was " + execTime.TotalMinutes.ToString("000.00") + " min(s) ..."); YJYGlobal.LogLine(" (fullArgs: " + fullArgs + ")"); YJYGlobal.LogLine("................................................................................"); YJYGlobal.LogLine("-"); return(execTime); }
private MessageTicker(IHubConnectionContext <dynamic> clients) { Clients = clients; _db = YJYEntities.Create(); YJYGlobal.LogLine("Starting MessageTicker..."); _timer = new Timer(Start, null, _updateInterval, TimeSpan.FromMilliseconds(-1)); }
public void Login(string auth) { int userId = 0; string token = null; try { var split = auth.Split('_'); userId = Convert.ToInt32(split[0]); token = split[1]; } catch (Exception ex) { //this.Context.User.Identity.IsAuthenticated = false; YJYGlobal.LogInformation("signalR MessageHub invalid auth: " + auth); } bool isUserExist; using (var db = YJYEntities.Create()) { //var s = HttpContext.Current.User.Identity.Name; //var name = Context.User.Identity.Name; //HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(userId.ToString()), null); // Get the request lifetime scope so you can resolve services. //var requestScope = HttpContext.Current.Request.GetDependencyScope(); //// Resolve the service you want to use. //var db = requestScope.GetService(typeof(YJYEntities)) as YJYEntities; //var httpContextBase = Context.Request.GetHttpContext(); //var request = Context.Request; //var nameValueCollection = request.Headers; //var db = YJYEntities.Create(); isUserExist = db.Users.Any(o => o.Id == userId && o.AuthToken == token); } //if (!isUserExist) // actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); if (isUserExist) { _ticker.AddAuthUser(Context.ConnectionId, userId); } else { YJYGlobal.LogInformation("signalR MessageHub wrong auth: " + auth); } }
private QuoteFeedTicker(IHubConnectionContext <dynamic> clients) { Clients = clients; //var basicRedisClientManager = YJYGlobal.GetNewBasicRedisClientManager(); //_redisClient = YJYGlobal.BasicRedisClientManager.GetClient().As<Quote>(); YJYGlobal.LogLine("Starting QuoteFeedTicker..."); //Start(); //_timer = new Timer(Start, null, _updateInterval, TimeSpan.FromMilliseconds(-1)); }
static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs) { YJYGlobal.LogLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}."); var context = exceptionReceivedEventArgs.ExceptionReceivedContext; YJYGlobal.LogLine("Exception context for troubleshooting:"); YJYGlobal.LogLine($"- Endpoint: {context.Endpoint}"); YJYGlobal.LogLine($"- Entity Path: {context.EntityPath}"); YJYGlobal.LogLine($"- Executing Action: {context.Action}"); return(Task.CompletedTask); }
public static void Run(bool isLive = false) { SessionSettings settings = new SessionSettings(YJYGlobal.GetConfigurationSetting("ayondoFixFeedCfgFilePath")); myApp = new AyondoFixFeedApp(YJYGlobal.GetConfigurationSetting("ayondoFixFeedUsername"), YJYGlobal.GetConfigurationSetting("ayondoFixFeedPassword")); IMessageStoreFactory storeFactory = new MemoryStoreFactory(); //new FileStoreFactory(settings); //ILogFactory logFactory = new FileLogFactory(settings); SocketInitiator initiator = new SocketInitiator(myApp, storeFactory, settings, null //logFactory ); //var redisClient = YJYGlobal.BasicRedisClientManager.GetClient(); //var redisProdDefClient = redisClient.As<ProdDef>(); //var redisTickClient = redisClient.As<Tick>(); initiator.Start(); // This will *ONLY* bind to localhost, if you want to bind to all addresses // use http://*:8080 to bind to all addresses. // See http://msdn.microsoft.com/library/system.net.httplistener.aspx // for more information. string url = "http://*:39680"; var start = WebApp.Start(url); Trace.Listeners.Remove("HostingTraceListener");//remove the trace listener that OWIN added Console.WriteLine("Server running on {0}", url); //Console.ReadLine(); //run tasks in NEW threads _timerProdDefs = new Timer(SaveProdDefs, null, _intervalProdDefs, TimeSpan.FromMilliseconds(-1)); _timerProdDefRequest = new Timer(SendProdDefRequest, null, _intervalProdDefRequest, TimeSpan.FromMilliseconds(-1)); _timerQuotes = new Timer(SaveQuotes, null, _intervalQuotes, TimeSpan.FromMilliseconds(-1)); _timerRawTicks = new Timer(SaveRawTicks, null, _intervalRawTicks, TimeSpan.FromMilliseconds(-1)); _timerTicks = new Timer(SaveTicks, null, _intervalTicks, TimeSpan.FromMilliseconds(-1)); _timerKLines = new Timer(SaveKLine, null, _intervalKLine, TimeSpan.FromMilliseconds(-1)); _timerQuoteBroadcast = new Timer(QuoteBroadcast, null, _intervalQuoteBroadcast, TimeSpan.FromMilliseconds(-1)); while (true) { //System.Console.WriteLine("o hai"); System.Threading.Thread.Sleep(1000); } //initiator.Stop(); }
public bool THTDeposit(THTDepositFormDTO form) { var authorization = Request.Headers.Authorization; if (authorization?.Parameter == null || authorization.Parameter != YJYGlobal.CALLBACK_AUTH_TOKEN) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "invalid auth token")); } if (string.IsNullOrWhiteSpace(form.transactionHash) || string.IsNullOrWhiteSpace(form.from) || string.IsNullOrWhiteSpace(form.tokenAmount)) { throw new ArgumentOutOfRangeException(nameof(form)); } form.tokenAmount = form.tokenAmount.Trim(); form.transactionHash = form.transactionHash.Trim(); form.from = form.from.Trim(); form.to = form.to.Trim(); BigInteger bi; var tryParse = BigInteger.TryParse(form.tokenAmount, NumberStyles.None, null, out bi); if (!tryParse || bi < new BigInteger(0)) { throw new ArgumentOutOfRangeException(nameof(form.tokenAmount)); } var deposit = FundService.AddTHTDeposit(form.transactionHash, form.@from, form.to, form.tokenAmount); if (deposit == null) { return(false); } try { var fundService = new FundService(db); fundService.AddUserBalanceByTHTDeposit(deposit.Id); } catch (Exception e) { YJYGlobal.LogExceptionAsWarning(e); } return(true); }
public static void DeleteBlob(string containerName, string blobName) { var storageConStr = YJYGlobal.GetConfigurationSetting("StorageConnectionString"); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConStr); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Retrieve a reference to a container. CloudBlobContainer container = blobClient.GetContainerReference(containerName); CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); if (blockBlob.Exists()) { blockBlob.Delete(); } }
private static void LogJobStartup()//(tradeheroEntities db, bool isMonitoring) { //if (!isMonitoring) //{ YJYGlobal.LogLine("***************************************************"); YJYGlobal.LogLine("*** TH_JOBS STARTUP - (local) " + DateTime.Now.ToString("dd MMM yyyy HH:mm") + " ***"); YJYGlobal.LogLine("***************************************************"); YJYGlobal.LogLine("-"); YJYGlobal.LogLine("this host: " + System.Environment.MachineName); //YJYGlobal.LogLine("constr: " + db.Database.Connection.ConnectionString); YJYGlobal.LogLine("curdir: " + Environment.CurrentDirectory); YJYGlobal.LogLine("fullArgs: " + fullArgs); YJYGlobal.LogLine("logDir: " + logDir); YJYGlobal.LogLine("-"); //} }
public static void Run() { YJYGlobal.LogLine("Starting..."); queueClient = new QueueClient(ServiceBusConnectionString, QueueName); // Register QueueClient's MessageHandler and receive messages in a loop RegisterOnMessageHandlerAndReceiveMessages(); YJYGlobal.LogLine("Receiving messages..."); while (true) { Thread.Sleep(TimeSpan.FromSeconds(1)); } }
public static YJYEntities Create(bool log = false, bool UseDatabaseNullSemantics = true) { string connectionString = YJYGlobal.GetDbConnectionString("YJYEntities"); var db = new YJYEntities(connectionString); db.Configuration.UseDatabaseNullSemantics = UseDatabaseNullSemantics; if (log || Debugger.IsAttached) { db.Database.Log = s => Trace.WriteLine(s); } //if (log) // Global.LogLine("created object-context for main DB [" + db.Database.Connection.Database + "]"); return(db); }
private static void SendProdDefRequest(object state) { while (true) { try { YJYGlobal.LogLine("sending mds1 request..."); myApp.SendMDS1Request(); } catch (Exception e) { YJYGlobal.LogLine("sending mds1 request failed"); YJYGlobal.LogException(e); } Thread.Sleep(_intervalProdDefRequest); } }
private static void SaveQuotes(object state) { while (true) { try { IList <Quote> quotes = new List <Quote>(); while (!myApp.QueueQuotes.IsEmpty) { Quote obj; var tryDequeue = myApp.QueueQuotes.TryDequeue(out obj); quotes.Add(obj); } if (quotes.Count > 0) { var distinctQuotes = quotes.GroupBy(o => o.Id).Select(o => o.OrderByDescending(p => p.Time).First()).ToList(); var dtBeginSave = DateTime.Now; using (var redisClient = YJYGlobal.PooledRedisClientsManager.GetClient()) { var redisQuoteClient = redisClient.As <Quote>(); redisQuoteClient.StoreAll(distinctQuotes); } YJYGlobal.LogLine("Quote: " + distinctQuotes.Count + "/" + quotes.Count + " (distinct/raw) " + " Time: " + quotes.Min(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + " ~ " + quotes.Max(o => o.Time).ToString(YJYGlobal.DATETIME_MASK_MILLI_SECOND) + ". Saved to redis " + (DateTime.Now - dtBeginSave).TotalMilliseconds); } } catch (Exception e) { YJYGlobal.LogException(e); } Thread.Sleep(_intervalQuotes); } }
public static void UploadFromBytes(string containerName, string blobName, byte[] bytes) { var storageConStr = YJYGlobal.GetConfigurationSetting("StorageConnectionString"); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConStr); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Retrieve a reference to a container. CloudBlobContainer container = blobClient.GetContainerReference(containerName); // Create the container if it doesn't already exist. container.CreateIfNotExists(); container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob }); // Retrieve reference to a blob named "myblob". CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); //// Save blob contents to a file. //using (var fileStream = System.IO.File.OpenWrite(@"path\myfile")) //{ // blockBlob.DownloadToStream(fileStream); //} //// read blob contents as a string. //string text; //using (var memoryStream = new MemoryStream()) //{ // blockBlob2.DownloadToStream(memoryStream); // text = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray()); //} //// Create or overwrite the "myblob" blob with contents from a local file. //using (var fileStream = System.IO.File.OpenRead(@"path\myfile")) //{ // blockBlob.UploadFromStream(fileStream); //} //// Delete the blob. //blockBlob.Delete(); blockBlob.UploadFromByteArray(bytes, 0, bytes.Length); }
private void UpdateQuotes(object state) { while (true) { //CFDGlobal.LogLine("Updating WebCache Quotes..."); using (var redisClient = _redisClientsManager.GetClient()) { try { Quotes = redisClient.As <Quote>().GetAll(); } catch (Exception e) { YJYGlobal.LogExceptionAsInfo(e); } } Thread.Sleep(_updateIntervalQuote); } }
private static void SaveApiHitsToDB(object state) { while (true) { try { var apiHits = new List<ApiHit>(); while (!ApiHitsQueue.IsEmpty) { ApiHit apiHit; ApiHitsQueue.TryDequeue(out apiHit); apiHits.Add(apiHit); } if (apiHits.Count > 0) { using (var db = YJYHistoryEntities.Create()) { //ef extension - BulkInsert //using (var transactionScope = new TransactionScope()) //{ db.BulkInsert(apiHits); db.SaveChanges(); //transactionScope.Complete(); //} ////ef - AddRange //db.ApiHits.AddRange(apiHits); //db.SaveChanges(); } } } catch (Exception e) { YJYGlobal.LogExceptionAsInfo(e); } Thread.Sleep(_dbSaveInterval); } }
static async Task ProcessMessagesAsync(Message message, CancellationToken token) { // Process the message //YJYGlobal.LogLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber}"); try { var posToClose = Serialization.ByteArrayToObject(message.Body) as PosToClose; YJYGlobal.LogLine( $"Received: {posToClose.Id} {posToClose.closeType} {posToClose.closePx} {posToClose.closePxTime}"); var autoClosePosition = PositionService.AutoClosePosition(posToClose); var checkAndCloseFollowPositions = PositionService.CheckAndCloseFollowPositions(autoClosePosition.Id); MessageService.AddAutoCloseMessage(autoClosePosition); MessageService.AddAutoCloseMessages(checkAndCloseFollowPositions); YJYGlobal.LogLine( $"pos closed: {autoClosePosition.Id} type:{autoClosePosition.CloseType} pl:{autoClosePosition.PL}"); // Complete the message so that it is not received again. // This can be done only if the queueClient is created in ReceiveMode.PeekLock mode (which is default). await queueClient.CompleteAsync(message.SystemProperties.LockToken); // Note: Use the cancellationToken passed as necessary to determine if the queueClient has already been closed. // If queueClient has already been Closed, you may chose to not call CompleteAsync() or AbandonAsync() etc. calls // to avoid unnecessary exceptions. } catch (Exception e) { YJYGlobal.LogException(e); await queueClient.AbandonAsync(message.SystemProperties.LockToken); } }
public PositionDTO NewPosition(NewPositionFormDTO form) { if (form.invest <= 0 || form.invest > 10000) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "invalid invest")); } if (form.leverage < 1) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "invalid leverage")); } var user = GetUser(); var balance = db.Balances.FirstOrDefault(o => o.Id == user.ActiveBalanceId); if (balance.Amount < form.invest) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, Resources.Resource.NotEnoughBalance)); } var cache = WebCache.Instance; decimal spread = 0.0005M; //点差,默认万分之五 var spreadMisc = db.Miscs.FirstOrDefault(m => m.Key == "spread"); if (spreadMisc != null) { decimal.TryParse(spreadMisc.Value, out spread); } var prodDef = cache.ProdDefs.FirstOrDefault(o => o.Id == form.securityId); if (prodDef.QuoteType == enmQuoteType.Closed || prodDef.QuoteType == enmQuoteType.Inactive) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, Resources.Resource.ProductClosed)); } //if (form.leverage > prodDef.MaxLeverage) if (form.leverage > MAX_LEVERAGE) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "exceeded max leverage")); } var quote = cache.Quotes.FirstOrDefault(o => o.Id == form.securityId); var positionService = new PositionService(); var price = Quotes.GetLastPrice(quote); if (form.isLong) //买多,买入价 = 买入价 + 加点差 { price = (1 + spread) * price; } else //买空, 买入价 = 买入价 - 加点差 { price = (1 - spread) * price; } var newPosition = positionService.CreateNewPosition(UserId, form.securityId, form.invest, form.isLong, form.leverage, price); var posIdToFollow = newPosition.Id; Task.Run(() => { YJYGlobal.LogLine("NEW THREAD: check and OPEN follow positions for pos " + posIdToFollow); PositionService.CheckAndOpenFollowPositions(posIdToFollow); }); var posDTO = new PositionDTO() { id = newPosition.Id, isLong = newPosition.Side.Value, settlePrice = newPosition.SettlePrice.Value, invest = newPosition.Invest.Value, leverage = newPosition.Leverage.Value, createAt = newPosition.CreateTime.Value, }; return(posDTO); }
public static List <Position> CheckAndCloseFollowPositions(int posIdToFollowClose) { List <Position> result = new List <Position>(); var db = YJYEntities.Create(); var basePosition = db.Positions.FirstOrDefault(o => o.Id == posIdToFollowClose); if (basePosition != null) { if (basePosition.ClosedAt != null && basePosition.ClosePrice != null) { var positions = db.Positions.Where(o => o.FollowPosId == basePosition.Id && o.ClosedAt == null).ToList(); foreach (var position in positions) { try { using ( var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable })) { using (var dbIsolated = YJYEntities.Create()) { var p = dbIsolated.Positions.FirstOrDefault(o => o.Id == position.Id); var u = dbIsolated.Users.FirstOrDefault(o => o.Id == position.UserId); if (u == null || p == null) { throw new ObjectNotFoundException(); } //position's balance, not user's current active balance var b = dbIsolated.Balances.FirstOrDefault(o => o.Id == p.BalanceId && o.UserId == u.Id); if (p.ClosedAt == null) { var pl = Trades.CalculatePL(p, basePosition.ClosePrice.Value); p.ClosedAt = DateTime.UtcNow; p.ClosePrice = basePosition.ClosePrice.Value; p.PL = pl; p.CloseType = PositionCloseType.Follow.ToString(); var pValue = p.Invest + pl; if (pValue > 0) { b.Amount = b.Amount + pValue; } //add a new transfer dbIsolated.Transfers.Add(new Transfer() { Amount = pValue, BalanceAfter = b.Amount, Time = DateTime.UtcNow, Type = TransferType.Close.ToString(), UserId = u.Id, PositionId = p.Id, BalanceId = b.Id, }); dbIsolated.SaveChanges(); result.Add(p); } } scope.Complete(); } } catch (Exception e) { YJYGlobal.LogWarning("follow close error:"); YJYGlobal.LogExceptionAsWarning(e); } } } else { YJYGlobal.LogWarning("FOLLOW CLOSE fail: base position is not closed"); } } return(result); }
public static void CheckAndOpenFollowPositions(int posIdToFollow) { var db = YJYEntities.Create(); var basePosition = db.Positions.FirstOrDefault(o => o.Id == posIdToFollow); if (basePosition != null) { var tradeFollows = db.UserTradeFollows.Where(o => o.FollowingId == basePosition.UserId && o.StopAfterCount > 0).ToList(); foreach (var tradeFollow in tradeFollows) { try { using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable })) { using (var dbIsolated = YJYEntities.Create()) { var tFollow = dbIsolated.UserTradeFollows.FirstOrDefault(o => o.UserId == tradeFollow.UserId && o.FollowingId == tradeFollow.FollowingId); if (tFollow != null && tFollow.StopAfterCount > 0) { var u = dbIsolated.Users.FirstOrDefault(o => o.Id == tFollow.UserId); if (u != null) { var b = dbIsolated.Balances.FirstOrDefault(o => o.Id == u.ActiveBalanceId); if (b.TypeId == basePosition.BalanceTypeId) //ONLY WHEN trade-follower's active balance type == base position's balance type { if (b.Amount < tFollow.InvestFixed) //not enough balance { tFollow.StopAfterCount = tFollow.StopAfterCount - 1; //count-- tFollow.LastTriggerAt = DateTime.UtcNow; if (tFollow.StopAfterCount == 0) //stop following if count == 0 { dbIsolated.UserTradeFollows.Remove(tFollow); } dbIsolated.SaveChanges(); } else { b.Amount = b.Amount - tFollow.InvestFixed; var p = new Position() { CreateTime = DateTimes.UtcToChinaTime(DateTime.UtcNow), Invest = tFollow.InvestFixed, Leverage = basePosition.Leverage, UserId = u.Id, Side = basePosition.Side, SecurityId = basePosition.SecurityId, SettlePrice = basePosition.SettlePrice, FollowPosId = basePosition.Id, FollowUserId = basePosition.UserId, BalanceId = b.Id, BalanceTypeId = b.TypeId, }; dbIsolated.Positions.Add(p); dbIsolated.SaveChanges(); //to get position auto id //add a new transfer dbIsolated.Transfers.Add(new Transfer() { Amount = -tFollow.InvestFixed, BalanceAfter = b.Amount, Time = DateTime.UtcNow, Type = TransferType.Open.ToString(), UserId = u.Id, PositionId = p.Id, //position id should be populated BalanceId = b.Id, }); tFollow.StopAfterCount = tFollow.StopAfterCount - 1; //count-- tFollow.LastTriggerAt = DateTime.UtcNow; if (tFollow.StopAfterCount == 0) //stop following if count == 0 { dbIsolated.UserTradeFollows.Remove(tFollow); } dbIsolated.SaveChanges(); } } } } } scope.Complete(); } } catch (Exception e) { YJYGlobal.LogWarning("copy trade error:"); YJYGlobal.LogExceptionAsWarning(e); } } } }