程序员的量化交易之路(32)--Cointrade之Portfolio组合(19)

IAT339-Portfolio:IAT339的投资组合 IAT339-投资组合 立即下载

转载须注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents,http://cloudtrade.top/


Portfolio:组合,代表的是多个证券组合在一起为了完成某一策略 。组合中每个证券都有自己的仓位(Position)。我们的策略就是要控制组合的Position进而涉及到买卖,订单。

Portfolio代码:

package org.cryptocoinpartners.schema;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.inject.Inject;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.NoResultException;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.apache.commons.lang.NotImplementedException;
import org.cryptocoinpartners.enumeration.PositionType;
import org.cryptocoinpartners.enumeration.TransactionType;
import org.cryptocoinpartners.module.Context;
import org.cryptocoinpartners.service.PortfolioService;
import org.cryptocoinpartners.util.PersistUtil;
import org.cryptocoinpartners.util.Remainder;
import org.slf4j.Logger;

import com.google.inject.Singleton;

/**
 * Many Owners may have Stakes in the Portfolio, but there is only one PortfolioManager, who is not necessarily an Owner.  The
 * Portfolio has multiple Positions.
 *
 * @author Tim Olson
 */
@Entity
@Singleton
@Cacheable
public class Portfolio extends EntityBase {

    private static Object lock = new Object();

    /** returns all Positions, whether they are tied to an open Order or not.  Use getTradeablePositions() */
    public @Transient
    Collection<Fill> getDetailedPositions() {
        Collection<Fill> allPositions = new ConcurrentLinkedQueue<Fill>();

        for (Asset asset : positions.keySet()) {
            for (Exchange exchange : positions.get(asset).keySet()) {
                for (Listing listing : positions.get(asset).get(exchange).keySet()) {
                    for (TransactionType transactionType : positions.get(asset).get(exchange).get(listing).keySet()) {
                        for (Iterator<Position> itp = positions.get(asset).get(exchange).get(listing).get(transactionType).iterator(); itp.hasNext();) {
                            Position pos = itp.next();
                            for (Fill fill : pos.getFills()) {
                                allPositions.add(fill);
                            }
                        }
                    }

                }
            }
        }

        return allPositions;
    }

    protected @Transient
    void persistPositions() {
        for (Asset asset : positions.keySet()) {
            for (Exchange exchange : positions.get(asset).keySet()) {
                for (Listing listing : positions.get(asset).get(exchange).keySet()) {
                    for (TransactionType transactionType : positions.get(asset).get(exchange).get(listing).keySet()) {

                        for (Position position : positions.get(asset).get(exchange).get(listing).get(transactionType)) {
                            position.Merge();
                        }
                    }
                }
            }
        }
    }

    public @Transient
    Collection<Position> getPositions() {
        ConcurrentLinkedQueue<Position> allPositions = new ConcurrentLinkedQueue<Position>();
        for (Asset asset : positions.keySet()) {
            for (Exchange exchange : positions.get(asset).keySet()) {
                for (Listing listing : positions.get(asset).get(exchange).keySet()) {
                    for (TransactionType transactionType : positions.get(asset).get(exchange).get(listing).keySet()) {
                        Amount longVolume = DecimalAmount.ZERO;
                        Amount longAvgPrice = DecimalAmount.ZERO;
                        Amount longAvgStopPrice = DecimalAmount.ZERO;
                        Amount shortVolume = DecimalAmount.ZERO;
                        Amount shortAvgPrice = DecimalAmount.ZERO;
                        Amount shortAvgStopPrice = DecimalAmount.ZERO;
                        for (Position position : positions.get(asset).get(exchange).get(listing).get(transactionType)) {
                            allPositions.add(position);
                            //                            for (Fill pos : position.getFills()) {
                            //
                            //                                if (pos.isLong()) {
                            //                                    longAvgPrice = ((longAvgPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getPrice(),
                            //                                            Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                            //                                    if (pos.getStopPrice() != null)
                            //                                        longAvgStopPrice = ((longAvgStopPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(
                            //                                                pos.getStopPrice(), Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()),
                            //                                                Remainder.ROUND_EVEN);
                            //
                            //                                    longVolume = longVolume.plus(pos.getOpenVolume());
                            //                                } else if (pos.isShort()) {
                            //                                    shortAvgPrice = ((shortAvgPrice.times(shortVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getPrice(),
                            //                                            Remainder.ROUND_EVEN))).dividedBy(shortVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                            //                                    if (pos.getStopPrice() != null)
                            //                                        shortAvgStopPrice = ((shortAvgStopPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(
                            //                                                pos.getStopPrice(), Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()),
                            //                                                Remainder.ROUND_EVEN);
                            //
                            //                                    shortVolume = shortVolume.plus(pos.getOpenVolume());
                            //                                }
                            //                            }
                        }
                        // need to change this to just return one position that is the total, not one long and one short.
                        //                        if (!shortVolume.isZero() || !longVolume.isZero()) {
                        //                            Market market = Market.findOrCreate(exchange, listing);
                        //                            Fill pos = new Fill();
                        //                            pos.setPortfolio(this);
                        //                            pos.setMarket(market);
                        //
                        //                            pos.setPriceCount(longAvgPrice.toBasis(market.getPriceBasis(), Remainder.ROUND_EVEN).getCount());
                        //                            pos.setVolumeCount(longVolume.toBasis(market.getPriceBasis(), Remainder.ROUND_EVEN).getCount());
                        //                            Position position = new Position(pos);
                        //                            allPositions.add(position);
                        //                        }

                    }
                }
            }
        }

        return allPositions;
    }

