#property indicator_chart_window
input string 強弱對比商品列表 = "EURUSD,GBPUSD,AUDUSD,NZDUSD,USDJPY,USDCAD,USDCHF,USDSEK,USDMXN,USDZAR,USDHKD,USDNOK,Copper,USDTRY,US30,SPX500,GER30,FRA40,UK100,ITA40,HKG33,JPN225,ESP35,AUS200,USOil,XAUUSD,XAGUSD";
input ENUM_TIMEFRAMES 對比週期 = PERIOD_H1;
input ENUM_BASE_CORNER 座標位置定位 = CORNER_LEFT_LOWER;
input int 比較強弱K棒數 = 1000;
input color 強勢顏色 = Aqua;
input color 弱勢顏色 = Tomato;
input int 字體大小 = 10;
input int 行距 = 5;
input int 圖表邊距 = 50;
int iCommodityCount = 0;
string strSymbolList[];
double dStrenghtIndex[];
double dStrenghtIndexAfterSorted[];
int iXAxis, iYAxis;
double dChartHeight, dChartWidth;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
iCommodityCount = StringSplit(強弱對比商品列表,',',strSymbolList);
ArrayResize(dStrenghtIndex,iCommodityCount,0);
ArrayResize(dStrenghtIndexAfterSorted,iCommodityCount,0);
ArrayInitialize(dStrenghtIndex,0.0);
ArrayInitialize(dStrenghtIndexAfterSorted,0.0);
/// 取得圖表視窗長寬大小
dChartWidth = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
dChartHeight = ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
CalculateXY(); //// 計算顯示左上角XY座標
//---
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
//// 指標退出時清除顯示文字
if (iCommodityCount>0)
{
for (int i=0;i<iCommodityCount+1;i++)
{
ObjectDelete(StringConcatenate("StrengthRankingLabel1_",i));
ObjectDelete(StringConcatenate("StrengthRankingLabel2_",i));
ObjectDelete(StringConcatenate("StrengthRankingLabel3_",i));
}
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
CalculateXY();
ProcessComparison();
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
void ProcessComparison()
{
int i,j, k, iLineCount, iIndicatorCount;
double dLatestPrice,dFirstComparedPrice, dPostiveLogRange, dNegativeLogRange, dRange;
color crLine;
string strStrengthIndicator;
//// 比較強弱邏輯
for (i=0;i<iCommodityCount;i++)
{
dLatestPrice = iClose(strSymbolList[i],對比週期,0);
dFirstComparedPrice = iClose(strSymbolList[i],對比週期,比較強弱K棒數);
if (dLatestPrice==0.0 || dFirstComparedPrice==0.0) continue; /// 跳過無效的商品,也許是使用者輸入商品名稱錯誤
dStrenghtIndex[i] = (dLatestPrice-dFirstComparedPrice)/dFirstComparedPrice;
}
//// 排序
ArrayCopy(dStrenghtIndexAfterSorted,dStrenghtIndex,0,0,WHOLE_ARRAY);
ArraySort(dStrenghtIndexAfterSorted,WHOLE_ARRAY,0,MODE_DESCEND);
//// 計算強弱最大和最小值的對數範圍,因為接下來的強弱方格顯示將采非線性對數距離顯示,避免過大和過小的強弱顯示過長的方格數
if (dStrenghtIndexAfterSorted[0]>=0.0) dPostiveLogRange = MathLog(dStrenghtIndexAfterSorted[0]+1.0);
if (dStrenghtIndexAfterSorted[iCommodityCount-1]<0.0) dNegativeLogRange = MathLog(MathAbs(dStrenghtIndexAfterSorted[iCommodityCount-1]-1.0));
if (dPostiveLogRange*dNegativeLogRange!=0.0)
dRange = MathMin(dPostiveLogRange,dNegativeLogRange);
else
dRange = MathMax(dPostiveLogRange,dNegativeLogRange);
//// 顯示排序後文字
SetLabel(StringConcatenate("StrengthRankingLabel1_",0),
"商品強弱順序 - "+PeriodToString(對比週期),iXAxis,iYAxis-5,"Arial",字體大小+2,White);
iLineCount++;
for (i=0;i<iCommodityCount;i++)
{
for (j=0;j<iCommodityCount;j++)
{ if (dStrenghtIndex[j]==dStrenghtIndexAfterSorted[i]) break;
}
if (iClose(strSymbolList[j],對比週期,0)==0.0) continue; /// 跳過無效的商品,也許是使用者輸入商品名稱錯誤
if (dStrenghtIndex[j]>=0.0) crLine = 強勢顏色;
else crLine = 弱勢顏色;
SetLabel(StringConcatenate("StrengthRankingLabel1_",i+1),
strSymbolList[j],iXAxis,iYAxis+iLineCount*(字體大小+行距),"Arial",字體大小,crLine);
SetLabel(StringConcatenate("StrengthRankingLabel2_",i+1),
DoubleToStr(dStrenghtIndex[j]*100,1)+"%",iXAxis+字體大小*7,iYAxis+iLineCount*(字體大小+行距),"Arial",字體大小,crLine);
/// 顯示強弱方格,采非線性對數計算強度格數 - Logarithmic scaling
if (dRange!=0.0){
if (dStrenghtIndex[j]>=0.0)
iIndicatorCount = (int)( (MathLog(dStrenghtIndex[j]+1.0)/dRange*5.0));
else iIndicatorCount = (int)( (MathLog(MathAbs(dStrenghtIndex[j]-1.0))/dRange*5.0));
}
if (iIndicatorCount==0) iIndicatorCount++;
strStrengthIndicator="";
for (k=0;k<iIndicatorCount;k++) strStrengthIndicator+=ShortToString(0x25a0); /// 0x25a0 - 方塊符號 unicode
SetLabel(StringConcatenate("StrengthRankingLabel3_",i+1),
strStrengthIndicator,iXAxis+字體大小*12,iYAxis+iLineCount*(字體大小+行距),"Arial",字體大小,crLine);
iLineCount++;
}
WindowRedraw();
return;
}
void SetLabel(string nm,string tx,int xd,int yd,string fn,int fs,color ct)
{
if(ObjectFind(nm)<0)
ObjectCreate(nm,OBJ_LABEL,0,0,0); //--- create the Label object
ObjectSet(nm,OBJPROP_STYLE,STYLE_SOLID);
ObjectSet(nm,OBJPROP_XDISTANCE,xd);
ObjectSet(nm,OBJPROP_YDISTANCE,yd);
ObjectSet(nm,OBJPROP_COLOR,ct);
ObjectSetText(nm,tx,fs,fn,ct);
}
string PeriodToString (int imin)
{
string strPrd;
switch (imin)
{
case (1):
strPrd="M1";
break;
case (2):
strPrd="M2";
break;
case (3):
strPrd="M3";
break;
case (5):
strPrd="M5";
break;
case (15):
strPrd="M15";
break;
case (30):
strPrd="M30";
break;
case (60):
strPrd="H1";
break;
case (60*4):
strPrd="H4";
break;
case (60*24):
strPrd="D1";
break;
case (60*24*7):
strPrd="W1";
break;
case (60*24*30):
strPrd="MN";
break;
}
return (strPrd);
}
void CalculateXY()
{
int iChartWidth = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
int iChartHeight = ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
switch(座標位置定位)
{
case (CORNER_LEFT_LOWER): iXAxis = 圖表邊距; iYAxis = iChartHeight - (iCommodityCount+3) * (字體大小+行距); break;
case (CORNER_LEFT_UPPER): iXAxis = 圖表邊距; iYAxis = 圖表邊距; break;
case (CORNER_RIGHT_UPPER): iXAxis = iChartWidth - 圖表邊距 - 字體大小*18; iYAxis = 圖表邊距; break;
case (CORNER_RIGHT_LOWER): iXAxis = iChartWidth - 圖表邊距 - 字體大小*18; iYAxis = iChartHeight - (iCommodityCount+3) * (字體大小+行距); break;
}
}
void OnChartEvent(const int id, // Event identifier
const long& lparam, // Event parameter of long type
const double& dparam, // Event parameter of double type
const string& sparam) // Event parameter of string type
{
//// 當圖表視窗大小改變消息觸發,動態調整顯示位置
if (id==CHARTEVENT_CHART_CHANGE && (dChartWidth!=ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0) || dChartHeight!=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0)) )
{
CalculateXY();
ProcessComparison();
}
}
|