盈透数据获取实时K线与坑点

        官方API文档地址

TWS API v9.72+: Trader Workstation APIhttps://interactivebrokers.github.io/tws-api/一.如何获取ETH/EUR/USD/BTC等外汇或者数字货币实时数据走势

1.第一种方式我们可以通过

eg:m_s.reqRealTimeBars(1,contract,5,"MIDPOINT",true,Collections.emptyList());

我们可以通过5秒k线数据图请求5秒内快照数据进行拼接

注意该方法是在 realtimeBar中进行回调我们需要在此接口中重写相关方法处理业务逻辑

简单的贴一份代码:

建立TWS CLIENT连接:

private EJavaSignal m_signal = new EJavaSignal();
private EClientSocket m_s = new EClientSocket(this, m_signal);
m_s.eConnect("localhost", 7496, 0);
  final EReader reader = new EReader(m_s, m_signal);
  reader.start();
   new Thread(() -> {
          while (m_s.isConnected()) {
              m_signal.waitForSignal();
              try {
                  SwingUtilities.invokeAndWait(() -> {
                   try {
                      reader.processMsgs();
                   } catch (Exception e) {
                      error(e);
                   }
                  });
              } catch (Exception e) {
                  error(e);
              }
          }
      }).start();
if (NextOrderId < 0) {
   sleep(1000);
}

以EUR为例:

Contract contract = new Contract();

contract.symbol("EUR");

contract.secType("CASH");

contract.exchange("IDEALPRO");

contract.currency("USD");

m_s.reqMarketDataType(1);

m_s.reqRealTimeBars(1,contract,5,"MIDPOINT",true,Collections.emptyList());

处理回调方法:

@Override public void realtimeBar(int reqId, long time, double open, double high, double low, double close, Decimal volume, Decimal wap, int count) throws UnirestException {
   //下面代码实在回调中处理自己的相关业务
我们是通过http请求我们自己的接口发送相关数据 在通过webscoket进行数据的推送
Unirest.post(twsnotifyUrl)
      .header("Content-Type", "application/json")
      .header("charset","utf-8")
      .body(jsonObject.toJSONString()).asString();
}

2.第二种方式我们可以通过

m_s.reqMktData(9,contract9,"",false,false, Collections.emptyList());

每秒快照的方式进行数据的请求只不过该方法我们回调的接口是不同的这点需要注意下

tickPrice我们可以通过这个回调接口得到k线所需要的相关价格进行k线数据的构造

话不多说直接贴代码 建立连接的过程是相同的

@Override public void tickPrice(int tickerId, int field, double price, TickAttrib attribs) throws UnirestException {
//处理相关业务
}

二.盈透数据的坑

因为我们是通过TWS客户端获取的实时数据推送 所以这一点也是比较坑的 我们需要VPS 取部署windows服务器 安装TWS客户端进行数据的推送 但是TWS客户端由于他的维护缺点每天都会定时的进行关闭维护 所以我们要向获取实时走势 就需要定时的维护TWS客户端 但是作为一个程序员  我们也是为了各种苦逼的事情想到的解决办法就是 进程守护 

直接上代码 让TWS每天定时守护进程 让他关机自己启动 

@echo off
 
set _task=tws.exe
set _svr=c:\windows\tws.exe
set _des=start.bat
set _interval=50
 
:checkstart
for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_task%" ') do (
 if %%n==%_task% (goto checkag) else goto startsvr
)
 
 
 
:startsvr
echo %time% 
echo ********program start begin********
echo program reboost at %time% ,please check log. >> restart_service.txt
start %_svr%
::echo exit >> %_des%
::start %_des%
::set/p=.<nul
::for /L %%i in (1 1 10) do set /p a=.<nul&ping.exe /n 2 127.0.0.1>nul
::echo .
::echo Wscript.Sleep WScript.Arguments(0) >%tmp%\delay.vbs 
::cscript //b //nologo %tmp%\delay.vbs 10000 
::del %_des% /Q
echo ********program start finished ********
goto checkstart
 
 
:checkag
echo %time% program %_task% run normally, next check will be lauched in %_interval% milliseconds ... 
echo Wscript.Sleep WScript.Arguments(0) >%tmp%\delay.vbs 
cscript //b //nologo %tmp%\delay.vbs %_interval% 
goto checkstart

