Пример #1
0
 public void Reset()
 {
     Result      = MarketDialogResult.Pending;
     Transaction = null;
     PlayerColumns.Reconstruct(Player.Resources, new List <ResourceAmount>(), (int)Player.Money);
     UpdateBottomDisplays();
     Layout();
 }
Пример #2
0
 public void Reset()
 {
     Result      = MarketDialogResult.Pending;
     Transaction = null;
     PlayerColumns.Reconstruct(Play.Trading.Helper.AggregateResourcesIntoTradeableItems(Player.Resources), new List <TradeableItem>(), (int)Player.Money);
     UpdateBottomDisplays();
     Layout();
 }
Пример #3
0
        public async Task <ActionResult> MakeMarketTransaction([FromBody] MarketTransaction marketTransaction, int planetId)
        {
            var planet = await _planetService.GetPlanetById(planetId);

            var result = await _planetService.MakeMarketTransaction(planet, marketTransaction);

            if (result == null)
            {
                return(BadRequest());
            }
            return(Ok(result));
        }
Пример #4
0
        private void UpdateTranInvoke()
        {
            MarketTransaction mt = null;

            while (true)
            {
                if (QueueTrans.TryDequeue(out mt))
                {
                    if (this.UpdateTransaction != null)
                    {
                        this.UpdateTransaction.Invoke(mt);
                    }
                }
                else
                {
                    Thread.Sleep(50);
                }
            }
        }
Пример #5
0
        public async Task <uint256> Order(int accountId, decimal isk)
        {
            MarketTransaction mtx = new MarketTransaction
            {
                AccountId = accountId,
                Time      = DateTime.Now,
                Amount    = -isk,
                Type      = TransactionType.Buy
            };

            try
            {
                var account = await _context.Account
                              .Include(x => x.MarketTransactions)
                              .FirstOrDefaultAsync(x => x.Id == accountId);

                if (account == null)
                {
                    _logger.LogCritical($"Order cancelled because no account with id: {accountId} was found");
                    return(null);
                }

                mtx.Fee = -Math.Round(isk * (account.Fee / 100));

                decimal rate = Decimal.Zero;

                using (var scope = _serviceProvider.CreateScope())
                {
                    var _tickerService = scope.ServiceProvider.GetRequiredService <TickerService>();

                    if (_tickerService.MarketState == MarketState.Open)
                    {
                        rate = _tickerService.Tickers["btcisk"].Ask;
                    }
                    else
                    {
                        _logger.LogCritical("Order cancelled because market is closed.");
                        mtx.Status = TransactionStatus.Rejected;
                        account.MarketTransactions.Add(mtx);
                        await _context.SaveChangesAsync();

                        return(null);
                    }
                }

                mtx.Rate = rate;

                if (rate == Decimal.Zero)
                {
                    _logger.LogCritical("Order cancelled because rate value was zero, this should never happen.");
                    mtx.Status = TransactionStatus.Rejected;
                    account.MarketTransactions.Add(mtx);
                    await _context.SaveChangesAsync();

                    return(null);
                }

                Money coins = Money.Coins(
                    Math.Round(isk / rate * (1 - account.Fee / 100), 8, MidpointRounding.ToZero));
                mtx.Coins = coins.ToDecimal(MoneyUnit.BTC);
                _logger.LogDebug($"Id: {accountId} Coins: {coins} ISK: {isk} Rate: {rate} Account Balance: {account.Balance}");

                if (account.Balance >= isk)
                {
                    mtx.Balance = account.Balance - isk;
                    _logger.LogDebug($"{accountId} has sufficient balance for the order");

                    using (var scope = _serviceProvider.CreateScope())
                    {
                        var _bitcoin = scope.ServiceProvider.GetRequiredService <BitcoinService>();
                        if (await _bitcoin.BitarCanMakePayment(accountId, coins))
                        {
                            account.Balance -= isk;
                            await _context.SaveChangesAsync();

                            ExtKey key      = _bitcoin._masterKey.Derive(new KeyPath($"m/84'/0'/{account.Derivation}'/0/0"));
                            var    receiver = key.PrivateKey.PubKey.GetSegwitAddress(Network.Main);

                            int bitarAccountId = 0;
                            var result         = await _bitcoin.SendBitcoin(0, receiver, coins, 36);

                            if (result != null)
                            {
                                _logger.LogDebug($"Bitcoin transaction result: {result.ToString()}");
                                mtx.TxId   = result.ToString();
                                mtx.Status = TransactionStatus.Completed;
                            }
                            else
                            {
                                _logger.LogCritical($"Bitcoin transaction failed");
                                // The bitcoin transaction failed.
                                // Should we refund the user right away?
                                // accountData.Balance += isk;
                                mtx.Status = TransactionStatus.Failed;
                            }

                            _logger.LogWarning(
                                "Market Transaction.\n" +
                                $"Id: {mtx.Id}\n" +
                                $"Date: {mtx.Time}\n" +
                                $"Rate: {mtx.Rate}\n" +
                                $"Coins: {mtx.Coins}\n" +
                                $"Fee: {mtx.Fee}\n" +
                                $"Amount: {mtx.Amount}\n" +
                                $"Type: {mtx.Type}\n" +
                                $"Status: {mtx.Status}");

                            account.MarketTransactions.Add(mtx);
                            await _context.SaveChangesAsync();

                            return(result);
                        }
                    }
                }
                else
                {
                    _logger.LogCritical(
                        "Order cancelled.\n" +
                        $"{accountId} does not have sufficient balance for the order.\n" +
                        $"Order => {coins} BTC for {isk} ISK.\n" +
                        $"Current balance: {account.Balance} ISK.");

                    mtx.Status = TransactionStatus.Rejected;
                    account.MarketTransactions.Add(mtx);
                    await _context.SaveChangesAsync();

                    return(null);
                }
            }
            catch (DbUpdateConcurrencyException)
            {
                _logger.LogError($"DbUpdateConcurrencyException: {accountId} {isk} ISK order cancelled.");
            }

            return(null);
        }