    public @Transient
    Position getPosition(Asset asset, Market market) {
        //ArrayList<Position> allPositions = new ArrayList<Position>();
        Position position = null;
        //TODO need to add these per portfoio, portoflio should not be null
        //  Position position = new Position(null, market.getExchange(), market, asset, DecimalAmount.ZERO, DecimalAmount.ZERO);
        // new ConcurrentLinkedQueue<Transaction>();
        Collection<Fill> fills = new ConcurrentLinkedQueue<Fill>();
        for (TransactionType transactionType : positions.get(asset).get(market.getExchange()).get(market.getListing()).keySet()) {

            //            Amount longVolume = DecimalAmount.ZERO;
            //            Amount longAvgPrice = DecimalAmount.ZERO;
            //            Amount longAvgStopPrice = DecimalAmount.ZERO;
            //            Amount shortVolume = DecimalAmount.ZERO;
            //            Amount shortAvgPrice = DecimalAmount.ZERO;
            //            Amount shortAvgStopPrice = DecimalAmount.ZERO;
            for (Position detailedPosition : positions.get(asset).get(market.getExchange()).get(market.getListing()).get(transactionType)) {

                for (Fill pos : detailedPosition.getFills()) {
                    fills.add(pos);

                    //                    if (pos.isLong()) {
                    //                        longAvgPrice = ((longAvgPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getPrice(),
                    //                                Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                    //                        if (pos.getStopPrice() != null)
                    //                            longAvgStopPrice = ((longAvgStopPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getStopPrice(),
                    //                                    Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                    //
                    //                        longVolume = longVolume.plus(pos.getOpenVolume());
                    //                    } else if (pos.isShort()) {
                    //                        shortAvgPrice = ((shortAvgPrice.times(shortVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getPrice(),
                    //                                Remainder.ROUND_EVEN))).dividedBy(shortVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                    //                        if (pos.getStopPrice() != null)
                    //                            shortAvgStopPrice = ((shortAvgStopPrice.times(longVolume, Remainder.ROUND_EVEN)).plus(pos.getOpenVolume().times(pos.getStopPrice(),
                    //                                    Remainder.ROUND_EVEN))).dividedBy(longVolume.plus(pos.getOpenVolume()), Remainder.ROUND_EVEN);
                    //
                    //                        shortVolume = shortVolume.plus(pos.getOpenVolume());
                }
            }
        }
        // need to change this to just return one position that is the total, not one long and one short.

        //        
        //        if (!shortVolume.isZero() || !longVolume.isZero()) {
        //                Fill pos = new Fill();
        //                pos.setPortfolio(this);
        //                pos.setMarket(market);
        //
        //                pos.setPriceCount(longAvgPrice.toBasis(market.getPriceBasis(), Remainder.ROUND_EVEN).getCount());
        //                pos.setVolumeCount(longVolume.toBasis(market.getVolumeBasis(), Remainder.ROUND_EVEN).getCount());
        //                position = new Position(pos);
        //                //allPositions.add(position);
        //            }

        return new Position(fills);
        //  return position;

    }

    public @Transient
    Collection<Position> getPositions(Asset asset, Exchange exchange) {
        Collection<Position> allPositions = new ConcurrentLinkedQueue<Position>();

        if (positions.get(asset) != null && positions.get(asset).get(exchange) != null) {
            synchronized (lock) {
                for (Iterator<Listing> itl = positions.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                    Listing listing = itl.next();
                    for (Iterator<TransactionType> itt = positions.get(asset).get(exchange).get(listing).keySet().iterator(); itt.hasNext();) {
                        TransactionType transactionType = itt.next();

                        for (Iterator<Position> itp = positions.get(asset).get(exchange).get(listing).get(transactionType).iterator(); itp.hasNext();) {
                            Position pos = itp.next();
                            allPositions.add(pos);
                        }
                    }
                }
            }
        }

        return allPositions;

    }

    public @Transient
    ConcurrentHashMap<Asset, Amount> getRealisedPnLs() {

        ConcurrentHashMap<Asset, Amount> allPnLs = new ConcurrentHashMap<Asset, Amount>();
        synchronized (lock) {
            for (Iterator<Asset> it = realisedProfits.keySet().iterator(); it.hasNext();) {

                Asset asset = it.next();
                for (Iterator<Exchange> ite = realisedProfits.get(asset).keySet().iterator(); ite.hasNext();) {
                    Exchange exchange = ite.next();
                    for (Iterator<Listing> itl = realisedProfits.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                        Listing listing = itl.next();
                        Amount realisedPnL = realisedProfits.get(asset).get(exchange).get(listing);

                        if (allPnLs.get(asset) == null) {
                            allPnLs.put(asset, realisedPnL);
                        } else {
                            allPnLs.put(asset, allPnLs.get(asset).plus(realisedPnL));
                        }
                    }

                }

            }
        }

        return allPnLs;
    }

    public @Transient
    Amount getRealisedPnL(Asset asset) {

        Amount realisedPnL = DecimalAmount.ZERO;
        for (Iterator<Exchange> ite = realisedProfits.get(asset).keySet().iterator(); ite.hasNext();) {
            Exchange exchange = ite.next();
            for (Iterator<Listing> itl = realisedProfits.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                Listing listing = itl.next();
                realisedPnL = realisedPnL.plus(realisedProfits.get(asset).get(exchange).get(listing));

            }
        }

        return realisedPnL;
    }

    public @Transient
    ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, Amount>>> getRealisedPnL() {

        return realisedProfits;
    }

    public @Transient
    DiscreteAmount getLongPosition(Asset asset, Exchange exchange) {
        long longVolumeCount = 0;
        synchronized (lock) {
            if (positions.get(asset) != null && positions.get(asset).get(exchange) != null) {
                for (Iterator<Listing> itl = positions.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                    Listing listing = itl.next();
                    for (Position itpos : positions.get(asset).get(exchange).get(listing).get(TransactionType.BUY)) {

                        for (Iterator<Fill> itp = itpos.getFills().iterator(); itp.hasNext();) {
                            Fill pos = itp.next();
                            longVolumeCount += pos.getOpenVolumeCount();
                        }
                    }

                }
            }
        }
        return new DiscreteAmount(longVolumeCount, asset.getBasis());

    }

    public @Transient
    DiscreteAmount getNetPosition(Asset asset, Exchange exchange) {
        long netVolumeCount = 0;
        Fill pos = null;
        synchronized (lock) {
            if (positions.get(asset) != null && positions.get(asset).get(exchange) != null) {
                for (Iterator<Listing> itl = positions.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                    Listing listing = itl.next();
                    for (Iterator<TransactionType> itt = positions.get(asset).get(exchange).get(listing).keySet().iterator(); itt.hasNext();) {
                        TransactionType transactionType = itt.next();

                        for (Position itpos : positions.get(asset).get(exchange).get(listing).get(transactionType)) {
                            for (Iterator<Fill> itp = itpos.getFills().iterator(); itp.hasNext();) {

                                pos = itp.next();
                                netVolumeCount += pos.getOpenVolumeCount();
                            }
                        }

                    }
                }
            }
        }
        return new DiscreteAmount(netVolumeCount, asset.getBasis());
    }

    public @Transient
    DiscreteAmount getShortPosition(Asset asset, Exchange exchange) {
        long shortVolumeCount = 0;
        synchronized (lock) {

            if (positions.get(asset) != null && positions.get(asset).get(exchange) != null) {
                for (Iterator<Listing> itl = positions.get(asset).get(exchange).keySet().iterator(); itl.hasNext();) {
                    Listing listing = itl.next();

                    for (Position itpos : positions.get(asset).get(exchange).get(listing).get(TransactionType.SELL)) {
                        for (Iterator<Fill> itp = itpos.getFills().iterator(); itp.hasNext();) {

                            Fill pos = itp.next();
                            shortVolumeCount += pos.getOpenVolumeCount();

                        }
                    }
                }
            }
        }
        return new DiscreteAmount(shortVolumeCount, asset.getBasis());

    }

    // public @OneToMany ConcurrentHashMap<BalanceType, List<Wallet>> getBalances() { return balances; }

    /**
     * Returns all Positions in the Portfolio which are not reserved as payment for an open Order
     */
    @Transient
    public Collection<Position> getTradeableBalance(Exchange exchange) {
        throw new NotImplementedException();
    }

