net.sf.smbt.ui.btc.views.TradesView.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.smbt.ui.btc.views.TradesView.java

Source

/***********************************************************************************
 * Ubiquisense - A smart ambient utilities framework 
 * 
 * Copyright (c) 2013, Lucas Bigeardel
 * 
 * The library is released under:
 * 
 * A) LGPL
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 * 
 * B) EPL
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Lucas Bigeardel <lucas.bigeardel@gmail.com> - Initial API and implementation
 ***********************************************************************************/

package net.sf.smbt.ui.btc.views;

import java.text.SimpleDateFormat;
import java.util.Date;

import net.sf.smbt.btc.BitcoinMarket;
import net.sf.smbt.btc.BtcCurrency;
import net.sf.smbt.btc.BtcPackage;
import net.sf.smbt.btc.cmd.BTCUtils;
import net.sf.smbt.btc.mtgox.DepthStatus;
import net.sf.smbt.btc.mtgox.DepthValue;
import net.sf.smbt.btc.mtgox.FetchKind;
import net.sf.smbt.btc.mtgox.Fundamentals;
import net.sf.smbt.btc.mtgox.MTGoxController;
import net.sf.smbt.btc.mtgox.MTGoxUtils;
import net.sf.smbt.btc.mtgox.MtgoxPackage;
import net.sf.smbt.fmodex.core.AudioUtils;
import net.sf.smbt.fmodex.core.SystemSound;
import net.sf.smbt.quantic.warp.QuanticMojo;
import net.sf.smbt.ui.btc.Activator;
import net.sf.smbt.ui.btc.prefs.MtGoxWalletPreferenceConstants;
import net.sf.smbt.ui.hmi.GUIToolkit;
import net.sf.smbt.ui.hmi.UbiJob;
import net.sf.smbt.ui.widgets.vu.UbiOscilloscope;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.mylyn.commons.ui.dialogs.AbstractNotificationPopup;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.part.ViewPart;

public class TradesView extends ViewPart {
    public SimpleDateFormat HH_MM_SS_DATE_FORMAT;

    private Image alarmIcon = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/alarm.png")
            .createImage();
    private Color lightBlue = new Color(Display.getDefault(), new RGB(0, 191, 255));
    private Font medFont = new Font(Display.getDefault(), "tahoma", 12, SWT.NORMAL);
    private Label currentLabel;
    private TreeViewer bidsDepthTreeViewer, asksDepthTreeViewer, lastSalesTreeViewer;
    private MTGoxController mtgoxController;
    private UbiOscilloscope oscillo;
    private ComboViewer currencyComboViewer;

    public TradesView() {
        HH_MM_SS_DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
        initMarket();
    }

    class RefreshSalesJob extends UbiJob {
        private DepthValue latest;

        public RefreshSalesJob() {
            super("refresh trades GUI");
        }

        public void setLatest(DepthValue latest) {
            this.latest = latest;
        }

        public DepthValue getLatest() {
            return latest;
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            if (latest.getCurrency().equals(mtgoxController.getMTGox().getCurrency())) {
                if (latest.getKind().equals(FetchKind.ASK)) {
                    AudioUtils.INSTANCE.playSystemSound(SystemSound.SMALL_BELL_RING_2);
                } else {
                    AudioUtils.INSTANCE.playSystemSound(SystemSound.SMALL_BELL_RING_1);
                }
                notifyTradeStatus2(latest, getDisplay());
                oscillo.redraw();
            }
            lastSalesTreeViewer.refresh();
            return Status.OK_STATUS;
        }
    };

    class RefreshDepthJob extends UbiJob {
        BitcoinMarket market;

        public RefreshDepthJob(BitcoinMarket market) {
            super("refresh depth GUI");
            this.market = market;
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            try {
                currentLabel.setText(market.getBroker() + "(" + market.getCurrency() + "/" + "BTC) : Buy ("
                        + market.getBuy() + " : " + market.getSell() + ") Sell | Low (" + market.getLow() + " : "
                        + market.getHigh() + ") High | Last :" + market.getLast());
                float[] values = new float[mtgoxController.getMTGox().getTrend().size()];
                int i = 0;
                for (Fundamentals f : mtgoxController.getMTGox().getTrend()) {
                    values[i] = f.getLast();
                    i++;
                }
                oscillo.setValues(values);
            } catch (Exception e) {
                e.printStackTrace();
            }
            asksDepthTreeViewer.refresh();
            bidsDepthTreeViewer.refresh();
            return Status.OK_STATUS;
        }
    };