Пример #6
0
        public async Task <ActionResult <string> > Withdraw(BitcoinWithdrawal withdrawal)
        {
            if (MathDecimals.GetDecimals(withdrawal.Amount) > 8)
            {
                return(BadRequest("withdrawal amount cannot have more than 8 decimals"));
            }

            if (MathDecimals.GetDecimals(withdrawal.Fees) > 8)
            {
                return(BadRequest("withdrawal fees cannot have more than 8 decimals"));
            }

            string accountIdString = User.FindFirstValue(ClaimTypes.NameIdentifier);

            if (accountIdString == null)
            {
                return(BadRequest("AccountId missing from request"));
            }

            int accountId = int.Parse(accountIdString);

            var account = await _context.Account
                          .Include(x => x.MarketTransactions)
                          .FirstOrDefaultAsync(x => x.Id == accountId);

            if (account == null)
            {
                return(NotFound("User not found in database"));
            }

            if (account.WithdrawalAddress == null)
            {
                return(NotFound("User has not set a withdrawal address"));
            }

            var   address = BitcoinAddress.Create(account.WithdrawalAddress, Network.Main);
            Money amount  = Money.FromUnit(withdrawal.Amount, MoneyUnit.BTC);
            Money fees    = Money.FromUnit(withdrawal.Fees, MoneyUnit.BTC);

            var result = await _bitcoin.SendBitcoin(accountId, address, amount, fees);

            if (result == null)
            {
                return(Conflict("Failed to create/send transaction"));
            }

            decimal rate = Decimal.Zero;

            if (_ticker.MarketState == MarketState.Open)
            {
                rate = _ticker.Tickers["btcisk"].Ask;
            }

            MarketTransaction mtx = new MarketTransaction
            {
                AccountId = accountId,
                Time      = DateTime.Now,
                Coins     = -(withdrawal.Amount + withdrawal.Fees),
                TxId      = result.ToString(),
                Type      = TransactionType.Withdrawal,
                Rate      = rate,
                Status    = TransactionStatus.Completed
            };

            account.MarketTransactions.Add(mtx);
            await _context.SaveChangesAsync();

            return(result.ToString());
        }