    @Transient
    public Collection<Transaction> getTransactions() {
        ConcurrentLinkedQueue<Transaction> allTransactions = new ConcurrentLinkedQueue<Transaction>();
        for (Iterator<Asset> it = transactions.keySet().iterator(); it.hasNext();) {
            Asset asset = it.next();
            for (Iterator<Exchange> ite = transactions.get(asset).keySet().iterator(); ite.hasNext();) {
                Exchange exchange = ite.next();
                for (Iterator<TransactionType> itt = transactions.get(asset).get(exchange).keySet().iterator(); itt.hasNext();) {
                    TransactionType type = itt.next();
                    for (Iterator<Transaction> ittr = transactions.get(asset).get(exchange).get(type).iterator(); ittr.hasNext();) {
                        Transaction tran = ittr.next();
                        allTransactions.add(tran);
                    }

                }
            }

        }
        return allTransactions;

    }

    @Transient
    public void removeTransaction(Transaction reservation) {
        if (transactions.get(reservation.getCurrency()) == null)
            return;
        if (transactions.get(reservation.getCurrency()).get(reservation.getExchange()) == null)
            return;
        if (transactions.get(reservation.getCurrency()).get(reservation.getExchange()).get(reservation.getType()) == null)
            return;
        synchronized (lock) {
            transactions.get(reservation.getCurrency()).get(reservation.getExchange()).get(reservation.getType()).remove(reservation);

            //            Iterator<Transaction> it = transactions.get(reservation.getCurrency()).get(reservation.getExchange()).get(reservation.getType()).iterator();
            //            while (it.hasNext()) {
            //                Transaction transaction = it.next();
            //                if (transaction != null && reservation != null && transaction.equals(reservation))
            //                    it.remove();
            // }
        }
    }

    /**
     * This is the main way for a Strategy to determine what assets it has available for trading
     */
    @Transient
    public Collection<Position> getReservedBalances(Exchange exchange) {
        throw new NotImplementedException();
    }

    /**
     * This is the main way for a Strategy to determine how much of a given asset it has available for trading
     * @param f
     * @return
     */
    @Transient
    public Collection<Position> getTradeableBalanceOf(Exchange exchange, Asset asset) {

        throw new NotImplementedException();
    }

    /**
     * Finds a Position in the Portfolio which has the same Asset as p, then breaks it into the amount p requires
     * plus an unreserved amount.  The resevered Position is then associated with the given order, while
     * the unreserved remainder of the Position has getOrder()==null.  To un-reserve the Position, call release(order)
     *
     * @param order the order which will be placed
     * @param p the cost of the order.  could be a different fungible than the order's quote fungible
     * @throws IllegalArgumentException
     */
    @Transient
    public void reserve(SpecificOrder order, Position p) throws IllegalArgumentException {
        throw new NotImplementedException();
    }

    @Transient
    public void release(SpecificOrder order) {
        throw new NotImplementedException();
    }

    @Transient
    public boolean addTransaction(Transaction transaction) {
        portfolioService.resetBalances();
        ConcurrentHashMap<Exchange, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>> assetTransactions = transactions.get(transaction
                .getCurrency());

        if (assetTransactions == null) {
            ConcurrentLinkedQueue<Transaction> transactionList = new ConcurrentLinkedQueue<Transaction>();
            assetTransactions = new ConcurrentHashMap<Exchange, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>>();
            transactionList.add(transaction);
            ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>> transactionGroup = new ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>();
            transactionGroup.put(transaction.getType(), transactionList);
            assetTransactions.put(transaction.getExchange(), transactionGroup);
            transactions.put(transaction.getCurrency(), assetTransactions);
            return true;
        } else {
            //asset is present, so check the market
            ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>> exchangeTransactions = assetTransactions.get(transaction.getExchange());

            if (exchangeTransactions == null) {
                ConcurrentLinkedQueue<Transaction> transactionList = new ConcurrentLinkedQueue<Transaction>();
                transactionList.add(transaction);
                ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>> transactionGroup = new ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>();
                transactionGroup.put(transaction.getType(), transactionList);
                assetTransactions.put(transaction.getExchange(), transactionGroup);

                return true;
            } else {
                ConcurrentLinkedQueue<Transaction> transactionList = exchangeTransactions.get(transaction.getType());

                if (transactionList == null) {
                    transactionList = new ConcurrentLinkedQueue<Transaction>();
                    transactionList.add(transaction);
                    exchangeTransactions.put(transaction.getType(), transactionList);
                    return true;
                } else {
                    transactionList.add(transaction);
                    exchangeTransactions.put(transaction.getType(), transactionList);
                    return true;
                }

            }

        }

    }

    /**
     * finds other Positions in this portfolio which have the same Exchange and Asset and merges this position's
     * amount into the found position's amount, thus maintaining only one Position for each Exchange/Asset pair.
     * this method does not remove the position from the positions list.
     * @return true iff another position was found and merged
     */

    protected void publishPositionUpdate(Position position, PositionType lastType, Market market) {

        PositionType mergedType = (position.isShort()) ? PositionType.SHORT : (position.isLong()) ? PositionType.LONG : PositionType.FLAT;

        context.route(new PositionUpdate(position, market, lastType, mergedType));
    }

    @Transient
    public void insert(Position position) {
        TransactionType transactionType = (position.isLong()) ? TransactionType.BUY : TransactionType.SELL;

        ConcurrentLinkedQueue<Position> detailPosition = new ConcurrentLinkedQueue<Position>();
        //Position detPosition = new Position(fill);
        //detPosition.Persit();
        detailPosition.add(position);
        ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>> positionType = new ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>();
        positionType.put(transactionType, detailPosition);
        ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>> listingPosition = new ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>();

        listingPosition.put(position.getMarket().getListing(), positionType);

        ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>> assetPositions = new ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>>();
        assetPositions.put(position.getMarket().getExchange(), listingPosition);
        positions.put(position.getMarket().getBase(), assetPositions);

    }