    public void initMarket() {
        String apiKey = Activator.getDefault().getPreferenceStore()
                .getString(MtGoxWalletPreferenceConstants.P_MTGOX_API_KEY);
        String secretKey = Activator.getDefault().getPreferenceStore()
                .getString(MtGoxWalletPreferenceConstants.P_MTGOX_SECRET_KEY);

        mtgoxController = MTGoxUtils.INSTANCE.getMTGoxControl(apiKey, secretKey);

        final RefreshSalesJob refreshSalesJob = new RefreshSalesJob();
        final RefreshDepthJob refreshDepthJob = new RefreshDepthJob(mtgoxController.getMTGox().getMarket());

        mtgoxController.getMTGox().getMarket().eAdapters().add(new AdapterImpl() {
            @Override
            public void notifyChanged(Notification msg) {
                if (msg.getFeature().equals(BtcPackage.Literals.BITCOIN_MARKET__BUY)) {
                    refreshDepthJob.cancel();
                    refreshDepthJob.schedule();
                }
            }
        });
        mtgoxController.getMTGox().eAdapters().add(new AdapterImpl() {
            @Override
            public void notifyChanged(Notification msg) {
                if (msg.getFeature().equals(MtgoxPackage.Literals.MT_GOX__ASKS)
                        || msg.getFeature().equals(MtgoxPackage.Literals.MT_GOX__BIDS)) {
                    refreshDepthJob.cancel();
                    refreshDepthJob.schedule();
                } else if (msg.getFeature().equals(MtgoxPackage.Literals.MT_GOX__SALES)) {
                    DepthValue v = (DepthValue) msg.getNewValue();
                    if (mtgoxController.getMtgoxDataManager().getMtGox().getMarket().getCurrency()
                            .equals(v.getCurrency())) {
                        refreshSalesJob.cancel();
                        refreshSalesJob.setLatest(v);
                        refreshSalesJob.schedule();
                    }
                }
            }
        });
    }