Пример #7
0
        public async Task <ActionResult <decimal> > Withdraw([FromBody] decimal amount)
        {
            string accountIdString = User.FindFirstValue(ClaimTypes.NameIdentifier);

            if (accountIdString == null)
            {
                return(BadRequest("AccountId missing from request"));
            }

            int accountId = int.Parse(accountIdString);

            var account = await _context.Account
                          .Include(x => x.MarketTransactions)
                          .FirstOrDefaultAsync(x => x.Id == accountId);

            if (account == null)
            {
                return(NotFound("User not found in database"));
            }

            if (account.BankAccountNumber == null)
            {
                return(NotFound("User has not set a bank account number"));
            }

            if (amount <= 0 || amount > 10000000)
            {
                return(BadRequest("Invalid amount"));
            }

            if (account.Balance - amount >= 0)
            {
                try
                {
                    _logger.LogCritical($"{account.Id} is withdrawing {amount} ISK to {account.BankAccountNumber}");
                    account.Balance -= amount;
                    await _context.SaveChangesAsync();

                    string hq     = account.BankAccountNumber.Substring(0, 4);
                    string hb     = account.BankAccountNumber.Substring(4, 2);
                    string num    = account.BankAccountNumber.Substring(6, 6);
                    bool   result = _landsbankinn.Pay(hq, hb, num, account.Kennitala, amount);

                    MarketTransaction mtx = new MarketTransaction
                    {
                        AccountId = accountId,
                        Time      = DateTime.Now,
                        Amount    = -amount,
                        Type      = TransactionType.Withdrawal,
                        Status    = TransactionStatus.Completed
                    };

                    if (result == false)
                    {
                        mtx.Status = TransactionStatus.Failed;
                        return(Conflict("Failed to create/send transaction"));
                    }

                    account.MarketTransactions.Add(mtx);
                    await _context.SaveChangesAsync();

                    _logger.LogCritical($"Withdrawal successful");

                    return(Ok(account.Balance));
                }
                catch (Exception e)
                {
                    _logger.LogError(e.ToString());
                    return(NotFound());
                }
            }

            return(NotFound("tf did you just try to do?"));
        }