当然了除了脚本 也给大家推荐个软件 Always Open 如果有需要自行下载

三.webscoket数据推送

public class AliyunClient extends WebSocketClient {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    private final AliyunExchangeService aliyunExchangeService;

    private AliyunMonitor aliyunMonitor;


    public AliyunClient(URI serverUri, AliyunExchangeService aliyunExchangeService) {
        super(serverUri,new Draft_6455());
        this.aliyunExchangeService = aliyunExchangeService;
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        logger.info("AliyunClient onOpen {} {}", handshakedata.getHttpStatusMessage(), handshakedata.getHttpStatus());

        aliyunMonitor = new AliyunMonitor();
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
        executorService.scheduleAtFixedRate(aliyunMonitor, 0, 10, TimeUnit.SECONDS);
        aliyunExchangeService.init();
    }

    @Override
    public void onMessage(String message) {
        logger.info("AliyunClient message: {} ", message);

        if (message.contains("ping")){
            aliyunMonitor = new AliyunMonitor();
            return;
        }
        if (message.contains("rm")) {
            aliyunExchangeService.handleData(message);
        }
    }

    @Override
    public void onMessage(ByteBuffer byteBuffer) {

    }


    @Override
    public void onClose(int code, String reason, boolean remote) {
        logger.error("AliyunClient onClose code: {} message: {}", code, reason);
        aliyunExchangeService.stop();
    }

    @Override
    public void onError(Exception ex) {
        logger.error("AliyunClient error");
    }


    class AliyunMonitor implements Runnable {

        @Override
        public void run() {
            sendPing();
        }

        private void sendPing() {
            send("/heartbeat/ok");
        }
    }
}

@Component
public class AliyunExchangeService implements IExchangeService {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

   // private static final String WEBSOCKET_URL = WebSocketProperties.ALIYUN_URL + WebSocketProperties.TOKEN;

    private final Map<String, String> TRADE_DETAIL_MAP = new HashMap<>();


    private AliyunClient aliyunClient;

    @Resource
    private MergeService mergeService;

    @Resource
    private SymbolCache symbolCache;


    @Override
    public void start() {
        try {
            TRADE_DETAIL_MAP.clear();
            logger.info("启动AliyunClient");
//            aliyunClient = new AliyunClient(new URI(WEBSOCKET_URL), this);
//            aliyunClient.connect();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    @Override
    public void stop() {
        //重连
        if (aliyunClient.getReadyState() == WebSocket.READYSTATE.OPEN
                || aliyunClient.getReadyState() == WebSocket.READYSTATE.CONNECTING) {
            aliyunClient.close();
        }
        aliyunClient = null;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }
        start();
    }

    public void init() {
        List<String> exchangeSymbolList = symbolCache.listExchangeSymbol(MarketConstant.EXCHANGE_ALIYUN);
        for (String symbol : exchangeSymbolList) {
            //订阅缓存中的所有行情数据
            sub(symbol);
        }
    }

    @Override
    public void sub(String symbol) {
        subTradeMarKet(symbol);
    }

    @Override
    public void unsub(String symbol) {
        unsubTradeMarket(symbol);
    }


    /**
     * 订阅行情数据
     * @param symbol
     */
    private void subTradeMarKet(String symbol) {
        String sub = "/sub/" + symbol;
        if (TRADE_DETAIL_MAP.containsKey(symbol)) {
            return;
        }
        TRADE_DETAIL_MAP.put(symbol, sub);
        aliyunClient.send(sub);
    }

    /**
     * 退订行情数据
     */
    private void unsubTradeMarket(String symbol) {
        String sub = "/unsub/" + symbol;
        if (!TRADE_DETAIL_MAP.containsKey(symbol)) {
            return;
        }
        TRADE_DETAIL_MAP.remove(symbol);
        aliyunClient.send(sub);
    }

    public void handleData(String message) {
        try {
           数据处理
            //}
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
}
public interface IExchangeService {

    void start();

    void stop();

    void sub(String symbol);

    void unsub(String symbol);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值