    private void notifyTradeStatus2(final DepthValue v, Display display) {
        final AbstractNotificationPopup notification = new AbstractNotificationPopup(display) {
            @Override
            protected void createContentArea(Composite composite) {
                composite.setLayout(new GridLayout(1, true));
                composite.setBackground(GUIToolkit.BG);
                Label label = new Label(composite, SWT.NONE);
                label.setBackground(GUIToolkit.BG);
                label.setForeground(
                        v.getKind().equals(FetchKind.ASK) ? GUIToolkit.lightRed : ColorConstants.darkGreen);
                if (v != null && v.getKind() != null
                        && mtgoxController.getMTGox().getMarket().getCurrency() != null) {
                    label.setText((v.getKind().equals(FetchKind.ASK) ? "Sold " : "Bought ") + v.getAmount()
                            + " for " + v.getPrice() + BTCUtils.INSTANCE.getCurrencySymbol(v.getCurrency()) + " "
                            + "\nat " + new Date(v.getStamp() * 1000));
                }
            }

            @Override
            protected String getPopupShellTitle() {
                return "MtGOX Trade done";
            }

            @Override
            protected Image getPopupShellImage(int maximumHeight) {
                return alarmIcon;
            }
        };
        if (Display.getDefault() == Display.getCurrent()) {
            notification.open();
        } else {
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    notification.open();
                }
            });
        }
    }

    @Override
    public void dispose() {
        if (mtgoxController != null) {
            if (mtgoxController.getMtgoxPipe() != null) {
                QuanticMojo.INSTANCE.closePipe(mtgoxController.getMtgoxPipe(), true);
            }
        }
        super.dispose();
    }

    @Override
    public void createPartControl(Composite parent) {
        Composite container = GUIToolkit.INSTANCE.createComposite(parent);
        container.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
        container.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());

        currencyComboViewer = new ComboViewer(container);
        currencyComboViewer.setContentProvider(new ArrayContentProvider());
        currencyComboViewer.setLabelProvider(new LabelProvider());
        currencyComboViewer.setInput(BtcCurrency.VALUES);
        currencyComboViewer.setSelection(new StructuredSelection(BtcCurrency.EUR));
        currencyComboViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection s = event.getSelection();
                if (s instanceof StructuredSelection) {
                    BtcCurrency currency = (BtcCurrency) ((StructuredSelection) s).getFirstElement();
                    mtgoxController.getMTGox().getMarket().setCurrency(currency);
                    mtgoxController.getMTGox().getTrend().clear();
                }
            }
        });
        currencyComboViewer.getCombo().setEnabled(false);

        currentLabel = new Label(container, SWT.NONE);
        currentLabel.setLayoutData(
                GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).grab(true, false).create());
        currentLabel.setFont(medFont);
        currentLabel.setForeground(lightBlue);
        currentLabel.setBackground(GUIToolkit.BG);
        currentLabel.setText(
                "                                                                                                                                                        ");

        Composite oscilloBag = GUIToolkit.INSTANCE.createComposite(container);
        oscilloBag.setLayout(GridLayoutFactory.fillDefaults().create());
        oscilloBag.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, false).create());

        oscillo = new UbiOscilloscope(oscilloBag, SWT.HORIZONTAL);
        oscillo.setBackground(GUIToolkit.BG);
        oscillo.setForeground(ColorConstants.yellow);
        oscillo.setLayout(GridLayoutFactory.fillDefaults().create());
        oscillo.setLayoutData(GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 33).grab(true, false).create());

        SashForm sash = new SashForm(container, SWT.BORDER | SWT.HORIZONTAL);
        sash.setLayout(GridLayoutFactory.fillDefaults().create());
        sash.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true).create());
        sash.setBackground(GUIToolkit.FG);

        SashForm sashDepths = new SashForm(sash, SWT.BORDER | SWT.HORIZONTAL);
        sashDepths.setLayout(GridLayoutFactory.fillDefaults().create());
        sashDepths.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        sashDepths.setBackground(GUIToolkit.FG);

        //
        // BIDS
        //

        bidsDepthTreeViewer = new TreeViewer(sashDepths);

        bidsDepthTreeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        bidsDepthTreeViewer.getControl().setFont(medFont);
        bidsDepthTreeViewer.getTree().setLinesVisible(false);
        bidsDepthTreeViewer.getControl().setBackground(ColorConstants.darkGray);
        bidsDepthTreeViewer.getControl().setForeground(ColorConstants.lightGray);

        bidsDepthTreeViewer.setLabelProvider(new AdapterFactoryLabelProvider(new MTGoxCompseableAdapterFactory()) {
            @Override
            public String getText(Object object) {
                return super.getText(object);
            }
        });
        bidsDepthTreeViewer.setContentProvider(new BtcTransactionsContentProvider(FetchKind.BID));
        bidsDepthTreeViewer.getTree().setHeaderVisible(true);
        bidsDepthTreeViewer.getTree().setLinesVisible(true);

        bidsDepthTreeViewer.setInput(mtgoxController.getMTGox());

        //
        // ASKS
        //

        asksDepthTreeViewer = new TreeViewer(sashDepths);

        asksDepthTreeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        asksDepthTreeViewer.getControl().setFont(medFont);
        asksDepthTreeViewer.getControl().setBackground(ColorConstants.darkGray);
        asksDepthTreeViewer.getControl().setForeground(ColorConstants.lightGray);
        asksDepthTreeViewer.getTree().setLinesVisible(false);

        asksDepthTreeViewer.setLabelProvider(new AdapterFactoryLabelProvider(new MTGoxCompseableAdapterFactory()) {
            @Override
            public String getText(Object object) {
                return super.getText(object);
            }
        });
        asksDepthTreeViewer.setContentProvider(new BtcTransactionsContentProvider(FetchKind.ASK));
        asksDepthTreeViewer.getTree().setHeaderVisible(true);
        asksDepthTreeViewer.getTree().setLinesVisible(true);

        asksDepthTreeViewer.setInput(mtgoxController.getMTGox());

        lastSalesTreeViewer = new TreeViewer(sash);

        lastSalesTreeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        lastSalesTreeViewer.getControl().setFont(medFont);
        lastSalesTreeViewer.getControl().setBackground(ColorConstants.darkGray);
        lastSalesTreeViewer.getControl().setForeground(ColorConstants.lightBlue);
        lastSalesTreeViewer.getTree().setLinesVisible(false);

        lastSalesTreeViewer.setLabelProvider(new AdapterFactoryLabelProvider(new MTGoxCompseableAdapterFactory()) {
            @Override
            public String getText(Object object) {
                return super.getText(object);
            }
        });
        lastSalesTreeViewer.setContentProvider(new LastSalesHistoryContentProvider());
        lastSalesTreeViewer.getTree().setHeaderVisible(true);
        lastSalesTreeViewer.getTree().setLinesVisible(true);

        lastSalesTreeViewer.setInput(mtgoxController.getMTGox());

        sash.setWeights(new int[] { 5, 3 });

        sashDepths.setWeights(new int[] { 3, 3 });

        createBidTradeTableViewerColumn("Sum", 75, bidsDepthTreeViewer);
        createBidTradeTableViewerColumn("Size", 75, bidsDepthTreeViewer);
        createBidTradeTableViewerColumn("BUY @", 75, bidsDepthTreeViewer);

        createAskTradeTableViewerColumn("SELL @", 75, asksDepthTreeViewer);
        createAskTradeTableViewerColumn("Size", 75, asksDepthTreeViewer);
        createAskTradeTableViewerColumn("Sum", 75, asksDepthTreeViewer);

        //

        createSalesTableViewerColumn("Volume", 65, lastSalesTreeViewer);
        createSalesTableViewerColumn("Price", 65, lastSalesTreeViewer);
        createSalesTableViewerColumn("Date", 65, lastSalesTreeViewer);
    }

    private TreeViewerColumn createBidTradeTableViewerColumn(String title, int bound, TreeViewer tv) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(tv, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        viewerColumn.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                if (cell.getElement() instanceof DepthValue) {
                    DepthValue v = (DepthValue) cell.getElement();
                    String cellText = "???";
                    cell.setForeground(GUIToolkit.FG);
                    cell.setBackground(GUIToolkit.BG);
                    long now = System.currentTimeMillis();
                    switch (cell.getColumnIndex()) {
                    case 0: // Bid Sum
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getSum();
                        }
                        break;
                    case 1: // Size
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getAmount();
                        }
                        break;
                    case 2: // Bid
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getPrice();
                        }
                        break;
                    }
                    cell.setText(cellText);
                    if (v instanceof DepthValue && (cell.getColumnIndex() == 0 || cell.getColumnIndex() == 1
                            || cell.getColumnIndex() == 2)) {
                        if (v.getLastLocalStatus() + 12000l > now) {
                            if (v.getStatus().equals(DepthStatus.ADD)) {
                                cell.setForeground(GUIToolkit.lightGreen);
                            } else if (v.getStatus().equals(DepthStatus.REM)) {
                                cell.setForeground(GUIToolkit.lightRed);
                            } else if (v.getStatus().equals(DepthStatus.UPDATE)) {
                                cell.setForeground(GUIToolkit.orange);
                            }
                        }
                    }
                }
            }
        });
        return viewerColumn;
    }

    private TreeViewerColumn createAskTradeTableViewerColumn(String title, int bound, TreeViewer tv) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(tv, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        viewerColumn.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                if (cell.getElement() instanceof DepthValue) {
                    DepthValue v = (DepthValue) cell.getElement();
                    String cellText = "???";
                    cell.setForeground(GUIToolkit.FG);
                    cell.setBackground(GUIToolkit.BG);
                    long now = System.currentTimeMillis();
                    switch (cell.getColumnIndex()) {
                    case 2: // Bid Sum
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getSum();
                        }
                        break;
                    case 1: // Size
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getAmount();
                        }
                        break;
                    case 0: // Bid
                        if (v instanceof DepthValue) {
                            cellText = "" + v.getPrice();
                        }
                        break;
                    }
                    cell.setText(cellText);
                    if (v instanceof DepthValue && (cell.getColumnIndex() == 0 || cell.getColumnIndex() == 1
                            || cell.getColumnIndex() == 2)) {
                        if (v.getLastLocalStatus() + 12000l > now) {
                            if (v.getStatus().equals(DepthStatus.ADD)) {
                                cell.setForeground(GUIToolkit.lightGreen);
                            } else if (v.getStatus().equals(DepthStatus.REM)) {
                                cell.setForeground(GUIToolkit.lightRed);
                            } else if (v.getStatus().equals(DepthStatus.UPDATE)) {
                                cell.setForeground(GUIToolkit.orange);
                            }
                        }
                    }
                }
            }
        });
        return viewerColumn;
    }

    private TreeViewerColumn createSalesTableViewerColumn(String title, int bound, TreeViewer tv) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(tv, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        viewerColumn.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            protected void paint(Event event, Object element) {
                super.paint(event, element);
            }

            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                if (cell.getElement() instanceof DepthValue) {
                    DepthValue v = (DepthValue) cell.getElement();
                    String cellText = "???";
                    switch (cell.getColumnIndex()) {
                    case 0: // Amount
                        cellText = "" + v.getAmount();
                        cell.setForeground(GUIToolkit.FG);
                        cell.setBackground(GUIToolkit.BG);
                        break;
                    case 1: // Price
                        String symbol = BTCUtils.INSTANCE.getCurrencySymbol(v.getCurrency());
                        cellText = "" + v.getPrice() + " " + symbol;
                        cell.setForeground(
                                v.getKind().equals(FetchKind.ASK) ? GUIToolkit.lightRed : GUIToolkit.lightGreen);
                        cell.setBackground(GUIToolkit.dark_gray);
                        break;
                    case 2: // Date
                        cell.setForeground(GUIToolkit.FG);
                        cell.setBackground(GUIToolkit.BG);
                        cellText = "" + HH_MM_SS_DATE_FORMAT.format(new Date(v.getStamp()));
                        break;
                    }
                    cell.setText(cellText);
                }
            }
        });
        return viewerColumn;
    }

    @Override
    public void setFocus() {
    }
}