    @Transient
    private boolean merge(Fill fill) {
        //synchronized (lock) {
        // We need to have a queue of buys and a queue of sells ( two array lists), ensure the itterator is descendingIterator for LIFO,
        // when we get a new trade coem in we add it to the buy or sell queue
        // 1) caluate price difference
        // 2) times price diff by min(trade quantity or the position) and add to relasied PnL
        // 3) update the quaitity of the postion and remove from queue if zero
        // 4) move onto next postion until the qty =0

        // https://github.com/webpat/jquant-core/blob/173d5ca79b318385a3754c8e1357de79ece47be4/src/main/java/org/jquant/portfolio/Portfolio.java
        TransactionType transactionType = (fill.isLong()) ? TransactionType.BUY : TransactionType.SELL;
        TransactionType openingTransactionType = (transactionType.equals(TransactionType.BUY)) ? TransactionType.SELL : TransactionType.BUY;

        ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>> assetPositions = positions
                .get(fill.getMarket().getBase());
        ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>> listingPosition = new ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>();
        //ConcurrentHashMap<Listing, ArrayList<Position>> listingPosition = new ConcurrentHashMap<Listing, ArrayList<Position>>();

        ConcurrentHashMap<Listing, Amount> marketRealisedProfits;
        ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, Amount>> assetRealisedProfits = realisedProfits.get(fill.getMarket().getTradedCurrency());
        if (assetRealisedProfits != null) {
            marketRealisedProfits = assetRealisedProfits.get(fill.getMarket().getListing());
        }

        if (assetPositions == null) {
            ConcurrentLinkedQueue<Position> detailPosition = new ConcurrentLinkedQueue<Position>();
            Position detPosition = new Position(fill);
            detPosition.Persit();
            detailPosition.add(detPosition);
            ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>> positionType = new ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>();
            positionType.put(transactionType, detailPosition);

            listingPosition.put(fill.getMarket().getListing(), positionType);
            assetPositions = new ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>>();
            assetPositions.put(fill.getMarket().getExchange(), listingPosition);
            positions.put(fill.getMarket().getBase(), assetPositions);

            Amount profits = DecimalAmount.ZERO;
            if (assetRealisedProfits == null) {
                assetRealisedProfits = new ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, Amount>>();
                marketRealisedProfits = new ConcurrentHashMap<Listing, Amount>();
                marketRealisedProfits.put(fill.getMarket().getListing(), profits);
                assetRealisedProfits.put(fill.getMarket().getExchange(), marketRealisedProfits);
                realisedProfits.put(fill.getMarket().getTradedCurrency(), assetRealisedProfits);
            }
            publishPositionUpdate(getPosition(fill.getMarket().getBase(), fill.getMarket()), PositionType.FLAT, fill.getMarket());
            return true;
        } else {
            //asset is present, so check the market
            ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>> exchangePositions = assetPositions.get(fill
                    .getMarket().getExchange());
            //	Amount exchangeRealisedProfits = realisedProfits.get(position.getMarket().getTradedCurrency()).get(position.getExchange())
            //	.get(position.getMarket().getListing());

            if (exchangePositions == null) {
                ConcurrentLinkedQueue<Position> detailPosition = new ConcurrentLinkedQueue<Position>();
                ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>> positionType = new ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>();
                Position detPosition = new Position(fill);
                detPosition.Persit();
                detailPosition.add(detPosition);
                positionType.put(transactionType, detailPosition);

                listingPosition.put(fill.getMarket().getListing(), positionType);

                assetPositions.put(fill.getMarket().getExchange(), listingPosition);
                Amount profits = DecimalAmount.ZERO;
                if (realisedProfits.get(fill.getMarket().getTradedCurrency()).get(fill.getMarket().getExchange()).get(fill.getMarket().getListing()) == null) {
                    marketRealisedProfits = new ConcurrentHashMap<Listing, Amount>();
                    marketRealisedProfits.put(fill.getMarket().getListing(), profits);
                    realisedProfits.get(fill.getMarket().getTradedCurrency()).put(fill.getMarket().getExchange(), marketRealisedProfits);
                }
                publishPositionUpdate(getPosition(fill.getMarket().getBase(), fill.getMarket()), PositionType.FLAT, fill.getMarket());

                return true;
            } else {

                //ConcurrentHashMap<TransactionType, ArrayList<Position>> listingPositions = exchangePositions.get(position.getMarket().getListing());
                //asset is present, so check the market
                // need yo vhnage this to have tne cocnurrent hashmap on here
                //ConcurrentHashMap<TransactionType, ArrayList<Position>> listingPositions = exchangePositions.get(position.getMarket().getListing());
                ConcurrentLinkedQueue<Position> listingPositions = exchangePositions.get(fill.getMarket().getListing()).get(transactionType);
                ConcurrentLinkedQueue<Position> openingListingPositions = exchangePositions.get(fill.getMarket().getListing()).get(openingTransactionType);

                if (listingPositions == null) {
                    ConcurrentLinkedQueue<Position> listingsDetailPosition = new ConcurrentLinkedQueue<Position>();
                    Position detPosition = new Position(fill);
                    detPosition.Persit();

                    listingsDetailPosition.add(detPosition);
                    exchangePositions.get(fill.getMarket().getListing()).put(transactionType, listingsDetailPosition);
                    listingPositions = exchangePositions.get(fill.getMarket().getListing()).get(transactionType);
                    Amount listingProfits = DecimalAmount.ZERO;
                    if (realisedProfits.get(fill.getMarket().getTradedCurrency()) == null
                            || realisedProfits.get(fill.getMarket().getTradedCurrency()).get(fill.getMarket().getExchange()) == null
                            || realisedProfits.get(fill.getMarket().getTradedCurrency()).get(fill.getMarket().getExchange()).get(fill.getMarket().getListing()) == null) {
                        marketRealisedProfits = new ConcurrentHashMap<Listing, Amount>();
                        marketRealisedProfits.put(fill.getMarket().getListing(), listingProfits);
                        realisedProfits.get(fill.getMarket().getTradedCurrency()).put(fill.getMarket().getExchange(), marketRealisedProfits);
                    }
                } else {

                    if (!listingPositions.isEmpty() || listingPositions.peek() != null) {
                        listingPositions.peek().addFill(fill);
                        //   listingPositions.peek().Merge();
                        // TODO need to persit the updated postitions
                        //PersistUtil.merge(listingPositions.peek());

                    } else {
                        Position detPosition = new Position(fill);
                        //   detPosition.addFill(fill);
                        listingPositions.add(detPosition);
                        detPosition.Persit();
                        //           PersistUtil.insert(detPosition);
                    }

                }
                if (openingListingPositions != null && !(openingListingPositions.isEmpty())) {
                    //	ArrayList<Position> positions = listingPositions.get(transactionType);

                    //somethign is up with the poistions calcuation for partial closeouts
                    // example 454 lots, closed out 421 lots, then added another 411 lots, total of 444 lots, but the average prices are not correct.
                    // need to update this .					

                    Amount realisedPnL = DecimalAmount.ZERO;
                    long closingVolumeCount = 0;
                    //position.getVolumeCount() 
                    Iterator<Position> itPos = listingPositions.iterator();
                    while (itPos.hasNext()) {
                        // closing position
                        Position pos = itPos.next();

                        Iterator<Fill> itP = pos.getFills().iterator();
                        while (itP.hasNext() && pos.hasFills()) {
                            //closing fill
                            // smoething is not righgt here.
                            Fill p = itP.next();

                            //Fill p = itp.next();
                            //while (p.getVolumeCount() != 0 && itp.hasNext()) {

                            //if (p.getExchange().equals(position.getExchange()) && p.getAsset().equals(position.getAsset())) {

                            Amount entryPrice = DecimalAmount.ZERO;
                            Amount exitPrice = DecimalAmount.ZERO;

                            // now need to get opposit side

                            //  for (Position openPos : openingListingPositions) {
                            Iterator<Position> itOlp = openingListingPositions.iterator();
                            while (itOlp.hasNext() && pos.hasFills()) {
                                // openg postion
                                Position openPos = itOlp.next();
                                Iterator<Fill> itOp = openPos.getFills().iterator();
                                while (itOp.hasNext() && pos.hasFills()) {
                                    //open fill
                                    Fill openPosition = itOp.next();
                                    if (Math.abs(p.getOpenVolumeCount()) > 0) {

                                        if ((Long.signum(openPosition.getOpenVolumeCount()) + Long.signum(p.getOpenVolumeCount())) != 0) {
                                            if (Math.abs(p.getOpenVolumeCount()) == 0 || Math.abs(openPosition.getOpenVolumeCount()) == 0)
                                                // openingListingPositions.(openPosition);
                                                itOp.remove();
                                            openPos.removeFill(openPosition);

                                            if (!openPos.hasFills())
                                                itOlp.remove();
                                            //openingListingPositions.remove(openPos);

                                            // itOp.remove();
                                            //  openPos.removeFill(openPosition);

                                            //  if (Math.abs(openPosition.getOpenVolumeCount()) == 0)
                                            //     openPos.removeFill(openPosition);
                                            //  openingListingPositions.remove(openPosition);
                                            //        PersistUtil.merge(openPos);

                                            //  openingListingPositions.remove(openPos);
                                            break;

                                        }
                                    }
                                    //Math signum();

                                    entryPrice = p.getPrice();
                                    exitPrice = openPosition.getPrice();
                                    if (p.getMarket().getTradedCurrency() == p.getMarket().getBase()) {
                                        // need to invert and revrese the prices if the traded ccy is not the quote ccy
                                        entryPrice = openPosition.getPrice().invert();
                                        exitPrice = p.getPrice().invert();

                                        //shortExitPrice = position.getShortAvgPrice().invert();
                                        //longEntryPrice = p.getLongAvgPrice().invert();
                                        //longExitPrice = position.getLongAvgPrice().invert();
                                        //shortEntryPrice = p.getShortAvgPrice().invert();

                                    } else if (p.getMarket().getTradedCurrency() != p.getMarket().getQuote()) {
                                        throw new NotImplementedException("Listings traded in neither base or quote currency are not supported");
                                    }

                                    // need to calcuate teh volume here
                                    // we have opposite postions, so if I am long, 
                                    // tests
                                    // long - postions =10, net =-5 -> neet ot take 5 max(), postion =10, net =-10 net to take 10 (max), psotis =10, net =-20 net to take  (Min)10
                                    // short postion =-10, net =5 neet to take 5, Max) postions = -10, net =10 need to take 10, postion =-10, net =20 net to take  min 10

                                    // need to srt out closing postions here
                                    // as we use negative numbers not long ans short numbers

                                    //	10,-5 () my volume is 5
                                    //	5,-10 my voulme is 5
                                    //	-10,5 my volume is -5
                                    //	-5,10 my volume is -5
                                    //	10,-10 my voulme is 10

                                    //Math.abs(a)

                                    closingVolumeCount = (openingTransactionType.equals(TransactionType.SELL)) ? (Math.min(
                                            Math.abs(openPosition.getOpenVolumeCount()), Math.abs(p.getOpenVolumeCount())))
                                            * -1 : (Math.min(Math.abs(openPosition.getOpenVolumeCount()), Math.abs(p.getOpenVolumeCount())));
                                    // need to think hwere as one if negative and one is postive, nwee to work out what is the quanity to update on currrnet and the passed position
                                    //when p=43 and open postion =-42
                                    if (Math.abs(p.getOpenVolumeCount()) >= Math.abs(openPosition.getOpenVolumeCount())) {
                                        long updatedVolumeCount = p.getOpenVolumeCount() + closingVolumeCount;
                                        //updatedVolumeCount = (p.isShort()) ? updatedVolumeCount * -1 : updatedVolumeCount;
                                        p.setOpenVolumeCount(updatedVolumeCount);
                                        PersistUtil.merge(p);
                                        // pos.Merge();
                                        if (Math.abs(updatedVolumeCount) == 0) {
                                            //itPos.remove();
                                            itP.remove();
                                            pos.removeFill(p);

                                            //pos.Merge();
                                            if (!pos.hasFills())
                                                itPos.remove();
                                            //listingPositions.remove(pos);

                                            //  itP.remove();
                                            //            PersistUtil.merge(pos);

                                            //listingPositions.remove(pos);
                                        }
                                        // listingPositions.remove(p);
                                        itOp.remove();
                                        openPosition.setOpenVolumeCount(0);
                                        PersistUtil.merge(openPosition);
                                        //openPos.Merge();
                                        //itOp.remove();
                                        //

                                        openPos.removeFill(openPosition);

                                        //openPos.Merge();
                                        //openPos.removeFill(openPosition)

                                        //    PersistUtil.merge(openPos);
                                        if (!openPos.hasFills())
                                            itOlp.remove();
                                        // openingListingPositions.remove(openPos);
                                        //  itOlp.remove();
                                        //
                                        //  openingListingPositions.remove(openPos);

                                        //openingListingPositions.remove(openPosition);

                                    } else {
                                        long updatedVolumeCount = openPosition.getOpenVolumeCount() + p.getOpenVolumeCount();
                                        openPosition.setOpenVolumeCount(updatedVolumeCount);
                                        PersistUtil.merge(openPosition);
                                        // openPos.Merge();
                                        if (Math.abs(updatedVolumeCount) == 0) {
                                            itOp.remove();
                                            openPos.removeFill(openPosition);

                                            if (!openPos.hasFills())
                                                itOlp.remove();
                                            // openingListingPositions.remove(openPos);
                                            //
                                            //

                                            //  openPos.removeFill(openPosition);
                                            //    PersistUtil.merge(openPosition);

                                            //  openingListingPositions.remove(openPos);
                                            //openPos.Merge();
                                        }
                                        //  openingListingPositions.remove(openPosition);
                                        itP.remove();
                                        p.setOpenVolumeCount(0);
                                        PersistUtil.merge(p);

                                        pos.removeFill(p);

                                        if (!pos.hasFills())
                                            itPos.remove();
                                        // listingPositions.remove(pos);
                                        // pos.Merge();
                                        //itPos.remove();
                                        // if (itP != null)
                                        //if (itPos.hasNext())
                                        //   

                                        // pos.Merge();

                                        //pos.removeFill(p)  itP.remove();
                                        // pos.removeFill(p);
                                        //           PersistUtil.merge(openPosition);

                                        // itPos.remove();
                                        //listingPositions.remove(pos);

                                        // listingPositions.remove(p);

                                    }
                                    DiscreteAmount volDiscrete = new DiscreteAmount(closingVolumeCount, p.getMarket().getListing().getVolumeBasis());

                                    realisedPnL = realisedPnL.plus(((entryPrice.minus(exitPrice)).times(volDiscrete, Remainder.ROUND_EVEN)).times(p.getMarket()
                                            .getContractSize(), Remainder.ROUND_EVEN));

                                    // need to confonvert to deiscreete amount

                                    //LongRealisedPnL = ((exitPrice.minus(entryPrice)).times(volDiscrete, Remainder.ROUND_EVEN)).times(position.getMarket()
                                    //	.getContractSize(), Remainder.ROUND_EVEN);

                                    //	ShortRealisedPnL = (position.getShortAvgPrice().minus(p.getLongAvgPrice())).times(position.getShortVolume().negate(),
                                    //	Remainder.ROUND_EVEN);
                                    //	LongRealisedPnL = (position.getLongAvgPrice().minus(p.getShortAvgPrice())).times(position.getLongVolume().negate(),
                                    //		Remainder.ROUND_EVEN);

                                }
                            }

                            Amount RealisedPnL = realisedPnL.toBasis(p.getMarket().getTradedCurrency().getBasis(), Remainder.ROUND_EVEN);
                            Amount PreviousPnL = (realisedProfits.get(p.getMarket().getTradedCurrency()) == null
                                    || realisedProfits.get(p.getMarket().getTradedCurrency()).get(p.getMarket().getExchange()) == null || realisedProfits
                                    .get(p.getMarket().getTradedCurrency()).get(p.getMarket().getExchange()).get(p.getMarket().getListing()) == null) ? DecimalAmount.ZERO
                                    : realisedProfits.get(p.getMarket().getTradedCurrency()).get(p.getMarket().getExchange()).get(p.getMarket().getListing());
                            if (!RealisedPnL.isZero()) {

                                Amount TotalRealisedPnL = RealisedPnL.plus(realisedProfits.get(p.getMarket().getTradedCurrency())
                                        .get(p.getMarket().getExchange()).get(p.getMarket().getListing()));

                                realisedProfits.get(p.getMarket().getTradedCurrency()).get(p.getMarket().getExchange())
                                        .put(p.getMarket().getListing(), TotalRealisedPnL);
                                Transaction trans = new Transaction(this, p.getMarket().getExchange(), p.getMarket().getTradedCurrency(),
                                        TransactionType.REALISED_PROFIT_LOSS, RealisedPnL, new DiscreteAmount(0, p.getMarket().getTradedCurrency().getBasis()));

                                context.route(trans);
                                PersistUtil.insert(trans);
                                //		manager.getPortfolioService().CreateTransaction(position.getExchange(), position.getMarket().getQuote(),
                                //			TransactionType.REALISED_PROFIT_LOSS, TotalRealisedPnL.minus(PreviousPnL), DecimalAmount.ZERO);

                            }

                            //							if (!totalQuantity.isZero()) {
                            //								//generate PnL
                            //								//Update postion Quanitty
                            //								//Recculate Avaerge Price
                            //								Amount avgPrice = ((p.getAvgPrice().times(p.getVolume(), Remainder.ROUND_EVEN)).plus(position.getLongVolume().times(
                            //										position.getAvgPrice(), Remainder.ROUND_EVEN))).dividedBy(p.getVolume().plus(position.getLongVolume()),
                            //										Remainder.ROUND_EVEN);
                            //								p.setAvgPrice(avgPrice);
                            //							}

                            //							if (!position.getLongVolume().isZero()) {
                            //								// i.e long position
                            //								Amount vol = (p.getLongAvgPrice().isZero()) ? position.getLongVolume() : p.getLongVolume().plus(position.getLongVolume());
                            //								if (!vol.isZero()) {
                            //									longExitPrice = ((p.getLongAvgPrice().times(p.getLongVolume(), Remainder.ROUND_EVEN)).plus(position.getLongVolume().times(
                            //											position.getLongAvgPrice(), Remainder.ROUND_EVEN))).dividedBy(vol, Remainder.ROUND_EVEN);
                            //									p.setLongAvgPrice(longExitPrice);
                            //								}
                            //							}

                            //							if (!position.getShortVolume().isZero()) {
                            //								// i.e short position
                            //								//this does not work when we net out the postion as we have a divid by zero error
                            //								Amount vol = (p.getShortAvgPrice().isZero()) ? position.getShortVolume() : p.getShortVolume().plus(position.getShortVolume());
                            //								if (vol.isZero()) {
                            //									shortExitPrice = ((p.getShortAvgPrice().times(p.getShortVolume(), Remainder.ROUND_EVEN)).plus(position.getShortVolume()
                            //											.times(position.getShortAvgPrice(), Remainder.ROUND_EVEN))).dividedBy(vol, Remainder.ROUND_EVEN);
                            //									p.setShortAvgPrice(shortExitPrice);
                            //								}
                            //							}
                            //p.setLongVolumeCount(p.getLongVolumeCount() + position.getLongVolumeCount());
                            //p.setShortVolumeCount(p.getShortVolumeCount() + position.getShortVolumeCount());

                            //	Long avgPriceCount = (long) avgPrice.divide(BigDecimal.valueOf(p.getMarket().getPriceBasis()), Remainder.ROUND_EVEN).asDouble();
                            //avgPrice = new DiscreteAmount(avgPriceCount, p.getMarket().getPriceBasis());
                            //DiscreteAmount avgDiscretePrice = new DiscreteAmount((long) avgPrice.times(p.getMarket().getPriceBasis(), Remainder.ROUND_EVEN)
                            //	.asDouble(), (long) (p.getMarket().getPriceBasis()));
                            // I need to net the amounts

                            // if the long and short volumes are zero we can remove the position
                            //if (p.getShortVolumeCount() * -1 == p.getLongVolumeCount()) {
                            //listingPositions.remove(p);
                            // publish realised PnL for the long and short posiotion
                            //TODO: we are merging postions based on the order they were creted (FIFO), might want to have a comparator to merge using LIFO, or some other algo

                            //}
                            //return true;

                            //}

                        }
                    }

                }
                //listingPositions.add(position);
                //// true;
                if (getPosition(fill.getMarket().getBase(), fill.getMarket()) == null) {
                    Position detPosition = new Position(fill);
                    detPosition.Persit();
                    publishPositionUpdate(detPosition, PositionType.FLAT, fill.getMarket());
                } else {
                    PositionType lastType = (openingTransactionType == TransactionType.BUY) ? PositionType.LONG : PositionType.SHORT;
                    publishPositionUpdate(getPosition(fill.getMarket().getBase(), fill.getMarket()), lastType, fill.getMarket());
                }
                return true;

            }//else {
             //listingPositions.add(position);
             //return true;
             //}

            //return true;

        }
        // }

    }

