1. 背景
上班族平时没有时间盯盘,股票突然冲高、跳水来不及操作,机会转瞬即逝。
2. 思路
通过软件实时获取股票价格信息,计算相关指标,满足涨跌幅度条件时,给微信发送信息,提示看看股票是否需要进行买卖。
3. 技术实现
3.1.1 通过java定时任务,拉取股票价格信息,判断涨跌幅度。
3.1.2 以百分之一为单位,每涨、跌一个百分点以上即发送微信通知。
3.1.3 相同的涨跌幅,每日只发送一次通知。
3.1.4 通知内容伪装成QQ黄钻订单信息。
核心代码如下:
(不求美观,只求一眼明了)
3.2.1. main 方法
package com.iv6.info4m;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;import com.iv6.tips.KdjSearchTask;
import com.iv6.tips.MaxUpdownTask2;
import com.iv6.util.ClearKeyTask;public class FirstM {private static ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(2);public static void main(String[] args) {ScheduleTask st = new ScheduleTask();st.addTask(new MyTask());st.addTask(new ClearKeyTask());//每分钟执行一次scheduExec.scheduleAtFixedRate(st, 50, 60 * 1000, TimeUnit.MILLISECONDS);}
}
3.2.2. 定时调度任务
package com.iv6.info4m;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class ScheduleTask implements Runnable {private List<Runnable> realTaskList= new ArrayList<Runnable>();public static Map<String,String> flagMap = new HashMap<String,String>();public void addTask(Runnable t) {realTaskList.add(t);}private ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));@Overridepublic void run() {for(Runnable r : realTaskList) {executor.execute(r);}}}
3.2.3. 实时获取股票信息任务
package com.iv6.info4m;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;class MyTask implements Runnable {@Overridepublic void run() {// 当前日期、星期String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));// 交易日LocalDate currentDate = LocalDate.now();int k = currentDate.getDayOfWeek().getValue();// 周1 - 5if (k > 5) {return;}// 交易时间String res = HttpUtils.getRes("http://quan.suning.com/getSysTime.do");JSONObject obj = JSON.parseObject(res);DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime currentTime = LocalDateTime.parse(obj.getString("sysTime2"), formatter);int h = currentTime.getHour();int m = currentTime.getMinute();int time = Integer.valueOf(String.valueOf(h) + String.valueOf(m < 10 ? "0" + m : m));// 交易时间检查if (time > 1530 || time < 930) {return;}check("sh601058", today);// check("sz000543", today);// check("sz002598", today);}public void check(String code, String today) {String res = HttpUtils.getRes("http://hq.sinajs.cn/list=" + code);res = res.substring(res.indexOf("\"") + 1, res.length() - 3);System.out.println(LocalDateTime.now() + " : " + res);String[] datas = res.split(",");// Double jkai = Double.valueOf(datas[1]);Double zshou = Double.valueOf(datas[2]);Double now = Double.valueOf(datas[3]);Double rate = (now - zshou) / zshou;String keyPlus = code + today + "+";String keyMinus = code + today + "-";// 上涨if (ScheduleTask.flagMap.get(keyPlus) == null) {if (rate > 0.1) {ScheduleTask.flagMap.put(keyPlus, "0.1");fireEmail("+10级", code);fireWechat("+10级", code);} else if (rate > 0.09) {ScheduleTask.flagMap.put(keyPlus, "0.09");fireEmail("+9级", code);fireWechat("+9级", code);} else if (rate > 0.08) {ScheduleTask.flagMap.put(keyPlus, "0.08");fireEmail("+8级", code);fireWechat("+8级", code);} else if (rate > 0.07) {ScheduleTask.flagMap.put(keyPlus, "0.07");fireEmail("+7级", code);fireWechat("+7级", code);} else if (rate > 0.06) {ScheduleTask.flagMap.put(keyPlus, "0.06");fireEmail("+6级", code);fireWechat("+6级", code);} else if (rate > 0.05) {ScheduleTask.flagMap.put(keyPlus, "0.05");fireEmail("+5级", code);fireWechat("+5级", code);} else if (rate > 0.04) {ScheduleTask.flagMap.put(keyPlus, "0.04");fireEmail("+4级", code);fireWechat("+4级", code);} else if (rate > 0.03) {ScheduleTask.flagMap.put(keyPlus, "0.03");fireEmail("+3级", code);fireWechat("+3级", code);} else if (rate > 0.02) {ScheduleTask.flagMap.put(keyPlus, "0.02");fireEmail("+2级", code);fireWechat("+2级", code);} else if (rate > 0.01) {ScheduleTask.flagMap.put(keyPlus, "0.01");fireEmail("+1级", code);fireWechat("+1级", code);}} else if (ScheduleTask.flagMap.get(keyPlus) != null) {Double lastRate = Double.valueOf(ScheduleTask.flagMap.get(keyPlus));if (rate > 0.1 && lastRate < 0.1) {ScheduleTask.flagMap.put(keyPlus, "0.1");fireEmail("+10级", code);fireWechat("+10级", code);} else if (rate > 0.09 && lastRate < 0.09) {ScheduleTask.flagMap.put(keyPlus, "0.09");fireEmail("+9级", code);fireWechat("+9级", code);} else if (rate > 0.08 && lastRate < 0.08) {ScheduleTask.flagMap.put(keyPlus, "0.08");fireEmail("+8级", code);fireWechat("+8级", code);} else if (rate > 0.07 && lastRate < 0.07) {ScheduleTask.flagMap.put(keyPlus, "0.07");fireEmail("+7级", code);fireWechat("+7级", code);} else if (rate > 0.06 && lastRate < 0.06) {ScheduleTask.flagMap.put(keyPlus, "0.06");fireEmail("+6级", code);fireWechat("+6级", code);} else if (rate > 0.05 && lastRate < 0.05) {ScheduleTask.flagMap.put(keyPlus, "0.05");fireEmail("+5级", code);fireWechat("+5级", code);} else if (rate > 0.04 && lastRate < 0.04) {ScheduleTask.flagMap.put(keyPlus, "0.04");fireEmail("+4级", code);fireWechat("+4级", code);} else if (rate > 0.03 && lastRate < 0.03) {ScheduleTask.flagMap.put(keyPlus, "0.03");fireEmail("+3级", code);fireWechat("+3级", code);} else if (rate > 0.02 && lastRate < 0.02) {ScheduleTask.flagMap.put(keyPlus, "0.02");fireEmail("+2级", code);fireWechat("+2级", code);} else if (rate > 0.01 && lastRate < 0.01) {ScheduleTask.flagMap.put(keyPlus, "0.01");fireEmail("+1级", code);fireWechat("+1级", code);}}// 下跌if (ScheduleTask.flagMap.get(keyMinus) == null) {if (rate < -0.1) {ScheduleTask.flagMap.put(keyMinus, "-0.1");fireEmail("-10级", code);fireWechat("-10级", code);} else if (rate < -0.09) {ScheduleTask.flagMap.put(keyMinus, "-0.09");fireEmail("-9级", code);fireWechat("-9级", code);} else if (rate < -0.08) {ScheduleTask.flagMap.put(keyMinus, "-0.08");fireEmail("-8级", code);fireWechat("-8级", code);} else if (rate < -0.07) {ScheduleTask.flagMap.put(keyMinus, "-0.07");fireEmail("-7级", code);fireWechat("-7级", code);} else if (rate < -0.06) {ScheduleTask.flagMap.put(keyMinus, "-0.06");fireEmail("-6级", code);fireWechat("-6级", code);} else if (rate < -0.05) {ScheduleTask.flagMap.put(keyMinus, "-0.05");fireEmail("-5级", code);fireWechat("-5级", code);} else if (rate < -0.04) {ScheduleTask.flagMap.put(keyMinus, "-0.04");fireEmail("-4级", code);fireWechat("-4级", code);} else if (rate < -0.03) {ScheduleTask.flagMap.put(keyMinus, "-0.03");fireEmail("-3级", code);fireWechat("-3级", code);} else if (rate < -0.02) {ScheduleTask.flagMap.put(keyMinus, "-0.02");fireEmail("-2级", code);fireWechat("-2级", code);} else if (rate < -0.01) {ScheduleTask.flagMap.put(keyMinus, "-0.01");fireEmail("-1级", code);fireWechat("-1级", code);}} else if (ScheduleTask.flagMap.get(keyMinus) != null) {Double lastRate = Double.valueOf(ScheduleTask.flagMap.get(keyMinus));if (rate < -0.1 && lastRate > -0.1) {ScheduleTask.flagMap.put(keyMinus, "-0.1");fireEmail("-10级", code);fireWechat("-10级", code);} else if (rate < -0.09 && lastRate > -0.09) {ScheduleTask.flagMap.put(keyMinus, "-0.09");fireEmail("-9级", code);fireWechat("-9级", code);} else if (rate < -0.08 && lastRate > -0.08) {ScheduleTask.flagMap.put(keyMinus, "-0.08");fireEmail("-8级", code);fireWechat("-8级", code);} else if (rate < -0.07 && lastRate > -0.07) {ScheduleTask.flagMap.put(keyMinus, "-0.07");fireEmail("-7级", code);fireWechat("-7级", code);} else if (rate < -0.06 && lastRate > -0.06) {ScheduleTask.flagMap.put(keyMinus, "-0.06");fireEmail("-6级", code);fireWechat("-6级", code);} else if (rate < -0.05 && lastRate > -0.05) {ScheduleTask.flagMap.put(keyMinus, "-0.05");fireEmail("-5级", code);fireWechat("-5级", code);} else if (rate < -0.04 && lastRate > -0.04) {ScheduleTask.flagMap.put(keyMinus, "-0.04");fireEmail("-4级", code);fireWechat("-4级", code);} else if (rate < -0.03 && lastRate > -0.03) {ScheduleTask.flagMap.put(keyMinus, "-0.03");fireEmail("-3级", code);fireWechat("-3级", code);} else if (rate < -0.02 && lastRate > -0.02) {ScheduleTask.flagMap.put(keyMinus, "-0.02");fireEmail("-2级", code);fireWechat("-2级", code);} else if (rate < -0.01 && lastRate > -0.01) {ScheduleTask.flagMap.put(keyMinus, "-0.01");fireEmail("-1级", code);fireWechat("-1级", code);}}// System.out.println(rate);}public void fireEmail(String flag, String code) {List<String> list = new ArrayList<String>();list.add("1083089079@qq.com");String date = LocalDateTime.now().minusDays(7).format(DateTimeFormatter.ISO_LOCAL_DATE);try {SendmailUtil.SendQQHtmlEmail("1083089079@qq.com", list, "QQ空间黄钻业务通知" + flag,MailTemplate.mailString.replace("########", date).replace("*********", code));} catch (Exception e) {e.printStackTrace();}}public void fireWechat(String flag, String code) {String date = LocalDateTime.now().minusDays(7).format(DateTimeFormatter.ISO_LOCAL_DATE);String title = "黄钻待支付订单提醒";String content = "您的QQ " + code + "于" + date + "购买了黄钻贵族" + flag+ " ,尚未完成支付。只差一步,开通即享QQ空间背景装扮、动态昵称展示、被挡访客查看等空间百余项特权。加入黄钻贵族,享受更多空间特权。";String remark = "点击详情别错过精彩...";SendWechat.sendMsg(title, content, remark);}public static void main(String[] args) {// 交易时间LocalTime currentTime = LocalTime.now();int h = currentTime.getHour();int m = currentTime.getMinute();int time = Integer.valueOf(String.valueOf(h) + String.valueOf(m));System.out.println(time);String res = HttpUtils.getRes("http://quan.suning.com/getSysTime.do");JSONObject obj = JSON.parseObject(res);DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime currentTime0 = LocalDateTime.parse(obj.getString("sysTime2"), formatter);System.out.println(currentTime0);}}
4. 截图为证
5. 改进
如果各位有更好的思路,可以私信我共同探讨交流。