Пример #8
0
        private void PubRoutine()
        {
            if (_pubSocket != null)
            {
                while (true)
                {
                    try
                    {
                        byte[] tmp;
                        if (_marketDataTmp.Count > 0 && _marketDataTmp.TryDequeue(out tmp))
                        {
                            using (MemoryStream stream = new MemoryStream(tmp))
                            {
                                MarketData data = _fmt.Deserialize(stream) as MarketData;
                                if (data != null)
                                {
                                    //更新当前市场数据
                                    if (_currentMarketDatas.ContainsKey(data.Code))
                                    {
                                        _currentMarketDatas[data.Code] = data;
                                    }
                                    else
                                    {
                                        _currentMarketDatas.TryAdd(data.Code, data);
                                    }
                                    //发布市场数据
                                    if (_subCodes.ContainsKey(data.Code))
                                    {
                                        using (MemoryStream stream1 = new MemoryStream())
                                        {
                                            _fmt.Serialize(stream1, data);
                                            byte[] td = stream1.ToArray();
                                            using (ZMessage msg = new ZMessage())
                                            {
                                                msg.Add(new ZFrame(data.Code + ":" + "MarketData"));
                                                msg.Add(new ZFrame(td));
                                                lock (_pubSocket)
                                                {
                                                    _pubSocket.Send(msg);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            _bytePool.Free(tmp);
                        }
                        else if (_marketTransactionTmp.Count > 0 && _marketTransactionTmp.TryDequeue(out tmp))
                        {
                            using (MemoryStream stream = new MemoryStream(tmp))
                            {
                                MarketTransaction trans = _fmt.Deserialize(stream) as MarketTransaction;
                                if (trans != null)
                                {
                                    //更新最近成交
                                    if (_lastTransactions.ContainsKey(trans.Code))
                                    {
                                        _lastTransactions[trans.Code] = trans;
                                    }
                                    else
                                    {
                                        _lastTransactions.TryAdd(trans.Code, trans);
                                    }
                                    //发布最新成交
                                    if (_subCodes.ContainsKey(trans.Code))
                                    {
                                        using (MemoryStream stream1 = new MemoryStream())
                                        {
                                            _fmt.Serialize(stream1, trans);
                                            byte[] td = stream1.ToArray();
                                            using (ZMessage msg = new ZMessage())
                                            {
                                                msg.Add(new ZFrame(trans.Code + ":" + "MarketTransaction"));
                                                msg.Add(new ZFrame(td));
                                                lock (_pubSocket)
                                                {
                                                    _pubSocket.Send(msg);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            _bytePool.Free(tmp);
                        }
                        else
                        {
                            Thread.Sleep(50);
                        }
                    }
                    catch (Exception ex)
                    {
                        AASClient.Program.logger.LogRunning("DataServerClient:数据发送错误!{0}", ex.Message);
                    }
                }
            }
        }
Пример #9
0
        public override void Construct()
        {
            Transaction = null;
            Result      = MarketDialogResult.Pending;

            Border = "border-fancy";

            var bottomRow = AddChild(new Widget
            {
                AutoLayout  = AutoLayout.DockBottom,
                MinimumSize = new Point(0, 32)
            });

            bottomRow.AddChild(new Gui.Widgets.Button
            {
                Font       = "font10",
                Border     = "border-button",
                TextColor  = new Vector4(0, 0, 0, 1),
                Text       = "Propose Trade",
                AutoLayout = AutoLayout.DockRight,
                OnClick    = (sender, args) =>
                {
                    if (PlayerColumns.Valid)
                    {
                        if (PlayerColumns.SelectedResources.Count == 0)
                        {
                            Root.ShowModalMessage("You've selected nothing to trade.");
                        }
                        else
                        {
                            Result      = MarketDialogResult.Propose;
                            Transaction = new MarketTransaction
                            {
                                PlayerEntity = Player,
                                PlayerItems  = PlayerColumns.SelectedResources,
                                PlayerMoney  = ComputeNetValue()
                            };

                            Root.SafeCall(OnPlayerAction, this);
                        }
                    }
                    else
                    {
                        Root.ShowTooltip(Root.MousePosition, "Trade is invalid");
                    }
                }
            });

            bottomRow.AddChild(new Gui.Widgets.Button
            {
                Font       = "font10",
                Border     = "border-button",
                TextColor  = new Vector4(0, 0, 0, 1),
                Text       = "Clear",
                Tooltip    = "Clear trade",
                AutoLayout = AutoLayout.DockRight,
                OnClick    = (sender, args) =>
                {
                    PlayerColumns.Reconstruct(Player.Resources, new List <ResourceAmount>(), (int)Player.Money);
                    UpdateBottomDisplays();
                    Layout();
                }
            });

            bottomRow.AddChild(new Gui.Widgets.Button
            {
                Font       = "font10",
                Border     = "border-button",
                TextColor  = new Vector4(0, 0, 0, 1),
                Text       = "Stop",
                Tooltip    = "Stop trading.",
                AutoLayout = AutoLayout.DockRight,
                //OnLayout = (sender) => sender.Rect.X -= 16,
                OnClick = (sender, args) =>
                {
                    Result = MarketDialogResult.Cancel;
                    Root.SafeCall(OnPlayerAction, this);
                    //this.Close();
                }
            });

            TotalDisplay = bottomRow.AddChild(new Widget
            {
                MinimumSize         = new Point(256, 64),
                AutoLayout          = AutoLayout.DockFill,
                Font                = "font10",
                TextColor           = new Vector4(0, 0, 0, 1),
                TextVerticalAlign   = VerticalAlign.Bottom,
                TextHorizontalAlign = HorizontalAlign.Left,
                Text                = "Total Profit: $0"
            });

            var mainPanel = AddChild(new Columns
            {
                AutoLayout = AutoLayout.DockFill
            });

            PlayerColumns = mainPanel.AddChild(new ResourceColumns
            {
                TradeEntity            = Player,
                ValueSourceEntity      = Player,
                AutoLayout             = AutoLayout.DockFill,
                ReverseColumnOrder     = true,
                LeftHeader             = "Our Items",
                RightHeader            = "We Offer",
                MoneyLabel             = "Our money",
                OnTotalSelectedChanged = (s) => UpdateBottomDisplays(),
                Tag            = "trade_money",
                ShowMoneyField = false
            }) as ResourceColumns;

            UpdateBottomDisplays();
        }
Пример #10
0
        private void MarketDataRoutine(object obj)
        {
            int index = (int)obj;

            while (true)
            {
                if (_isRunning == true && _source != null)
                {
                    if (_source.MarketDataCache.Count > 0)
                    {
                        TDFMarketData[] tmd;
                        if (_source.MarketDataCache.TryDequeue(out tmd))
                        {
                            MarketData[] md = new MarketData[tmd.Length];
                            for (int i = 0; i < tmd.Length; i++)
                            {
                                md[i]           = new MarketData();
                                md[i].WindCode  = tmd[i].WindCode;
                                md[i].Code      = tmd[i].Code;
                                md[i].ActionDay = tmd[i].ActionDay;
                                md[i].Time      = tmd[i].Time;
                                md[i].Status    = tmd[i].Status;
                                md[i].PreClose  = tmd[i].PreClose;
                                md[i].Open      = tmd[i].Open;
                                md[i].High      = tmd[i].High;
                                md[i].Low       = tmd[i].Low;
                                md[i].Match     = tmd[i].Match;
                                for (int j = 0; j < 10; j++)
                                {
                                    md[i].AskPrice[j] = tmd[i].AskPrice[j];
                                    md[i].AskVol[j]   = (int)tmd[i].AskVol[j];
                                    md[i].BidPrice[j] = tmd[i].BidPrice[j];
                                    md[i].BidVol[j]   = (int)tmd[i].BidVol[j];
                                }
                                md[i].NumTrades           = (int)(tmd[i].NumTrades);
                                md[i].Volume              = (int)(tmd[i].Volume);
                                md[i].Turnover            = tmd[i].Turnover;
                                md[i].TotalAskVol         = (int)(tmd[i].TotalAskVol);
                                md[i].TotalBidVol         = (int)(tmd[i].TotalBidVol);
                                md[i].WeightedAvgAskPrice = tmd[i].WeightedAvgAskPrice;
                                md[i].WeightedAvgBidPrice = tmd[i].WeightedAvgBidPrice;
                                md[i].IOPV            = tmd[i].IOPV;
                                md[i].YieldToMaturity = tmd[i].YieldToMaturity;
                                md[i].HighLimited     = tmd[i].HighLimited;
                                md[i].LowLimited      = tmd[i].LowLimited;
                                tmd[i].Prefix.CopyTo(md[i].Prefix, 0);
                                md[i].Syl1 = tmd[i].Syl1;
                                md[i].Syl2 = tmd[i].Syl2;
                                md[i].SD2  = tmd[i].SD2;
                            }
                            lock (this)
                            {
                                _recvDataCount += tmd.Length;
                            }
                            if (NewMarketData != null)
                            {
                                NewMarketData(md);
                            }
                        }
                    }
                    else if (_source.OrderCache.Count > 0)
                    {
                        TDFOrder[] oc;
                        if (_source.OrderCache.TryDequeue(out oc))
                        {
                            MarketOrder[] mo = new MarketOrder[oc.Length];
                            for (int i = 0; i < mo.Length; i++)
                            {
                                mo[i]              = new MarketOrder();
                                mo[i].WindCode     = oc[i].WindCode;
                                mo[i].Code         = oc[i].Code;
                                mo[i].ActionDay    = oc[i].ActionDay;
                                mo[i].Time         = oc[i].Time;
                                mo[i].Order        = oc[i].Order;
                                mo[i].Price        = oc[i].Price;
                                mo[i].Volume       = oc[i].Volume;
                                mo[i].OrderKind    = oc[i].OrderKind;
                                mo[i].FunctionCode = oc[i].FunctionCode;
                            }
                            lock (this)
                            {
                                _recvDataCount += oc.Length;
                            }
                            if (NewMarketOrder != null)
                            {
                                NewMarketOrder(mo);
                            }
                        }
                    }
                    else if (_source.TransactionCache.Count > 0)
                    {
                        TDFTransaction[] t;
                        if (_source.TransactionCache.TryDequeue(out t))
                        {
                            MarketTransaction[] mt = new MarketTransaction[t.Length];
                            for (int i = 0; i < t.Length; i++)
                            {
                                mt[i]              = new MarketTransaction();
                                mt[i].WindCode     = t[i].WindCode;
                                mt[i].Code         = t[i].Code;
                                mt[i].ActionDay    = t[i].ActionDay;
                                mt[i].Time         = t[i].Time;
                                mt[i].Index        = t[i].Index;
                                mt[i].Price        = t[i].Price;
                                mt[i].Volume       = t[i].Volume;
                                mt[i].Turnover     = t[i].Turnover;
                                mt[i].Flag         = t[i].BSFlag;
                                mt[i].OrderKind    = t[i].OrderKind;
                                mt[i].FunctionCode = t[i].FunctionCode;
                                mt[i].AskOrder     = t[i].AskOrder;
                                mt[i].BidOrder     = t[i].BidOrder;
                            }
                            lock (this)
                            {
                                _recvDataCount += t.Length;
                            }
                            if (NewMarketTransction != null)
                            {
                                NewMarketTransction(mt);
                            }
                        }
                    }
                    else if (_source.OrderQueueCache.Count > 0)
                    {
                        TDFOrderQueue[] oq;
                        if (_source.OrderQueueCache.TryDequeue(out oq))
                        {
                            MarketOrderQueue[] moq = new MarketOrderQueue[oq.Length];
                            for (int i = 0; i < oq.Length; i++)
                            {
                                moq[i]           = new MarketOrderQueue();
                                moq[i].WindCode  = oq[i].WindCode;
                                moq[i].Code      = oq[i].Code;
                                moq[i].ActionDay = oq[i].ActionDay;
                                moq[i].Time      = oq[i].Time;
                                moq[i].Side      = oq[i].Side;
                                moq[i].Price     = oq[i].Price;
                                moq[i].Orders    = oq[i].Orders;
                                moq[i].Items     = oq[i].ABItems;
                                oq[i].ABVolume.CopyTo(moq[i].Volume, 0);
                            }
                            lock (this)
                            {
                                _recvDataCount += oq.Length;
                            }
                            if (NewMarketOrderQueue != null)
                            {
                                NewMarketOrderQueue(moq);
                            }
                        }
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }
                }
                else
                {
                    Thread.Sleep(1000);
                }
            }
        }
Пример #11
0
        public async Task <MarketTransactionResult> MakeMarketTransaction(Planet planet, MarketTransaction marketTransaction)
        {
            var marketTransactionResult = new MarketTransactionResult();
            var p = await _planetRepository.GetAsync(planet.PlanetId);

            if (p != null)
            {
                var market = p.Market;

                if (marketTransaction.TransactionType == "sell")
                {
                    var item = market.ConsumableItems.FirstOrDefault(x => x.ItemId == marketTransaction.ItemId);
                    if (item.Amount + marketTransaction.Amount > item.MaxAmount)
                    {
                        marketTransactionResult.Result = false;
                    }
                    else
                    {
                        item.Amount = item.Amount + marketTransaction.Amount;
                        marketTransactionResult.Result           = true;
                        marketTransactionResult.TransactionType  = marketTransaction.TransactionType;
                        marketTransactionResult.TransactionValue = marketTransaction.Amount * item.BaseValue;
                    }
                }
                else
                if (marketTransaction.TransactionType == "buy")
                {
                    var item = market.ProductionItems.FirstOrDefault(x => x.ItemId == marketTransaction.ItemId);
                    if (item.Amount - marketTransaction.Amount <= 0)
                    {
                        marketTransactionResult.Result = false;
                    }
                    else
                    {
                        item.Amount = item.Amount - marketTransaction.Amount;
                        marketTransactionResult.Result           = true;
                        marketTransactionResult.TransactionType  = marketTransaction.TransactionType;
                        marketTransactionResult.TransactionValue = marketTransaction.Amount * item.BaseValue;
                    }
                }
            }
            else
            {
                marketTransactionResult.Result = false;
            }
            return(marketTransactionResult);
        }