    public Portfolio(String name, PortfolioManager manager) {
        this.name = name;
        this.manager = manager;

    }

    private String name;

    public String getName() {
        return name;
    }

    @OneToMany
    public Collection<Stake> getStakes() {
        return stakes;
    }

    @ManyToOne
    public Asset getBaseAsset() {
        return baseAsset;
    }

    @Transient
    public PortfolioManager getManager() {
        return manager;
    }

    /**
     * Adds the given position to this Portfolio.  Must be authorized.
     * @param position
     * @param authorization
     */
    @Transient
    protected void modifyPosition(Fill fill, Authorization authorization) {
        assert authorization != null;
        assert fill != null;
        boolean modifiedExistingPosition = false;
        merge(fill);
        persistPositions();

        // if 

        //		for (Position curPosition : positions) {
        //			if (curPosition.merge(position)) {
        //				modifiedExistingPosition = true;
        //				break;
        //			}
        //		}
        //		if (!modifiedExistingPosition)
        //			positions.add(position);
    }

    @Override
    public String toString() {

        return getName();
    }

    // JPA
    public Portfolio() {
        this.positions = new ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>>>();
        this.realisedProfits = new ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, Amount>>>();
        this.balances = new ConcurrentLinkedQueue<>();
        this.transactions = new ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>>>();

    }

