背景
前面,通過(guò)圖文 如何利用 C# 爬取 ONE 的交易數(shù)據(jù)? 向大家介紹了<u>如何爬取在 BigOne 上線(xiàn)的數(shù)字資產(chǎn)的交易數(shù)據(jù)</u>。
其次,通過(guò)圖文 如何利用BigOne的API制作自動(dòng)化交易系統(tǒng) -- 身份驗(yàn)證 向大家介紹了<u>利用 BigOne API 函數(shù)之前的身份驗(yàn)證問(wèn)題</u>。
然后,通過(guò)圖文 如何利用BigOne的API制作自動(dòng)化交易系統(tǒng) -- 獲取賬戶(hù)資產(chǎn) 向大家介紹了<u>利用 BigOne API 函數(shù)獲取自己的賬戶(hù)資產(chǎn)數(shù)據(jù)</u>。
接著,通過(guò)圖文 如何利用BigOne的API制作自動(dòng)化交易系統(tǒng) -- 訂單系統(tǒng) 向大家介紹了 <u>利用 BigOne API 函數(shù)進(jìn)行掛單、撤單、查詢(xún)訂單狀態(tài)等交易操作</u>。
最后,通過(guò)圖文 如何進(jìn)行代碼的重構(gòu)?以封裝 BigOne API 為例 向大家介紹了 <u>利用 Layers 軟件體系結(jié)構(gòu)風(fēng)格重構(gòu)對(duì) BigOne API 的封裝過(guò)程</u>。
有了以上的基礎(chǔ),我們就可以制定交易策略,通過(guò)自動(dòng)化的方式進(jìn)行數(shù)字資產(chǎn)的交易了。從此告別手動(dòng)掛單、撤單、查看是否成交的煩惱!
技術(shù)分析
道氏理論指出,金融市場(chǎng)的價(jià)格變動(dòng)可以分為三種情況,分別是上漲、下跌和牛皮。而在上漲或下跌的過(guò)程中也會(huì)在較短周期上出現(xiàn)連續(xù)的波動(dòng),價(jià)格最終或者以無(wú)趨勢(shì)波動(dòng)呈現(xiàn)出來(lái),或者以短期的波動(dòng)和長(zhǎng)期的趨勢(shì)呈現(xiàn)出來(lái)的。在外匯市場(chǎng)上有一種被稱(chēng)為漁網(wǎng)交易法的交易理念,這種理念認(rèn)為,在一定的時(shí)間周期上,價(jià)格基本處于往復(fù)波動(dòng)的狀態(tài),投資者可以通過(guò)較高的頻率交易,利用限價(jià)單的交易方式來(lái)獲得價(jià)格波動(dòng)的收益。
什么是網(wǎng)格交易法呢?
網(wǎng)格交易法,就是跌買(mǎi)漲賣(mài)。具體做法是把資金分成 n 份,每次投入固定金額,先初始建倉(cāng),再設(shè)定一個(gè)百分比,比如 5%,股價(jià)跌 5% 就買(mǎi)入一份,漲 5% 就賣(mài)出一份,如此反復(fù)買(mǎi)賣(mài),不斷的低吸高拋,不斷產(chǎn)生盈利,從而積少成多。

本次圖文,就是帶著大家通過(guò) BigOne API 構(gòu)建一個(gè)針對(duì)數(shù)字資產(chǎn)的等金額網(wǎng)格交易策略,該策略的基本流程如下:

- 創(chuàng)建網(wǎng)格對(duì)象:根據(jù)歷史成交數(shù)據(jù)確定向上、向下的網(wǎng)格密度(寬度)以及確定每個(gè)網(wǎng)格賣(mài)出、買(mǎi)入的價(jià)格和數(shù)量。
- 撤銷(xiāo)全部訂單:撤銷(xiāo)當(dāng)前未完成的訂單。
- 掛買(mǎi)入訂單:形成買(mǎi)入的網(wǎng)格。
- 掛賣(mài)出訂單:形成賣(mài)出的網(wǎng)格。
- 判斷訂單狀態(tài):監(jiān)測(cè)數(shù)字資產(chǎn)價(jià)格是否觸及網(wǎng)格,如果觸及并成交則重新創(chuàng)建網(wǎng)格對(duì)象,如此往復(fù)執(zhí)行。
代碼實(shí)現(xiàn)
Step1 定義網(wǎng)格交易用到的數(shù)據(jù)結(jié)構(gòu)。
<u>表示訂單的結(jié)構(gòu) Order</u>
public class Order
{
// 價(jià)格
public double Price { get; set; }
// 數(shù)量
public double Amount { get; set; }
public Order(double price, double amount)
{
Price = price;
Amount = amount;
}
}
<u>表示數(shù)字貨幣資產(chǎn)的接口 IDigitalCurrency</u>。
public interface IDigitalCurrency
{
// 資產(chǎn)ID
string AssetId { get; }
// 獲取該資產(chǎn)的歷史記錄
List<AssetData> GetHistoryData(string period, string time, string limit);
// 獲取該資產(chǎn)的歷史記錄
List<AssetData> GetHistoryData();
}
<u>利用 BTC 來(lái)實(shí)現(xiàn)數(shù)字資產(chǎn)接口舉例</u>。
代碼原理參見(jiàn):如何利用 C# 爬取 ONE 的交易數(shù)據(jù)?
public class Btc : IDigitalCurrency
{
public string AssetId { get; } = "BTC";
public List<AssetData> GetHistoryData(string period, string time, string limit)
{
string url =
"https://b1.run/api/xn/v1/asset_pairs/550b34db-696e-4434-a126-196f827d9172/candles?"
+ "period=" + period
+ "&time=" + time
+ "&limit=" + limit;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
IHtmlDocument document = new JumonyParser().LoadDocument(url);
List<IHtmlNode> nos = document.Nodes().ToList();
string str = nos[0].ToString();
StringReader sr = new StringReader(str);
JsonTextReader jsonReader = new JsonTextReader(sr);
JsonSerializer serializer = new JsonSerializer();
JsonOne one = serializer.Deserialize<JsonOne>(jsonReader);
return one.data;
}
public List<AssetData> GetHistoryData()
{
string period = "DAY1";
DateTime dt = DateTime.Now;
string time = dt.Year + "-" + dt.Month.ToString().PadLeft(2, '0')
+ "-" + dt.Day.ToString().PadLeft(2, '0')
+ "T00:00:00.000Z";
string limit = "250";
return GetHistoryData(period, time, limit);
}
}
Step2 網(wǎng)格交易的抽象結(jié)構(gòu) GridMethod。
public abstract class GridMethod
{
// 資產(chǎn)
public IDigitalCurrency Asset { get; protected set; }
// 市場(chǎng)交易對(duì)
public string MarketId { get; protected set; }
// 網(wǎng)格的基準(zhǔn)價(jià)格
public double BasePrice { get; protected set; }
// 按照基準(zhǔn)價(jià)格進(jìn)行購(gòu)買(mǎi)時(shí),所用的資金
public double BaseMoney { get; protected set; }
// 取數(shù)據(jù)的天數(shù),用于計(jì)算網(wǎng)格密度
public int Days { get; protected set; }
// 每日交易的頻數(shù),用于計(jì)算網(wǎng)格密度
public int DailyTurnover { get; protected set; }
// 向上網(wǎng)格的密度(寬度)
public double GridAmplitudeUp { get; protected set; }
// 向下網(wǎng)格的密度(寬度)
public double GridAmplitudeDown { get; protected set; }
// 向上,向下劃分網(wǎng)格的條數(shù)
public int GridCount { get; protected set; }
// 訂單列表
public List<Order> OrderList { get; protected set; }
// 計(jì)算網(wǎng)格密度(寬度)
protected abstract void CalculateAmplitude();
// 計(jì)算網(wǎng)格訂單
protected abstract void CalculateGrid();
// 撤銷(xiāo)所有訂單
public abstract void CancelAllOrder();
// 創(chuàng)建買(mǎi)入訂單
public abstract List<OrderResponse> CreateBidOrders();
// 創(chuàng)建賣(mài)出訂單
public abstract List<OrderResponse> CreateAskOrders();
// 網(wǎng)格的格式化輸出
public override string ToString()
{
string infor = "AssetId:" + Asset.AssetId + Environment.NewLine
+ "MarketId:" + MarketId + Environment.NewLine
+ "BasePrice:" + BasePrice + Environment.NewLine
+ "BaseMoney:" + BaseMoney + Environment.NewLine
+ "Days:" + Days + Environment.NewLine
+ "DailyTurnover:" + DailyTurnover + Environment.NewLine
+ "GridAmplitudeUp:" + GridAmplitudeUp + Environment.NewLine
+ "GridAmplitudeDown:" + GridAmplitudeDown + Environment.NewLine
+ "GridCount:" + GridCount;
return infor;
}
}
Step3 等金額的網(wǎng)格策略 GridMethodEqualMoney。
該交易策略的每個(gè)網(wǎng)格所使用的網(wǎng)格寬度相同、金額相同,即是一種沉淀數(shù)字資產(chǎn)的交易策略。
public sealed class GridMethodEqualMoney : GridMethod
{
private readonly IDigitalCurrencyUtility _digitalCurrencyUtility;
public GridMethodEqualMoney(IDigitalCurrency asset, string marketId, int days, int dailyTurnover,
double baseMoney, double basePrice, int gridCount, IDigitalCurrencyUtility digitalCurrencyUtility)
{
_digitalCurrencyUtility = digitalCurrencyUtility;
Asset = asset;
MarketId = marketId;
BasePrice = basePrice;
BaseMoney = baseMoney;
Days = days;
DailyTurnover = dailyTurnover;
GridCount = gridCount;
//計(jì)算向上、向下的網(wǎng)格寬度
CalculateAmplitude();
//計(jì)算訂單列表
CalculateGrid();
}
protected override void CalculateAmplitude()
{
//根據(jù)以往的成交量數(shù)據(jù),計(jì)算指定周期的振幅。
List<AssetData> lstTrade = Asset.GetHistoryData();
List<double> lst = new List<double>();
int count = Days < lstTrade.Count - 1 ? Days : lstTrade.Count - 1;
for (int i = 0; i < count; i++)
{
double zf = (lstTrade[i].high - lstTrade[i].low)/lstTrade[i + 1].close;
lst.Add(zf);
}
double result = lst.Count == 0 ? 0.02 : Math.Round(lst.Average()/(2.0*DailyTurnover), 4);
result = Math.Max(0.02, result);
GridAmplitudeUp = result;
GridAmplitudeDown = result;
}
protected override void CalculateGrid()
{
OrderList = new List<Order>();
double price = Math.Round(BasePrice, 6);
double amount = Math.Round(BaseMoney/price, 3);
Order order = new Order(price, amount);
OrderList.Add(order);
for (int i = 0; i < GridCount; i++)
{
price = Math.Round(price/(1.0 - GridAmplitudeUp), 6);
amount = Math.Round(BaseMoney/price, 3);
order = new Order(price, amount);
OrderList.Add(order);
}
price = Math.Round(BasePrice, 6);
for (int i = 0; i < GridCount; i++)
{
price = Math.Round(price*(1.0 - GridAmplitudeDown), 6);
amount = Math.Round(BaseMoney/price, 3);
order = new Order(price, amount);
OrderList.Add(order);
}
OrderList = OrderList.OrderBy(a => a.Price).ToList();
}
public override void CancelAllOrder()
{
_digitalCurrencyUtility.CancelAllOrder(MarketId);
}
public override List<OrderResponse> CreateBidOrders()
{
List<Order> lst = OrderList.GetRange(0, GridCount);
return _digitalCurrencyUtility.CreateBidOrders(lst, MarketId);
}
public override List<OrderResponse> CreateAskOrders()
{
List<Order> lst = OrderList.GetRange(GridCount + 1, GridCount);
return _digitalCurrencyUtility.CreateAskOrders(lst, MarketId);
}
}
總結(jié)
到此為止,網(wǎng)格交易策略的實(shí)現(xiàn)框架就基本介紹完了,下面是我利用該框架對(duì) BTC、EOS、BTM、PRS、ONE等 進(jìn)行網(wǎng)格交易的截圖。
<u>ONE-USDT 交易對(duì)</u>