    protected void setPositions(
            ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>>> positions) {
        this.positions = positions;
    }

    protected void setBalances(Collection<Balance> balances) {
        this.balances = balances;
    }

    public void setBaseAsset(Asset baseAsset) {
        this.baseAsset = baseAsset;
    }

    protected void setTransactions(
            ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>>> transactions) {
        this.transactions = transactions;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected void setStakes(Collection<Stake> stakes) {
        this.stakes = stakes;
    }

    public static Portfolio findOrCreate(String portfolioName) {
        final String queryStr = "select p from Portfolio p where name=?1";
        try {
            return PersistUtil.queryOne(Portfolio.class, queryStr, portfolioName);
        } catch (NoResultException e) {
            //  context.getInjector().getInstance(Portfolio.class);
            // PersistUtil.insert(portfolio);
            return null;
        }
    }

    protected void setManager(PortfolioManager manager) {
        this.manager = manager;
    }

    public static final class Factory {
        /**
         * Constructs a new instance of {@link Tick}.
         * @return new TickImpl()
         */
        public static Portfolio newInstance() {
            return new Portfolio();
        }

        public static Portfolio newInstance(String name, PortfolioManager manager) {
            final Portfolio entity = new Portfolio(name, manager);
            return entity;
        }

        // HibernateEntity.vsl merge-point
    }

    private PortfolioManager manager;
    @Inject
    private Logger log;
    @Inject
    protected Context context;
    @Inject
    protected PortfolioService portfolioService;
    private Asset baseAsset;
    private ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Position>>>>> positions;
    private ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<Listing, Amount>>> realisedProfits;
    private Collection<Balance> balances = Collections.emptyList();
    private ConcurrentHashMap<Asset, ConcurrentHashMap<Exchange, ConcurrentHashMap<TransactionType, ConcurrentLinkedQueue<Transaction>>>> transactions;
    private Collection<Stake> stakes = Collections.emptyList();

    private final Collection<Balance> trades = Collections.emptyList();

}


java程序员刷题软件-Portfolio:著名计划和项目的集合 java程序员刷题软件文件夹 这个存储库包含我参与过的著名程序和项目的集合。 README 为每个程序提供了简要说明,以及指向外部存储库中程序的链接。 除非另有说明,所有工作都是我自己的。 面部识别作为生物特征验证 —— 与来自美国、哥伦比亚、中国和泰国的大学合作开展分布式软件开发项目,以创建使用面部识别进行远程身份验证的操作概念。 我在一个美国-哥伦比亚混合团队工作,创建了一个 Android 应用程序,用于注册用户、拍照并与另一个团队的数据库服务器连接。 与合作伙伴一起创建了一份提案、计划和报告,以测试面部识别作为生物特征认证措施的可行性和安全性。 我开发了面部识别认证系统 (FRAS) 软件,该软件与 Microsoft 的 FaceAPI 系统接口以在我们的项目中使用。 利用 OpenCV 对一组图像执行不同的图像处理技术,并利用 OpenMP 并行化处理技术和管道。 我开发了该应用程序并协助创建了报告和演示文稿,这些报告和演示文稿展示了通过并行处理获得的性能提升。 安卓应用 我开发的轻量级笔记应用程序,灵感来自 Google Keep。 从美国境内的监测站收集预测和历史潮汐信 立即下载

相关推荐

IBM项目管理工具portfolio介绍

IBM项目管理工具portfolio的介绍,

Spring(一):基本概念及整体框架

一.初识Spring Spring可以做很多事情,但这些功能都依赖于两个核心特性:依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Proramming,AOP),本章将从Spring策略出发,讲一下Spring框架和DI,AOP 的基本样例。 Spring最恨本的使命是简化Java开发,为了降低Java开发的复杂性,Spring采取了以下4...