<u>PRS-USDT 交易對(duì)</u>

<u>EOS-USDT 交易對(duì)</u>

<u>BTM-USDT 交易對(duì)</u>

該策略的回測(cè)和評(píng)估需要積累一定數(shù)據(jù)才能進(jìn)行,我們后面再來(lái)介紹。
網(wǎng)格交易看起來(lái)似乎簡(jiǎn)單,其實(shí)里面包含了很復(fù)雜的問(wèn)題,比如市場(chǎng)趨勢(shì)向上、向下、橫盤(pán)震蕩時(shí)我們?nèi)绾握{(diào)整向上、向下網(wǎng)格的寬度;如何確定每個(gè)網(wǎng)格買(mǎi)入、賣(mài)出的數(shù)字資產(chǎn)數(shù)量(金字塔、倒金字塔、同量……);資金固定的情況下如何進(jìn)行資金分配等等。這些都是需要考慮和寫(xiě)程序根據(jù)不同的場(chǎng)景進(jìn)行自適應(yīng)調(diào)整的。慢慢來(lái)??!今天就到這里吧!See You!
相關(guān)圖文:
- 如何利用 C# 實(shí)現(xiàn) K 最鄰近算法?
- 如何利用 C# 實(shí)現(xiàn) K-D Tree 結(jié)構(gòu)?
- 如何利用 C# + KDTree 實(shí)現(xiàn) K 最鄰近算法?
- 如何利用 C# 對(duì)神經(jīng)網(wǎng)絡(luò)模型進(jìn)行抽象?
- 如何利用 C# 實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)的感知器模型?
- 如何利用 C# 實(shí)現(xiàn) Delta 學(xué)習(xí)規(guī)則?
- 如何利用 C# 爬取帶 Token 驗(yàn)證的網(wǎng)站數(shù)據(jù)?
- 如何利用 C# 向 Access 數(shù)據(jù)庫(kù)插入大量數(shù)據(jù)?
- 如何利用 C# 開(kāi)發(fā)「桌面版百度翻譯」軟件!
- 如何利用 C# 開(kāi)發(fā)「股票數(shù)據(jù)分析軟件」(上)
- 如何利用 C# 開(kāi)發(fā)「股票數(shù)據(jù)分析軟件」(中)
- 如何利用 C# 開(kāi)發(fā)「股票數(shù)據(jù)分析軟件」(下)
- 如何利用 C# 爬取「財(cái)報(bào)說(shuō)」中的股票數(shù)據(jù)?
- 如何利用 C# 爬取 One 持有者返利數(shù)據(jù)!
- 如何利用 C# 爬取Gate.io交易所的公告!
- 如何利用 C# 爬取BigOne交易所的公告!
- 如何利用 C# 爬取「貓眼電影:熱映口碑榜」及對(duì)應(yīng)影片信息!
- 如何利用 C# 爬取「貓眼電影專(zhuān)業(yè)版:票房」數(shù)據(jù)!
- 如何利用 C# 爬取「貓眼電影:最受期待榜」及對(duì)應(yīng)影片信息!
- 如何利用 C# 爬取「貓眼電影:國(guó)內(nèi)票房榜」及對(duì)應(yīng)影片信息!
- 如何利用 C# + Python 破解貓眼電影的反爬蟲(chóng)機(jī)制?