zyq_2014的博客 531

有关SPSS中Fisher精确检验无法进行的解决方法(由于无法打开临时文件,因此无法进行计算)

最近在帮一个四年生完成她的毕业论文,在用SPSS进行R×C表检验的时候,发现Fisher精确检验的结果无法显示,提示为“由于无法打开临时文件,因此无法进行计算”,大概像下图一样。 (这图是从网上找的) 然...

chuyang37的博客 3万+

程序员的量化交易之路(2)----Esper文档学习之技术概览(1)

转载请注明出处:http://blog.youkuaiyun.com/minimicall/ 在接下来的20个工作日中,我将坚持翻译或者略翻译Esper的官方文档。 为什么需要学习Esper,因为我们需要理解复合事件处理 Complex Event Processing (CEP)。在量化交易系统中,CEP是必不可少的。它负责处理海量的实时事件。 关于CEP更多...

weixin_33883178的博客 440

面试复习题--RN面试

考察点:热更新方案的深度理解,选型能力,实战落地经验。答题思路主流热更新方案对比。

hqiangtai的博客 728

HID报告描述符实战解析:从Usage到Item的完整设计流程

本文深入解析了HID报告描述符的设计流程,从核心概念Usage(用途定义)入手,详细阐述了如何通过Item(条目)的三种角色——全局、局部与主干,构建出能被系统正确识别的设备“说明书”。文章以标准USB鼠标和键盘为例进行实战拆解,并介绍了使用Report ID与自定义设备等进阶设计方法,帮助开发者掌握这一实现USB设备即插即用的关键技术。

weixin_29230865的博客 282

程序员的量化交易之路(1)----规划开篇

其实,一直对量化交易有一定的理解和情节。早在中大读研究生的时候实验室师兄,已经去了中国平安核心投资团队,做高频交易研究的国源师兄的影响,就开始对金融世界产生了浓厚的兴趣。看了丁磊编著的《量化投资--策略与技术》和艾琳.奥尔德里奇的《高频交易》,反复的看,但是都入不了味,现在回过头来想,一个连股都不炒的人怎么可能入味呢。对一些金融的基本概念都不懂。 2...

weixin_34357436的博客 766

中小型微服务系统 硬件设备如何部署,QPS大概多少

作为一名合格的开发工程师,不仅仅要在前期开发阶段对业务和技术有深入了解,知道选用哪种合适的技术,业务如何拆分,还要思考后期线上环境,资源,延迟,性能等如何优化维护以及分布式系统一些线上生产的一些问题。 本篇主要针对之前了解的情况对硬件设备资源做一个简单的介绍: 首先分布式系统线上实践问题,我们应该对公司的流量,各个服务,网管,注册中心应该如何部署,部署多少台机器才合适,每台机器的配置如何,每天整体流量有多少,高峰期的请求量有多少,你的整体系统是否扛得住(注:很多公司现在直接使用K8S docker 实现

wangxuelei036的博客 1万+

中年码农成功转行量化交易,历程分享

1节课3小时课程,我看回放需要8个小时才能跟上,稍不留神就跟不上,还得反复的看;最初的想法是读PhD,圆了年轻那会儿的梦想,也能为人生下半场发展做好铺垫,个人兴趣是人工智能和金融相结合的方向,毕竟人工智能是IT行业的热点和趋势,有无穷无尽的潜力和发展方向,按整个行业发展来看,正处于大的变革期。我,坐标北京,中年大叔,人生上半场码农,从最早的VC6.0、MFC、逆向工程、网络编程,到中期的Java、React,到近期的大数据、AI一路走下来,在一次又一次的技术革新浪潮中,疲于奔命,始终缺少方向感、归属感。

qq_46094651的博客 560

SOI技术实战:从晶圆结构到芯片性能提升的完整解析

本文深入解析SOI(Silicon on Insulator)技术如何通过独特的三明治晶圆结构提升芯片性能,涵盖从220nm SOI层设计到7nm节点的工艺挑战。详细探讨了埋氧层的绝缘优势、性能提升的物理机制,以及AMD处理器和5G射频中的实战应用,为半导体行业提供关键技术洞见。

wdx0123456的博客 960

基于FPGA的多通道音频信号采样系统设计

FPGA是随着数字集成电路的发展而逐步演变而来的。从早期的电子管、晶体管、小规模集成电路,到超大规模集成电路(VLSIC),数字集成电路的集成度和性能不断提升。FPGA的出现为系统设计师提供了灵活的设计平台,使其能够在不依赖半导体厂商的情况下快速设计专用集成电路(ASIC)。FPGA具有设计周期短、成本低、开发工具先进等优点,广泛应用于原型设计和产品生产中。VHDL是一种用于描述数字系统的硬件描述语言,其语言形式类似于计算机高级语言,但包含了许多硬件特征语句。

qq_62634009的博客 709

数据库异常 Cause: java.sql.SQLDataException: Cannot determine value type from string

使用mybatisplus查询表中指定字段,导致异常。

success1218的博客 1186

【短距离通信】【WiFi】精讲WiFi 6E协议!图解超赞超详细!!!

802.11ax(HE,HighEfficiency) (Wi-Fi 6E):6G频段共有1200MHz的频谱给到WiFi 6E使用,可用于从5.925GHz到7.125GHz。WiFi将可以访问59个20MHz信道,29个40MHz信道14个80MHz信道和7个160MHz信道。这不仅代表可以有很多频道,还可以代表可以解锁更高的数据速率。因为 802.11ax 标准(Wi-Fi 6)也在 2.4GHz 和 5GHz 频段运行,所以 6GHz 频段的 Wi-Fi 将被命名为 Wi-Fi 6E。

风云说通信 2347

SnapdragonCamera源码分析(三)createSessions & startPreview

接上一篇SnapdragonCamera源码分析(二)OpenCamera流程继续分析,当Camera Device被成功open后,开始创建Session会话。 createSessions(): private void createSessions() { if(PersistUtil.isTraceEnable()) Trace.beginSection("createSessions"); if (mPaused || !mCamer

Otaku_627的博客 1677

2026华为OD面试手撕代码真题目录

一般面试的时候每一轮技术面都会出一到两个手撕代码题,这些题的特点就是,非常短小,易于理解。不可能会再出阅读理解一样的机试题的。但是这些题目也非常注意基本功,很注意细节的处理,一般都是easy+medium题目。但是大家一定要注意,因为大部分面试官上面一开始就会让你做题,直接看你所有的做题过程(防止有人水平一般,机试就网上找的答案的蒙混过关),手撕代码题会给你后面的面试定一个基调。

MISAYAONE的博客 9万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

程序员的量化交易之路(7)--金融概念Positon

转载需说明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents Position 仓: long postion:多头 open long position :开多头仓 close long poition : 平(闭)多头仓 short positon:空头 open short positio...

weixin_34274029的博客 296

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

程序员的量化交易之路(10)--金融概念Stop-limit Order

转载需注明:http://blog.youkuaiyun.com/minimicall,http://cloudtrade.top Market Order: 市价订单。就是如果你下单后,基本上会马上执行的,该订单价格就是下单后的市场价格。 Limit order:限价订单。这个也容易理解,就是限定一个价格买入和卖出。比如某股票市价可能是15,你希望大跌后买入,...

weixin_34054931的博客 637

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

程序员的量化交易之路(9)--金融系统概念basis

转载需注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents , http://cloudtrade.top basis:基差 常见的几个概念有: Adjusted basis, the net cost of an asset after adjusting for various tax-related i

MiniMicall的专栏 3479

程序员的量化交易之路(36)--Lean之数据读取SubscriptionDataReader4

转载需注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents,http://cloudtrade.top 数据读取需要定义一个读者。直接见下面代码: namespace QuantConnect.Lean.Engine.DataFeeds { /**********************...

weixin_34277853的博客 420

程序员的量化交易之路(33)--QuantConnect之案例1

转载需注明:http://blog.youkuaiyun.com/minimicall,http://cloudtrade.top/ 分析Cointrader有一定层度了,发现它毕竟不是一个产品,没有得到验证。在架构、编码等方面都非常的不规范。 想编写一个云交易平台,任道而重远。我们需要参照一些成熟的架构。 Quantopian的zipline不行,因为我就是看...

weixin_34364135的博客 4493

程序员如何学习量化交易,一文总结

最近有位金融行业的朋友想把一个盈利能力很强的策略做成量化程序遇到问题,问题是这样的 线程A在while(true)的循环里做条件判断,循环耗时1分钟。循环结束判断条件满足的时候调用交易接口下单建仓。想实现条件成立马上建仓,而不需要等待1分钟的循环。想通过多进程或者多线程方式,但两个线程不知道如何交互。 对有经验的开发来说这样的逻辑很简单,只要通过线程通信的方式就可以实现。A线程判断到满足条件就发个消息给B线程,B线程while(true)等待消息就行。技术本身不复杂,只是没接触过编程的不知道还可以这么干

瞎猫实验室 5667

程序员的量化交易之路(39)--Lean之BacktestingRealTimeHandler回测实时时间事件处理7...

</pre>转载需注明出处:<a target=_blank href="http://blog.youkuaiyun.com/minimicall?viewmode=contents">http://blog.youkuaiyun.com/minimicall?viewmode=contents</a>,<a target=_bl...

weixin_33961829的博客 344

基于IB(Interactive Brokers)盈透证券的股票及期货行情获取讲解

盈透证券,作为老牌帝国主义券商,能够提供强到变态的交易平台TWS,多到变态的全球股票、期货等产品覆盖,以及低到变态的交易费用。如果做全球股票或期货交易,能够对接盈透证券相关接口还是不错的选择,但是这里忍不住要吐槽一下盈透的接口命名,一点都不优雅,感觉有点渣, 有种乱糟糟的感觉。

grafx的专栏 2万+
上一篇: 程序员的量化交易之路(31)--cointrader之Balance现金(18)
下一篇: 程序员的量化交易之路(33)--QuantConnect之案例1
minimicall
博客等级 码龄18年 407粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值